diff --git a/libraries/HDC100X/HDC100X.cpp b/libraries/HDC100X/HDC100X.cpp new file mode 100644 index 0000000..d0f9da1 --- /dev/null +++ b/libraries/HDC100X/HDC100X.cpp @@ -0,0 +1,295 @@ +/*********************** + +This library was written for the Texas Instruments +HDC100X temperature and humidity sensor. +It has been tested for the HDC1000 and the HDC1008 +Buy the HDC1008 breakout board at: https://www.tindie.com/stores/RFgermany +This library is made by Florian Roesner. +Released under GNU GPL v2.0 license. + +*************************/ +//#include "Arduino.h" +#include "HDC100X.h" +//#include "Wire.h" + +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- +//PUBLIC: +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- + +HDC100X::HDC100X(){ + ownAddr = HDC100X_ADDR1; + dataReadyPin = -1; +} +//----------------------------------------------------------------------- +HDC100X::HDC100X(uint8_t address){ + ownAddr = address; + //dataReadyPin = pin; +} +//----------------------------------------------------------------------- +HDC100X::HDC100X(bool addr0, bool addr1){ + // set the two bits the way you set the address jumpers + ownAddr = 0b1000000 |(addr0|(addr1<<1)); + //dataReadyPin = pin; +} + +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- + +uint8_t HDC100X::begin(uint8_t mode, uint8_t tempRes, uint8_t humiRes, bool heaterState){ + int i; + + /* sets the mode and resolution and the state of the heater element. care must be taken, because it will change the temperature reading + ** in: + ** mode: HDC100X_TEMP_HUMI + ** tempRes: HDC100X_11BIT/HDC100X_14BIT + ** humiRes: HDC100X_8BIT/HDC100X_11BIT/HDC100X_14BIT + ** heaterState: ENABLE/DISABLE + ** out: + ** high byte of the configuration register + */ + Wire.begin(); + + // test I2C address + Wire.beginTransmission(ownAddr); + i = Wire.endTransmission(); + if(i != 0) // error device not found + { + for(int tries=3; tries!=0; tries--) + { + Wire.beginTransmission(HDC100X_ADDR1); + i = Wire.endTransmission(); + if(i == 0) + { + ownAddr = HDC100X_ADDR1; + break; + } + delay(20); // wait 20ms + Wire.beginTransmission(HDC100X_ADDR2); + i = Wire.endTransmission(); + if(i == 0) + { + ownAddr = HDC100X_ADDR2; + break; + } + delay(20); // wait 20ms + Wire.beginTransmission(HDC100X_ADDR3); + i = Wire.endTransmission(); + if(i == 0) + { + ownAddr = HDC100X_ADDR3; + break; + } + delay(20); // wait 20ms + Wire.beginTransmission(HDC100X_ADDR4); + i = Wire.endTransmission(); + if(i == 0) + { + ownAddr = HDC100X_ADDR4; + break; + } + delay(20); // wait 20ms + } + } + + HDCmode = mode; + return writeConfigData(mode|(tempRes<<2)|humiRes|(heaterState<<5)); +} +//----------------------------------------------------------------------- +uint8_t HDC100X::begin(uint8_t mode, uint8_t resulution, bool heaterState){ + /* sets the mode, resolution and heaterState. Care must be taken, because it will change the temperature reading + ** in: + ** mode: HDC100X_TEMP/HDC100X_HUMI + ** resolution: HDC100X_8BIT(just for the humidity)/HDC100X_11BIT(both)/HDC100X_14BIT(both) + ** heaterState: ENABLE/DISABLE + ** out: + ** high byte of the configuration register + */ + Wire.begin(); + HDCmode = mode; + if(mode == HDC100X_HUMI) return writeConfigData(resulution|(heaterState<<5)); + else return writeConfigData((resulution<<2)|(heaterState<<5)); +} + +//######----------------------------------------------------------------------- + +void HDC100X::setAddr(uint8_t address){ + /* sets the slave address + ** in: + ** address: slave address byte + ** out: + ** none + */ + ownAddr = address; +} +//----------------------------------------------------------------------- +void HDC100X::setAddr(bool addr0, bool addr1){ + /* sets the slave address + ** in: + ** addr0: true/false + ** addr1: true/false + ** out: + ** none + */ + ownAddr = 0b1000000 |(addr0|(addr1<<1)); +} +//----------------------------------------------------------------------- +void HDC100X::setDrPin(int8_t pin){ + dataReadyPin = pin; +} + +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- + +uint8_t HDC100X::setMode(uint8_t mode, uint8_t tempRes, uint8_t humiRes){ + /* sets the mode and resolution + ** in: + ** mode: HDC100X_TEMP_HUMI + ** tempRes: HDC100X_11BIT/HDC100X_14BIT + ** humiRes: HDC100X_8BIT/HDC100X_11BIT/HDC100X_14BIT + ** out: + ** high byte of the configuration register + */ + uint8_t tempReg = getConfigReg() & 0xA0; + HDCmode = mode; + return writeConfigData(tempReg|mode|(tempRes<<2)|humiRes); +} +//----------------------------------------------------------------------- +uint8_t HDC100X::setMode(uint8_t mode, uint8_t resolution){ + /* sets the mode and resolution + ** in: + ** mode: HDC100X_TEMP/HDC100X_HUMI + ** resolution: HDC100X_8BIT(just for the humidity)/HDC100X_11BIT(both)/HDC100X_14BIT(both) + ** out: + ** high byte of the configuration register + */ + uint8_t tempReg = getConfigReg() & 0xA0; + HDCmode = mode; + if(mode == HDC100X_HUMI) return writeConfigData(tempReg|resolution); + return writeConfigData(tempReg|(resolution<<2)); +} + +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- + +uint8_t HDC100X::setHeater(bool state){ + /* turns on the heater to get rid of condensation. Care must be taken, because it will change the temperature reading + ** in: + ** state: true/false + ** out: + ** high byte of the configuration register + */ + uint8_t regData = getConfigReg() & 0x5F; + if(state) return writeConfigData(regData|(state<<5)); + return writeConfigData(regData); +} + +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- + +bool HDC100X::battLow(void){ + // returns a false if input voltage is higher than 2.8V and if lower a true + + if(getConfigReg() & 0x08) return true; + return false; +} + +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- + +float HDC100X::getTemp(void){ + // returns the a float number of the temperature in degrees Celsius + if(HDCmode == HDC100X_TEMP || HDCmode == HDC100X_TEMP_HUMI) + return ((float)getRawTemp()/65536.0*165.0-40.0); + + return 0.0; +} +//----------------------------------------------------------------------- +float HDC100X::getHumi(void){ + // returns the a float number of the humidity in percent + if(HDCmode == HDC100X_HUMI || HDCmode == HDC100X_TEMP_HUMI) + return ((float)getRawHumi()/65536.0*100.0); + + return 0.0; +} + +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- + +uint16_t HDC100X::getRawTemp(void){ + // returns the raw 16bit data of the temperature register + if(HDCmode == HDC100X_TEMP || HDCmode == HDC100X_TEMP_HUMI) + return read2Byte(HDC100X_TEMP_REG); + + return 0; +} +//----------------------------------------------------------------------- +uint16_t HDC100X::getRawHumi(void){ + // returns the raw 16bit data of the humidity register + if(HDCmode == HDC100X_HUMI || HDCmode == HDC100X_TEMP_HUMI) + return read2Byte(HDC100X_HUMI_REG); + + return 0; +} + +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- + +uint8_t HDC100X::getConfigReg(void){ + // returns the high byte of the configuration register + return (read2Byte(HDC100X_CONFIG_REG)>>8); +} + +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- + +uint16_t HDC100X::read2Byte(uint8_t reg){ + /* reads two bytes from the defined register + ** in: + ** reg: HDC100X_TEMP_REG/HDC100X_HUMI_REG/HDC100X_CONFIG_REG/HDC100X_ID1_REG/HDC100X_ID2_REG/HDC100X_ID3_REG + ** out: + ** two byte of data from the defined register + */ + uint16_t data=0; + setRegister(reg); + Wire.requestFrom(ownAddr, 2U); + if(Wire.available()>=2){ + data = Wire.read()<<8; + data += Wire.read(); + } + return data; +} + +uint8_t HDC100X::writeConfigData(uint8_t config){ + /* writes the config byte to the configuration register + ** in: + ** config: one byte + ** out: + ** one byte 0:success 1:data too long to fit in transmit buffer 2:received NACK on transmit of address 3:received NACK on transmit of data 4:other error + */ + Wire.beginTransmission(ownAddr); + Wire.write(HDC100X_CONFIG_REG); + Wire.write(config); + Wire.write(0x00); //the last 8 bits are always 0 + return Wire.endTransmission(); +} + +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- +//PRIVATE: +//######----------------------------------------------------------------------- +//######----------------------------------------------------------------------- + +void HDC100X::setRegister(uint8_t reg){ + /* set the register for the next read or write cycle + ** in: + ** reg: HDC100X_TEMP_REG/HDC100X_HUMI_REG/HDC100X_CONFIG_REG/HDC100X_ID1_REG/HDC100X_ID2_REG/HDC100X_ID3_REG + ** out: + ** none + */ + Wire.beginTransmission(ownAddr); + Wire.write(reg); + Wire.endTransmission(); + delay(10); // wait a little so that the sensor can set its register +} diff --git a/libraries/HDC100X/HDC100X.h b/libraries/HDC100X/HDC100X.h new file mode 100644 index 0000000..b2a4a58 --- /dev/null +++ b/libraries/HDC100X/HDC100X.h @@ -0,0 +1,89 @@ +/*********************** + +This library was written for the Texas Instruments +HDC100X temperature and humidity sensor. +It has been tested for the HDC1000 and the HDC1008 +Buy the HDC1008 breakout board at: https://www.tindie.com/stores/RFgermany +This library is made by Florian Roesner. +Released under GNU GPL v2.0 license. + +*************************/ + +#ifndef _HDC100X_H_ +#define _HDC100X_H_ + +#include +#include "Wire.h" + +#if (ARDUINO >= 100) + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +#define HDC100X_ADDR1 0x43 +#define HDC100X_ADDR2 0x40 +#define HDC100X_ADDR3 0x41 +#define HDC100X_ADDR4 0x42 + +#define HDC100X_TEMP_REG 0x00 +#define HDC100X_HUMI_REG 0x01 +#define HDC100X_CONFIG_REG 0x02 +#define HDC100X_ID1_REG 0xFB +#define HDC100X_ID2_REG 0xFC +#define HDC100X_ID3_REG 0xFD + + +#define HDC100X_RST 0x80 +#define HDC100X_TEMP_HUMI 0x16 +#define HDC100X_HUMI 1 +#define HDC100X_TEMP 0 + +#define HDC100X_14BIT 0x00 +#define HDC100X_11BIT 0x01 +#define HDC100X_8BIT 0x02 + +#define DISABLE 0 +#define ENABLE 1 + + + +class HDC100X{ + public: + HDC100X(); + HDC100X(uint8_t address); + HDC100X(bool addr0, bool addr1); + + uint8_t begin(uint8_t mode, uint8_t tempRes, uint8_t humiRes, bool heaterState); + uint8_t begin(uint8_t mode, uint8_t resulution, bool heaterState); + + void setAddr(bool addr0, bool addr1); + void setAddr(uint8_t address); + void setDrPin(int8_t pin); + + uint8_t setMode(uint8_t mode, uint8_t tempRes, uint8_t humiRes); + uint8_t setMode(uint8_t mode, uint8_t resolution); + + uint8_t setHeater(bool state); + bool battLow(void); + + float getTemp(void); + float getHumi(void); + + uint16_t getRawTemp(void); + uint16_t getRawHumi(void); + + uint8_t getConfigReg(void); + uint16_t read2Byte(uint8_t reg); + + uint8_t writeConfigData(uint8_t config); + + private: + uint8_t ownAddr; + uint8_t dataReadyPin; + uint8_t HDCmode; + void setRegister(uint8_t reg); + +}; + +#endif //_HDC100X_H_ diff --git a/libraries/HDC100X/KEYWORDS.txt b/libraries/HDC100X/KEYWORDS.txt new file mode 100644 index 0000000..75a952d --- /dev/null +++ b/libraries/HDC100X/KEYWORDS.txt @@ -0,0 +1,52 @@ +####################################### +# Syntax Coloring Map +####################################### + +DISABLE KEYWORD2 +ENABLE KEYWORD2 + + +####################################### +# Datatypes (KEYWORD1) +####################################### + +HDC100X KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +setAddr KEYWORD2 +setDrPin KEYWORD2 +setMode KEYWORD2 +setHeater KEYWORD2 +battLow KEYWORD2 +getTemp KEYWORD2 +getHumi KEYWORD2 +getRawTemp KEYWORD2 +getRawHumi KEYWORD2 +getConfigReg KEYWORD2 +read2Byte KEYWORD2 +setRegister KEYWORD2 +writeConfigData KEYWORD2 + + +###################################### +# Constants (LITERAL1) +####################################### +HDC100X_DEFAULT_ADDR LITERAL1 + +HDC100X_TEMP_REG LITERAL1 +HDC100X_HUMI_REG LITERAL1 +HDC100X_CONFIG_REG LITERAL1 +HDC100X_ID1_REG LITERAL1 +HDC100X_ID2_REG LITERAL1 +HDC100X_ID3_REG LITERAL1 + +HDC100X_RST LITERAL1 +HDC100X_TEMP_HUMI LITERAL1 +HDC100X_HUMI LITERAL1 +HDC100X_TEMP LITERAL1 +HDC100X_14BIT LITERAL1 +HDC100X_11BIT LITERAL1 +HDC100X_8BIT LITERAL1 diff --git a/libraries/HDC100X/examples/readTempHumi/readTempHumi.ino b/libraries/HDC100X/examples/readTempHumi/readTempHumi.ino new file mode 100644 index 0000000..4f624cc --- /dev/null +++ b/libraries/HDC100X/examples/readTempHumi/readTempHumi.ino @@ -0,0 +1,22 @@ +#include +#include + +HDC100X HDC1(0x43); + + +#define LED 13 +bool state = false; + +void setup(){ + Serial.begin(9600); + HDC1.begin(HDC100X_TEMP_HUMI,HDC100X_14BIT,HDC100X_14BIT,DISABLE); +} + +void loop(){ + Serial.print(" Humidity: "); + Serial.print(HDC1.getHumi()); + Serial.print("%, Temperature: "); + Serial.print(HDC1.getTemp()); + Serial.println("C"); + delay(500); +} diff --git a/libraries/HDC100X/examples/test/test.ino b/libraries/HDC100X/examples/test/test.ino new file mode 100644 index 0000000..d2b5764 --- /dev/null +++ b/libraries/HDC100X/examples/test/test.ino @@ -0,0 +1,25 @@ +#include +#include + +HDC100X hdc; + +#define LED 13 +bool state = false; + +void setup() +{ + Serial.begin(9600); + + hdc.begin(HDC100X_TEMP_HUMI,HDC100X_14BIT,HDC100X_14BIT,DISABLE); +} + +void loop() +{ + Serial.print(" Humidity: "); + Serial.print(hdc.getHumi()); + Serial.print("%, Temperature: "); + Serial.print(hdc.getTemp()); + Serial.println("C"); + + delay(500); +} diff --git a/libraries/HDC100X/keywords.txt b/libraries/HDC100X/keywords.txt new file mode 100644 index 0000000..361fac6 --- /dev/null +++ b/libraries/HDC100X/keywords.txt @@ -0,0 +1,22 @@ +####################################### +# Datatypes (KEYWORD1) +####################################### + +HDC100X KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +setAddr KEYWORD2 +setDrPin KEYWORD2 +setMode KEYWORD2 +setHeater KEYWORD2 +battLow KEYWORD2 +getTemp KEYWORD2 +getHumi KEYWORD2 +getRawTemp KEYWORD2 +getRawHumi KEYWORD2 +getConfigReg KEYWORD2 +read2Byte KEYWORD2 +writeConfigData KEYWORD2 diff --git a/libraries/IBM_LMIC_framework/README.md b/libraries/IBM_LMIC_framework/README.md new file mode 100644 index 0000000..47cc97c --- /dev/null +++ b/libraries/IBM_LMIC_framework/README.md @@ -0,0 +1,365 @@ +Arduino-LMIC library +==================== +This repository contains the IBM LMIC (LoraMAC-in-C) library, slightly +modified to run in the Arduino environment, allowing using the SX1272, +SX1276 tranceivers and compatible modules (such as some HopeRF RFM9x +modules). + +This library mostly exposes the functions defined by LMIC, it makes no +attempt to wrap them in a higher level API that is more in the Arduino +style. To find out how to use the library itself, see the examples, or +see the PDF file in the doc subdirectory. + +This library requires Arduino IDE version 1.6.6 or above, since it +requires C99 mode to be enabled by default. + +Installing +---------- +To install this library: + + - install it using the Arduino Library manager ("Sketch" -> "Include + Library" -> "Manage Libraries..."), or + - download a zipfile from github using the "Download ZIP" button and + install it using the IDE ("Sketch" -> "Include Library" -> "Add .ZIP + Library..." + - clone this git repository into your sketchbook/libraries folder. + +For more info, see https://www.arduino.cc/en/Guide/Libraries + +Features +-------- +The LMIC library provides a fairly complete LoRaWAN Class A and Class B +implementation, supporting the EU-868 and US-915 bands. Only a limited +number of features was tested using this port on Arduino hardware, so be +careful when using any of the untested features. + +What certainly works: + - Sending packets uplink, taking into account duty cycling. + - Encryption and message integrity checking. + - Receiving downlink packets in the RX2 window. + - Custom frequencies and datarate settings. + - Over-the-air activation (OTAA / joining). + +What has not been tested: + - Receiving downlink packets in the RX1 window. + - Receiving and processing MAC commands. + - Class B operation. + +If you try one of these untested features and it works, be sure to let +us know (creating a github issue is probably the best way for that). + +Configuration +------------- +A number of features can be configured or disabled by editing the +`config.h` file in the library folder. Unfortunately the Arduino +environment does not offer any way to do this (compile-time) +configuration from the sketch, so be careful to recheck your +configuration when you switch between sketches or update the library. + +At the very least, you should set the right type of transceiver (SX1272 +vs SX1276) in config.h, most other values should be fine at their +defaults. + +Supported hardware +------------------ +This library is intended to be used with plain LoRa transceivers, +connecting to them using SPI. In particular, the SX1272 and SX1276 +families are supported (which should include SX1273, SX1277, SX1278 and +SX1279 which only differ in the available frequencies, bandwidths and +spreading factors). It has been tested with both SX1272 and SX1276 +chips, using the Semtech SX1272 evaluation board and the HopeRF RFM92 +and RFM95 boards (which supposedly contain an SX1272 and SX1276 chip +respectively). + +This library contains a full LoRaWAN stack and is intended to drive +these Transceivers directly. It is *not* intended to be used with +full-stack devices like the Microchip RN2483 and the Embit LR1272E. +These contain a transceiver and microcontroller that implements the +LoRaWAN stack and exposes a high-level serial interface instead of the +low-level SPI transceiver interface. + +This library is intended to be used inside the Arduino environment. It +should be architecture-independent, so it should run on "normal" AVR +arduinos, but also on the ARM-based ones, and some success has been seen +running on the ESP8266 board as well. It was tested on the Arduino Uno, +Pinoccio Scout, Teensy LC and 3.x, ESP8266, Arduino 101. + +This library an be quite heavy, especially if the fairly small ATmega +328p (such as in the Arduino Uno) is used. In the default configuration, +the available 32K flash space is nearly filled up (this includes some +debug output overhead, though). By disabling some features in `config.h` +(like beacon tracking and ping slots, which are not typically needed), +some space can be freed up. Some work is underway to replace the AES +encryption implementation, which should free up another 8K or so of +flash in the future, making this library feasible to run on a 328p +microcontroller. + +Connections +----------- +To make this library work, your Arduino (or whatever Arduino-compatible +board you are using) should be connected to the transceiver. The exact +connections are a bit dependent on the transceiver board and Arduino +used, so this section tries to explain what each connection is for and +in what cases it is (not) required. + +Note that the SX1272 module runs at 3.3V and likely does not like 5V on +its pins (though the datasheet is not say anything about this, and my +transceiver did not obviously break after accidentally using 5V I/O for +a few hours). To be safe, make sure to use a level shifter, or an +Arduino running at 3.3V. The Semtech evaluation board has 100 ohm resistors in +series with all data lines that might prevent damage, but I would not +count on that. + +### Power +The SX127x transceivers need a supply voltage between 1.8V and 3.9V. +Using a 3.3V supply is typical. Some modules have a single power pin +(like the HopeRF modules, labeled 3.3V) but others expose multiple power +pins for different parts (like the Semtech evaluation board that has +`VDD_RF`, `VDD_ANA` and `VDD_FEM`), which can all be connected together. +Any *GND* pins need to be connected to the Arduino *GND* pin(s). + +### SPI +The primary way of communicating with the transceiver is through SPI +(Serial Peripheral Interface). This uses four pins: MOSI, MISO, SCK and +SS. The former three need to be directly connected: so MOSI to MOSI, +MISO to MISO, SCK to SCK. Where these pins are located on your Arduino +varies, see for example the "Connections" section of the [Arduino SPI +documentation](SPI). + +The SS (slave select) connection is a bit more flexible. On the SPI +slave side (the transceiver), this must be connect to the pin +(typically) labeled *NSS*. On the SPI master (Arduino) side, this pin +can connect to any I/O pin. Most Arduinos also have a pin labeled "SS", +but this is only relevant when the Arduino works as an SPI slave, which +is not the case here. Whatever pin you pick, you need to tell the +library what pin you used through the pin mapping (see below). + +[SPI]: https://www.arduino.cc/en/Reference/SPI + +### DIO pins +The DIO (digitial I/O) pins on the transceiver board can be configured +for various functions. The LMIC library uses them to get instant status +information from the transceiver. For example, when a LoRa transmission +starts, the DIO0 pin is configured as a TxDone output. When the +transmission is complete, the DIO0 pin is made high by the transceiver, +which can be detected by the LMIC library. + +The LMIC library needs only access to DIO0, DIO1 and DIO2, the other +DIOx pins can be left disconnected. On the Arduino side, they can +connect to any I/O pin, since the current implementation does not use +interrupts or other special hardware features (though this might be +added in the feature, see also the "Timing" section). + +In LoRa mode the DIO pins are used as follows: + * DIO0: TxDone and RxDone + * DIO1: RxTimeout + +In FSK mode they are used as follows:: + * DIO0: PayloadReady and PacketSent + * DIO2: TimeOut + +Both modes need only 2 pins, but the tranceiver does not allow mapping +them in such a way that all needed interrupts map to the same 2 pins. +So, if both LoRa and FSK modes are used, all three pins must be +connected. + +The pins used on the Arduino side should be configured in the pin +mapping in your sketch (see below). + +### Reset +The transceiver has a reset pin that can be used to explicitely reset +it. The LMIC library uses this to ensure the chip is in a consistent +state at startup. In practice, this pin can be left disconnected, since +the transceiver will already be in a sane state on power-on, but +connecting it might prevent problems in some cases. + +On the Arduino side, any I/O pin can be used. The pin number used must +be configured in the pin mapping (see below). + +### RXTX +The transceiver contains two separate antenna connections: One for RX +and one for TX. A typical transceiver board contains an antenna switch +chip, that allows switching a single antenna between these RX and TX +connections. Such a antenna switcher can typically be told what +position it should be through an input pin, often labeled *RXTX*. + +The easiest way to control the antenna switch is to use the *RXTX* pin +on the SX127x transceiver. This pin is automatically set high during TX +and low during RX. For example, the HopeRF boards seem to have this +connection in place, so they do not expose any *RXTX* pins and the pin +can be marked as unused in the pin mapping. + +Some boards do expose the antenna switcher pin, and sometimes also the +SX127x *RXTX* pin. For example, the SX1272 evaluation board calls the +former *FEM_CTX* and the latter *RXTX*. Again, simply connecting these +together with a jumper wire is the easiest solution. + +Alternatively, or if the SX127x *RXTX* pin is not available, LMIC can be +configured to control the antenna switch. Connect the antenna switch +control pin (e.g. *FEM_CTX* on the Semtech evaluation board) to any I/O +pin on the Arduino side, and configure the pin used in the pin map (see +below). It is not entirely clear why would *not* want the transceiver to +control the antenna directly, though. + +### Pin mapping +As described above, most connections can use arbitrary I/O pins on the +Arduino side. To tell the LMIC library about these, a pin mapping struct +is used in the sketch file. + +For example, this could look like this: + + lmic_pinmap lmic_pins = { + .nss = 6, + .rxtx = LMIC_UNUSED_PIN, + .rst = 5, + .dio = {2, 3, 4}, + }; + +The names refer to the pins on the transceiver side, the numbers refer +to the Arduino pin numbers (to use the analog pins, use constants like +`A0`). For the DIO pins, the three numbers refer to DIO0, DIO1 and DIO2 +respectively. Any pins that are not needed should be specified as +`LMIC_UNUSED_PIN`. The nss and dio0 pin is required, the others can +potentially left out (depending on the environments and requirements, +see the notes above for when a pin can or cannot be left out). + +The name of this struct must always be `lmic_pins`, which is a special name +recognized by the library. + +#### LoRa Nexus by Ideetron +This board uses the following pin mapping: + + const lmic_pinmap lmic_pins = { + .nss = 10, + .rxtx = LMIC_UNUSED_PIN, + .rst = LMIC_UNUSED_PIN, // hardwired to AtMega RESET + .dio = {4, 5, 7}, + }; + +Examples +-------- +This library currently provides three examples: + + - `ttn-abp.ino` shows a basic transmission of a "Hello, world!" message + using the LoRaWAN protocol. It contains some frequency settings and + encryption keys intended for use with The Things Network, but these + also correspond to the default settings of most gateways, so it + should work with other networks and gateways as well. This example + uses activation-by-personalization (ABP, preconfiguring a device + address and encryption keys), and does not employ over-the-air + activation. + + Reception of packets (in response to transmission, using the RX1 and + RX2 receive windows is also supported). + + - `ttn-otaa.ino` also sends a "Hello, world!" message, but uses over + the air activation (OTAA) to first join a network to establish a + session and security keys. This was tested with The Things Network, + but should also work (perhaps with some changes) for other networks. + + - `raw.ino` shows how to access the radio on a somewhat low level, + and allows to send raw (non-LoRaWAN) packets between nodes directly. + This is useful to verify basic connectivity, and when no gateway is + available, but this example also bypasses duty cycle checks, so be + careful when changing the settings. + +Timing +------ +Unfortunately, the SX127x tranceivers do not support accurate +timekeeping themselves (there is a sequencer that is *almost* sufficient +for timing the RX1 and RX2 downlink windows, but that is only available +in FSK mode, not in LoRa mode). This means that the microcontroller is +responsible for keeping track of time. In particular, it should note +when a packet finished transmitting, so it can open up the RX1 and RX2 +receive windows at a fixed time after the end of transmission. + +This timing uses the Arduino `micros()` timer, which has a granularity +of 4μs and is based on the primary microcontroller clock. For timing +events, the tranceiver uses its DIOx pins as interrupt outputs. In the +current implementation, these pins are not handled by an actual +interrupt handler, but they are just polled once every LMIC loop, +resulting in a bit inaccuracy in the timestamping. Also, running +scheduled jobs (such as opening up the receive windows) is done using a +polling approach, which might also result in further delays. + +Fortunately, LoRa is a fairly slow protocol and the timing of the +receive windows is not super critical. To synchronize transmitter and +receiver, a preamble is first transmitted. Using LoRaWAN, this preamble +consists of 8 symbols, of which the receiver needs to see 4 symbols to +lock on. The current implementation tries to enable the receiver for 5 +symbol times at 1.5 symbol after the start of the receive window, +meaning that a inacurracy of plus or minus 2.5 symbol times should be +acceptable. + +At the fastest LoRa setting supported by the tranceiver (SF5BW500) a +single preamble symbol takes 64μs, so the receive window timing should +be accurate within 160μs (for LoRaWAN this is SF7BW250, needing accuracy +within 1280μs). This is certainly within a crystal's accuracy, but using +the internal oscillator is probably not feasible (which is 1% - 10% +accurate, depending on calibration). This accuracy should also be +feasible with the polling approach used, provided that the LMIC loop is +run often enough. + +It would be good to properly review this code at some point, since it +seems that in some places some offsets and corrections are applied that +might not be appropriate for the Arduino environment. So if reception is +not working, the timing is something to have a closer look at. + +The LMIC library was intended to connect the DIO pins to interrupt +lines and run code inside the interrupt handler. However, doing this +opens up an entire can of worms with regard to doing SPI transfers +inside interrupt routines (some of which is solved by the Arduino +`beginTransaction()` API, but possibly not everything). One simpler +alternative could be to use an interrupt handler to just store a +timestamp, and then do the actual handling in the main loop (this +requires modifications of the library to pass a timestamp to the LMIC +`radio_irq_handler()` function). + +An even more accurate solution could be to use a dedicated timer with an +input capture unit, that can store the timestamp of a change on the DIO0 +pin (the only one that is timing-critical) entirely in hardware. +Unfortunately, timer0, as used by Arduino's `millis()` and `micros()` +functions does not seem to have an input capture unit, meaning a +separate timer is needed for this. + +If the main microcontroller does not have a crystal, but uses the +internal oscillator, the clock output of the transceiver (on DIO5) could +be usable to drive this timer instead of the main microcontroller clock, +to ensure the receive window timing is sufficiently accurate. Ideally, +this would use timer2, which supports asynchronous mode (e.g. running +while the microcontroller is sleeping), but that timer does not have an +input capture unit. Timer1 has one, but it seems it will stop running +once the microcontroller sleeps. Running the microcontroller in idle +mode with a slower clock might be feasible, though. Instead of using the +main crystal oscillator of the transceiver, it could be possible to use +the transceiver's internal RC oscillator (which is calibrated against +the transceiver crystal), or to calibrate the microcontroller internal +RC oscillator using the transceiver's clkout. However, that datasheet is +a bit vague on the RC oscillator's accuracy and how to use it exactly +(some registers seem to be FSK-mode only), so this needs some +experiments. + +Downlink datarate +----------------- +Note that the datarate used for downlink packets in the RX2 window +defaults to SF12BW125 according to the specification, but some networks +use different values (iot.semtech.com and The Things Network both use +SF9BW). When using personalized activate (ABP), it is your +responsibility to set the right settings, e.g. by adding this to your +sketch (after calling `LMIC_setSession`). `ttn-abp.ino` already does +this. + + LMIC.dn2Dr = DR_SF9; + +When using OTAA, the network communicates the RX2 settings in the +join accept message, but the LMIC library does not currently process +these settings. Until that is solved (see issue #20), you should +manually set the RX2 rate, *after* joining (see the handling of +`EV_JOINED` in the `ttn-otaa.ino` for an example. + +License +------- +Most source files in this repository are made available under the +Eclipse Public License v1.0. The examples which use a more liberal +license. Some of the AES code is available under the LGPL. Refer to each +individual source file for more details. diff --git a/libraries/IBM_LMIC_framework/doc/LMiC-v1.5.pdf b/libraries/IBM_LMIC_framework/doc/LMiC-v1.5.pdf new file mode 100644 index 0000000..b14bd69 Binary files /dev/null and b/libraries/IBM_LMIC_framework/doc/LMiC-v1.5.pdf differ diff --git a/libraries/IBM_LMIC_framework/doc/README.txt b/libraries/IBM_LMIC_framework/doc/README.txt new file mode 100644 index 0000000..42027c3 --- /dev/null +++ b/libraries/IBM_LMIC_framework/doc/README.txt @@ -0,0 +1,4 @@ +DISCLAIMER: +Please note that the software is provided AS IS and we cannot +provide support for optimizations, adaptations, integration, +ports to other platforms or device drivers! diff --git a/libraries/IBM_LMIC_framework/doc/release-notes.txt b/libraries/IBM_LMIC_framework/doc/release-notes.txt new file mode 100644 index 0000000..90618c4 --- /dev/null +++ b/libraries/IBM_LMIC_framework/doc/release-notes.txt @@ -0,0 +1,28 @@ +============================================================================== +LMIC VERSION 1.4 (17-Mar-2015) +------------------------------- + + - changed API: inverted port indicator flag in LMIC.txrxFlags + (now TXRX_PORT, previously TXRX_NOPORT) + + - fixed offset OFF_CFLIST constant + + - changed CRC-16 algorithm for beacons to CCITT(XMODEM) polynomial + + - fixed radio driver (low data rate optimization for SF11+SF12 only for BW125) + + - fixed timer rollover handling in job queue + +============================================================================== +LMIC VERSION 1.5 (8-May-2015) +------------------------------ + + - fixed condition in convFreq() + + - fixed freq*100 bug and freq==0 bug for CFList + + - fixed TX scheduling bug + + - better support for GNU compiler toolchain + +============================================================================== diff --git a/libraries/IBM_LMIC_framework/examples/raw/raw.ino b/libraries/IBM_LMIC_framework/examples/raw/raw.ino new file mode 100644 index 0000000..1e0382f --- /dev/null +++ b/libraries/IBM_LMIC_framework/examples/raw/raw.ino @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (c) 2015 Matthijs Kooijman + * + * Permission is hereby granted, free of charge, to anyone + * obtaining a copy of this document and accompanying files, + * to do whatever they want with them without any restriction, + * including, but not limited to, copying, modification and redistribution. + * NO WARRANTY OF ANY KIND IS PROVIDED. + * + * This example transmits data on hardcoded channel and receives data + * when not transmitting. Running this sketch on two nodes should allow + * them to communicate. + *******************************************************************************/ + +#include +#include +#include + +#if !defined(DISABLE_INVERT_IQ_ON_RX) +#error This example requires DISABLE_INVERT_IQ_ON_RX to be set. Update \ + config.h in the lmic library to set it. +#endif + +// How often to send a packet. Note that this sketch bypasses the normal +// LMIC duty cycle limiting, so when you change anything in this sketch +// (payload length, frequency, spreading factor), be sure to check if +// this interval should not also be increased. +// See this spreadsheet for an easy airtime and duty cycle calculator: +// https://docs.google.com/spreadsheets/d/1voGAtQAjC1qBmaVuP1ApNKs1ekgUjavHuVQIXyYSvNc +#define TX_INTERVAL 2000 + +// Pin mapping +const lmic_pinmap lmic_pins = { + .nss = 6, + .rxtx = LMIC_UNUSED_PIN, + .rst = 5, + .dio = {2, 3, 4}, +}; + + +// These callbacks are only used in over-the-air activation, so they are +// left empty here (we cannot leave them out completely unless +// DISABLE_JOIN is set in config.h, otherwise the linker will complain). +void os_getArtEui (u1_t* buf) { } +void os_getDevEui (u1_t* buf) { } +void os_getDevKey (u1_t* buf) { } + +void onEvent (ev_t ev) { +} + +osjob_t txjob; +osjob_t timeoutjob; +static void tx_func (osjob_t* job); + +// Transmit the given string and call the given function afterwards +void tx(const char *str, osjobcb_t func) { + os_radio(RADIO_RST); // Stop RX first + delay(1); // Wait a bit, without this os_radio below asserts, apparently because the state hasn't changed yet + LMIC.dataLen = 0; + while (*str) + LMIC.frame[LMIC.dataLen++] = *str++; + LMIC.osjob.func = func; + os_radio(RADIO_TX); + Serial.println("TX"); +} + +// Enable rx mode and call func when a packet is received +void rx(osjobcb_t func) { + LMIC.osjob.func = func; + LMIC.rxtime = os_getTime(); // RX _now_ + // Enable "continuous" RX (e.g. without a timeout, still stops after + // receiving a packet) + os_radio(RADIO_RXON); + Serial.println("RX"); +} + +static void rxtimeout_func(osjob_t *job) { + digitalWrite(LED_BUILTIN, LOW); // off +} + +static void rx_func (osjob_t* job) { + // Blink once to confirm reception and then keep the led on + digitalWrite(LED_BUILTIN, LOW); // off + delay(10); + digitalWrite(LED_BUILTIN, HIGH); // on + + // Timeout RX (i.e. update led status) after 3 periods without RX + os_setTimedCallback(&timeoutjob, os_getTime() + ms2osticks(3*TX_INTERVAL), rxtimeout_func); + + // Reschedule TX so that it should not collide with the other side's + // next TX + os_setTimedCallback(&txjob, os_getTime() + ms2osticks(TX_INTERVAL/2), tx_func); + + Serial.print("Got "); + Serial.print(LMIC.dataLen); + Serial.println(" bytes"); + Serial.write(LMIC.frame, LMIC.dataLen); + Serial.println(); + + // Restart RX + rx(rx_func); +} + +static void txdone_func (osjob_t* job) { + rx(rx_func); +} + +// log text to USART and toggle LED +static void tx_func (osjob_t* job) { + // say hello + tx("Hello, world!", txdone_func); + // reschedule job every TX_INTERVAL (plus a bit of random to prevent + // systematic collisions), unless packets are received, then rx_func + // will reschedule at half this time. + os_setTimedCallback(job, os_getTime() + ms2osticks(TX_INTERVAL + random(500)), tx_func); +} + +// application entry point +void setup() { + Serial.begin(115200); + Serial.println("Starting"); + #ifdef VCC_ENABLE + // For Pinoccio Scout boards + pinMode(VCC_ENABLE, OUTPUT); + digitalWrite(VCC_ENABLE, HIGH); + delay(1000); + #endif + + pinMode(LED_BUILTIN, OUTPUT); + + // initialize runtime env + os_init(); + + // Set up these settings once, and use them for both TX and RX + +#if defined(CFG_eu868) + // Use a frequency in the g3 which allows 10% duty cycling. + LMIC.freq = 869525000; +#elif defined(CFG_us915) + LMIC.freq = 902300000; +#endif + + // Maximum TX power + LMIC.txpow = 27; + // Use a medium spread factor. This can be increased up to SF12 for + // better range, but then the interval should be (significantly) + // lowered to comply with duty cycle limits as well. + LMIC.datarate = DR_SF9; + // This sets CR 4/5, BW125 (except for DR_SF7B, which uses BW250) + LMIC.rps = updr2rps(LMIC.datarate); + + Serial.println("Started"); + Serial.flush(); + + // setup initial job + os_setCallback(&txjob, tx_func); +} + +void loop() { + // execute scheduled jobs and events + os_runloop_once(); +} diff --git a/libraries/IBM_LMIC_framework/examples/ttn-abp/ttn-abp.ino b/libraries/IBM_LMIC_framework/examples/ttn-abp/ttn-abp.ino new file mode 100644 index 0000000..a8b4a18 --- /dev/null +++ b/libraries/IBM_LMIC_framework/examples/ttn-abp/ttn-abp.ino @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman + * + * Permission is hereby granted, free of charge, to anyone + * obtaining a copy of this document and accompanying files, + * to do whatever they want with them without any restriction, + * including, but not limited to, copying, modification and redistribution. + * NO WARRANTY OF ANY KIND IS PROVIDED. + * + * This example sends a valid LoRaWAN packet with payload "Hello, + * world!", using frequency and encryption settings matching those of + * the The Things Network. + * + * This uses ABP (Activation-by-personalisation), where a DevAddr and + * Session keys are preconfigured (unlike OTAA, where a DevEUI and + * application key is configured, while the DevAddr and session keys are + * assigned/generated in the over-the-air-activation procedure). + * + * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in + * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably + * violated by this sketch when left running for longer)! + * + * To use this sketch, first register your application and device with + * the things network, to set or generate a DevAddr, NwkSKey and + * AppSKey. Each device should have their own unique values for these + * fields. + * + * Do not forget to define the radio type correctly in config.h. + * + *******************************************************************************/ + +#include +#include +#include + +// LoRaWAN NwkSKey, network session key +// This is the default Semtech key, which is used by the early prototype TTN +// network. +static const PROGMEM u1_t NWKSKEY[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; + +// LoRaWAN AppSKey, application session key +// This is the default Semtech key, which is used by the early prototype TTN +// network. +static const u1_t PROGMEM APPSKEY[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; + +// LoRaWAN end-device address (DevAddr) +static const u4_t DEVADDR = 0x03FF0001 ; // <-- Change this address for every node! + +// These callbacks are only used in over-the-air activation, so they are +// left empty here (we cannot leave them out completely unless +// DISABLE_JOIN is set in config.h, otherwise the linker will complain). +void os_getArtEui (u1_t* buf) { } +void os_getDevEui (u1_t* buf) { } +void os_getDevKey (u1_t* buf) { } + +static uint8_t mydata[] = "Hello, world!"; +static osjob_t sendjob; + +// Schedule TX every this many seconds (might become longer due to duty +// cycle limitations). +const unsigned TX_INTERVAL = 60; + +// Pin mapping +const lmic_pinmap lmic_pins = { + .nss = 6, + .rxtx = LMIC_UNUSED_PIN, + .rst = 5, + .dio = {2, 3, 4}, +}; + +void onEvent (ev_t ev) { + Serial.print(os_getTime()); + Serial.print(": "); + switch(ev) { + case EV_SCAN_TIMEOUT: + Serial.println(F("EV_SCAN_TIMEOUT")); + break; + case EV_BEACON_FOUND: + Serial.println(F("EV_BEACON_FOUND")); + break; + case EV_BEACON_MISSED: + Serial.println(F("EV_BEACON_MISSED")); + break; + case EV_BEACON_TRACKED: + Serial.println(F("EV_BEACON_TRACKED")); + break; + case EV_JOINING: + Serial.println(F("EV_JOINING")); + break; + case EV_JOINED: + Serial.println(F("EV_JOINED")); + break; + case EV_RFU1: + Serial.println(F("EV_RFU1")); + break; + case EV_JOIN_FAILED: + Serial.println(F("EV_JOIN_FAILED")); + break; + case EV_REJOIN_FAILED: + Serial.println(F("EV_REJOIN_FAILED")); + break; + case EV_TXCOMPLETE: + Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); + if (LMIC.txrxFlags & TXRX_ACK) + Serial.println(F("Received ack")); + if (LMIC.dataLen) { + Serial.println(F("Received ")); + Serial.println(LMIC.dataLen); + Serial.println(F(" bytes of payload")); + } + // Schedule next transmission + os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); + break; + case EV_LOST_TSYNC: + Serial.println(F("EV_LOST_TSYNC")); + break; + case EV_RESET: + Serial.println(F("EV_RESET")); + break; + case EV_RXCOMPLETE: + // data received in ping slot + Serial.println(F("EV_RXCOMPLETE")); + break; + case EV_LINK_DEAD: + Serial.println(F("EV_LINK_DEAD")); + break; + case EV_LINK_ALIVE: + Serial.println(F("EV_LINK_ALIVE")); + break; + default: + Serial.println(F("Unknown event")); + break; + } +} + +void do_send(osjob_t* j){ + // Check if there is not a current TX/RX job running + if (LMIC.opmode & OP_TXRXPEND) { + Serial.println(F("OP_TXRXPEND, not sending")); + } else { + // Prepare upstream data transmission at the next possible time. + LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0); + Serial.println(F("Packet queued")); + } + // Next TX is scheduled after TX_COMPLETE event. +} + +void setup() { + Serial.begin(115200); + Serial.println(F("Starting")); + + #ifdef VCC_ENABLE + // For Pinoccio Scout boards + pinMode(VCC_ENABLE, OUTPUT); + digitalWrite(VCC_ENABLE, HIGH); + delay(1000); + #endif + + // LMIC init + os_init(); + // Reset the MAC state. Session and pending data transfers will be discarded. + LMIC_reset(); + + // Set static session parameters. Instead of dynamically establishing a session + // by joining the network, precomputed session parameters are be provided. + #ifdef PROGMEM + // On AVR, these values are stored in flash and only copied to RAM + // once. Copy them to a temporary buffer here, LMIC_setSession will + // copy them into a buffer of its own again. + uint8_t appskey[sizeof(APPSKEY)]; + uint8_t nwkskey[sizeof(NWKSKEY)]; + memcpy_P(appskey, APPSKEY, sizeof(APPSKEY)); + memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY)); + LMIC_setSession (0x1, DEVADDR, nwkskey, appskey); + #else + // If not running an AVR with PROGMEM, just use the arrays directly + LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY); + #endif + + #if defined(CFG_eu868) + // Set up the channels used by the Things Network, which corresponds + // to the defaults of most gateways. Without this, only three base + // channels from the LoRaWAN specification are used, which certainly + // works, so it is good for debugging, but can overload those + // frequencies, so be sure to configure the full frequency range of + // your network here (unless your network autoconfigures them). + // Setting up channels should happen after LMIC_setSession, as that + // configures the minimal channel set. + // NA-US channels 0-71 are configured automatically + LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band + LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band + // TTN defines an additional channel at 869.525Mhz using SF9 for class B + // devices' ping slots. LMIC does not have an easy way to define set this + // frequency and support for class B is spotty and untested, so this + // frequency is not configured here. + #elif defined(CFG_us915) + // NA-US channels 0-71 are configured automatically + // but only one group of 8 should (a subband) should be active + // TTN recommends the second sub band, 1 in a zero based count. + // https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json + LMIC_selectSubBand(1); + #endif + + // Disable link check validation + LMIC_setLinkCheckMode(0); + + // TTN uses SF9 for its RX2 window. + LMIC.dn2Dr = DR_SF9; + + // Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library) + LMIC_setDrTxpow(DR_SF7,14); + + // Start job + do_send(&sendjob); +} + +void loop() { + os_runloop_once(); +} diff --git a/libraries/IBM_LMIC_framework/examples/ttn-otaa/ttn-otaa.ino b/libraries/IBM_LMIC_framework/examples/ttn-otaa/ttn-otaa.ino new file mode 100644 index 0000000..d667aa2 --- /dev/null +++ b/libraries/IBM_LMIC_framework/examples/ttn-otaa/ttn-otaa.ino @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman + * + * Permission is hereby granted, free of charge, to anyone + * obtaining a copy of this document and accompanying files, + * to do whatever they want with them without any restriction, + * including, but not limited to, copying, modification and redistribution. + * NO WARRANTY OF ANY KIND IS PROVIDED. + * + * This example sends a valid LoRaWAN packet with payload "Hello, + * world!", using frequency and encryption settings matching those of + * the The Things Network. + * + * This uses OTAA (Over-the-air activation), where where a DevEUI and + * application key is configured, which are used in an over-the-air + * activation procedure where a DevAddr and session keys are + * assigned/generated for use with all further communication. + * + * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in + * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably + * violated by this sketch when left running for longer)! + + * To use this sketch, first register your application and device with + * the things network, to set or generate an AppEUI, DevEUI and AppKey. + * Multiple devices can use the same AppEUI, but each device has its own + * DevEUI and AppKey. + * + * Do not forget to define the radio type correctly in config.h. + * + *******************************************************************************/ + +#include +#include +#include + +// This EUI must be in little-endian format, so least-significant-byte +// first. When copying an EUI from ttnctl output, this means to reverse +// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, +// 0x70. +static const u1_t PROGMEM APPEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);} + +// This should also be in little endian format, see above. +static const u1_t PROGMEM DEVEUI[8]={ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);} + +// This key should be in big endian format (or, since it is not really a +// number but a block of memory, endianness does not really apply). In +// practice, a key taken from ttnctl can be copied as-is. +// The key shown here is the semtech default key. +static const u1_t PROGMEM APPKEY[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; +void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);} + +static uint8_t mydata[] = "Hello, world!"; +static osjob_t sendjob; + +// Schedule TX every this many seconds (might become longer due to duty +// cycle limitations). +const unsigned TX_INTERVAL = 60; + +// Pin mapping +const lmic_pinmap lmic_pins = { + .nss = 6, + .rxtx = LMIC_UNUSED_PIN, + .rst = 5, + .dio = {2, 3, 4}, +}; + +void onEvent (ev_t ev) { + Serial.print(os_getTime()); + Serial.print(": "); + switch(ev) { + case EV_SCAN_TIMEOUT: + Serial.println(F("EV_SCAN_TIMEOUT")); + break; + case EV_BEACON_FOUND: + Serial.println(F("EV_BEACON_FOUND")); + break; + case EV_BEACON_MISSED: + Serial.println(F("EV_BEACON_MISSED")); + break; + case EV_BEACON_TRACKED: + Serial.println(F("EV_BEACON_TRACKED")); + break; + case EV_JOINING: + Serial.println(F("EV_JOINING")); + break; + case EV_JOINED: + Serial.println(F("EV_JOINED")); + + // Disable link check validation (automatically enabled + // during join, but not supported by TTN at this time). + LMIC_setLinkCheckMode(0); + break; + case EV_RFU1: + Serial.println(F("EV_RFU1")); + break; + case EV_JOIN_FAILED: + Serial.println(F("EV_JOIN_FAILED")); + break; + case EV_REJOIN_FAILED: + Serial.println(F("EV_REJOIN_FAILED")); + break; + break; + case EV_TXCOMPLETE: + Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); + if (LMIC.txrxFlags & TXRX_ACK) + Serial.println(F("Received ack")); + if (LMIC.dataLen) { + Serial.println(F("Received ")); + Serial.println(LMIC.dataLen); + Serial.println(F(" bytes of payload")); + } + // Schedule next transmission + os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); + break; + case EV_LOST_TSYNC: + Serial.println(F("EV_LOST_TSYNC")); + break; + case EV_RESET: + Serial.println(F("EV_RESET")); + break; + case EV_RXCOMPLETE: + // data received in ping slot + Serial.println(F("EV_RXCOMPLETE")); + break; + case EV_LINK_DEAD: + Serial.println(F("EV_LINK_DEAD")); + break; + case EV_LINK_ALIVE: + Serial.println(F("EV_LINK_ALIVE")); + break; + default: + Serial.println(F("Unknown event")); + break; + } +} + +void do_send(osjob_t* j){ + // Check if there is not a current TX/RX job running + if (LMIC.opmode & OP_TXRXPEND) { + Serial.println(F("OP_TXRXPEND, not sending")); + } else { + // Prepare upstream data transmission at the next possible time. + LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0); + Serial.println(F("Packet queued")); + } + // Next TX is scheduled after TX_COMPLETE event. +} + +void setup() { + Serial.begin(9600); + Serial.println(F("Starting")); + + #ifdef VCC_ENABLE + // For Pinoccio Scout boards + pinMode(VCC_ENABLE, OUTPUT); + digitalWrite(VCC_ENABLE, HIGH); + delay(1000); + #endif + + // LMIC init + os_init(); + // Reset the MAC state. Session and pending data transfers will be discarded. + LMIC_reset(); + + // Start job (sending automatically starts OTAA too) + do_send(&sendjob); +} + +void loop() { + os_runloop_once(); +} diff --git a/libraries/IBM_LMIC_framework/examples/ttn/ttn.ino b/libraries/IBM_LMIC_framework/examples/ttn/ttn.ino new file mode 100644 index 0000000..13be9c1 --- /dev/null +++ b/libraries/IBM_LMIC_framework/examples/ttn/ttn.ino @@ -0,0 +1,207 @@ +/******************************************************************************* + * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman + * + * Permission is hereby granted, free of charge, to anyone + * obtaining a copy of this document and accompanying files, + * to do whatever they want with them without any restriction, + * including, but not limited to, copying, modification and redistribution. + * NO WARRANTY OF ANY KIND IS PROVIDED. + * + * This example sends a valid LoRaWAN packet with payload "Hello, + * world!", using frequency and encryption settings matching those of + * the (early prototype version of) The Things Network. + * + * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in g1, + * 0.1% in g2). + * + * Change DEVADDR to a unique address! + * See http://thethingsnetwork.org/wiki/AddressSpace + * + * Do not forget to define the radio type correctly in config.h. + * + *******************************************************************************/ + +#include +#include +#include + +// LoRaWAN NwkSKey, network session key +// This is the default Semtech key, which is used by the prototype TTN +// network initially. +static const PROGMEM u1_t NWKSKEY[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; + +// LoRaWAN AppSKey, application session key +// This is the default Semtech key, which is used by the prototype TTN +// network initially. +static const u1_t PROGMEM APPSKEY[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; + +// LoRaWAN end-device address (DevAddr) +// See http://thethingsnetwork.org/wiki/AddressSpace +static const u4_t DEVADDR = 0x03FF0001 ; // <-- Change this address for every node! + +// These callbacks are only used in over-the-air activation, so they are +// left empty here (we cannot leave them out completely unless +// DISABLE_JOIN is set in config.h, otherwise the linker will complain). +void os_getArtEui (u1_t* buf) { } +void os_getDevEui (u1_t* buf) { } +void os_getDevKey (u1_t* buf) { } + +static uint8_t mydata[] = "Hello, world!"; +static osjob_t sendjob; + +// Schedule TX every this many seconds (might become longer due to duty +// cycle limitations). +const unsigned TX_INTERVAL = 60; + +// Pin mapping +const lmic_pinmap lmic_pins = { + .nss = 6, + .rxtx = LMIC_UNUSED_PIN, + .rst = 5, + .dio = {2, 3, 4}, +}; + +void onEvent (ev_t ev) { + Serial.print(os_getTime()); + Serial.print(": "); + switch(ev) { + case EV_SCAN_TIMEOUT: + Serial.println(F("EV_SCAN_TIMEOUT")); + break; + case EV_BEACON_FOUND: + Serial.println(F("EV_BEACON_FOUND")); + break; + case EV_BEACON_MISSED: + Serial.println(F("EV_BEACON_MISSED")); + break; + case EV_BEACON_TRACKED: + Serial.println(F("EV_BEACON_TRACKED")); + break; + case EV_JOINING: + Serial.println(F("EV_JOINING")); + break; + case EV_JOINED: + Serial.println(F("EV_JOINED")); + break; + case EV_RFU1: + Serial.println(F("EV_RFU1")); + break; + case EV_JOIN_FAILED: + Serial.println(F("EV_JOIN_FAILED")); + break; + case EV_REJOIN_FAILED: + Serial.println(F("EV_REJOIN_FAILED")); + break; + break; + case EV_TXCOMPLETE: + Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); + if(LMIC.dataLen) { + // data received in rx slot after tx + Serial.print(F("Data Received: ")); + Serial.write(LMIC.frame+LMIC.dataBeg, LMIC.dataLen); + Serial.println(); + } + // Schedule next transmission + os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); + break; + case EV_LOST_TSYNC: + Serial.println(F("EV_LOST_TSYNC")); + break; + case EV_RESET: + Serial.println(F("EV_RESET")); + break; + case EV_RXCOMPLETE: + // data received in ping slot + Serial.println(F("EV_RXCOMPLETE")); + break; + case EV_LINK_DEAD: + Serial.println(F("EV_LINK_DEAD")); + break; + case EV_LINK_ALIVE: + Serial.println(F("EV_LINK_ALIVE")); + break; + default: + Serial.println(F("Unknown event")); + break; + } +} + +void do_send(osjob_t* j){ + // Check if there is not a current TX/RX job running + if (LMIC.opmode & OP_TXRXPEND) { + Serial.println(F("OP_TXRXPEND, not sending")); + } else { + // Prepare upstream data transmission at the next possible time. + LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0); + Serial.println(F("Packet queued")); + } + // Next TX is scheduled after TX_COMPLETE event. +} + +void setup() { + Serial.begin(115200); + Serial.println(F("Starting")); + + #ifdef VCC_ENABLE + // For Pinoccio Scout boards + pinMode(VCC_ENABLE, OUTPUT); + digitalWrite(VCC_ENABLE, HIGH); + delay(1000); + #endif + + // LMIC init + os_init(); + // Reset the MAC state. Session and pending data transfers will be discarded. + LMIC_reset(); + + // Set static session parameters. Instead of dynamically establishing a session + // by joining the network, precomputed session parameters are be provided. + #ifdef PROGMEM + // On AVR, these values are stored in flash and only copied to RAM + // once. Copy them to a temporary buffer here, LMIC_setSession will + // copy them into a buffer of its own again. + uint8_t appskey[sizeof(APPSKEY)]; + uint8_t nwkskey[sizeof(NWKSKEY)]; + memcpy_P(appskey, APPSKEY, sizeof(APPSKEY)); + memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY)); + LMIC_setSession (0x1, DEVADDR, nwkskey, appskey); + #else + // If not running an AVR with PROGMEM, just use the arrays directly + LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY); + #endif + + // Set up the channels used by the Things Network, which corresponds + // to the defaults of most gateways. Without this, only three base + // channels from the LoRaWAN specification are used, which certainly + // works, so it is good for debugging, but can overload those + // frequencies, so be sure to configure the full frequency range of + // your network here (unless your network autoconfigures them). + // Setting up channels should happen after LMIC_setSession, as that + // configures the minimal channel set. + LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band + LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band + LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band + // TTN defines an additional channel at 869.525Mhz using SF9 for class B + // devices' ping slots. LMIC does not have an easy way to define set this + // frequency and support for class B is spotty and untested, so this + // frequency is not configured here. + + // Disable link check validation + LMIC_setLinkCheckMode(0); + + // Set data rate and transmit power (note: txpow seems to be ignored by the library) + LMIC_setDrTxpow(DR_SF7,14); + + // Start job + do_send(&sendjob); +} + +void loop() { + os_runloop_once(); +} diff --git a/libraries/IBM_LMIC_framework/library.properties b/libraries/IBM_LMIC_framework/library.properties new file mode 100644 index 0000000..0dbf7d5 --- /dev/null +++ b/libraries/IBM_LMIC_framework/library.properties @@ -0,0 +1,9 @@ +name=IBM LMIC framework +version=1.5.0+arduino-1 +author=IBM +maintainer=Matthijs Kooijman +sentence=Arduino port of the LMIC (LoraWAN-in-C, formerly LoraMAC-in-C) framework provided by IBM. +paragraph=Supports SX1272/SX1276 and HopeRF RFM92/RFM95 tranceivers +category=Communication +url=http://www.research.ibm.com/labs/zurich/ics/lrsc/lmic.html +architectures=* diff --git a/libraries/IBM_LMIC_framework/src/aes/ideetron/AES-128_V10.cpp b/libraries/IBM_LMIC_framework/src/aes/ideetron/AES-128_V10.cpp new file mode 100644 index 0000000..1d790f9 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/aes/ideetron/AES-128_V10.cpp @@ -0,0 +1,342 @@ +/****************************************************************************************** +#if defined(USE_IDEETRON_AES) +* Copyright 2015, 2016 Ideetron B.V. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +******************************************************************************************/ +/****************************************************************************************** +* +* File: AES-128_V10.cpp +* Author: Gerben den Hartog +* Compagny: Ideetron B.V. +* Website: http://www.ideetron.nl/LoRa +* E-mail: info@ideetron.nl +******************************************************************************************/ +/**************************************************************************************** +* +* Created on: 20-10-2015 +* Supported Hardware: ID150119-02 Nexus board with RFM95 +* +* Firmware Version 1.0 +* First version +****************************************************************************************/ + +// This file was taken from +// https://github.com/Ideetron/RFM95W_Nexus/tree/master/LoRaWAN_V31 for +// use with LMIC. It was only cosmetically modified: +// - AES_Encrypt was renamed to lmic_aes_encrypt. +// - All other functions and variables were made static +// - Tabs were converted to 2 spaces +// - An #include and #if guard was added +// - S_Table is now stored in PROGMEM + +#include "../../lmic/oslmic.h" + +#if defined(USE_IDEETRON_AES) + +/* +******************************************************************************************** +* Global Variables +******************************************************************************************** +*/ + +static unsigned char State[4][4]; + +static CONST_TABLE(unsigned char, S_Table)[16][16] = { + {0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76}, + {0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0}, + {0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15}, + {0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75}, + {0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84}, + {0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF}, + {0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8}, + {0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2}, + {0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73}, + {0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB}, + {0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79}, + {0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08}, + {0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A}, + {0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E}, + {0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF}, + {0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16} +}; + +extern "C" void lmic_aes_encrypt(unsigned char *Data, unsigned char *Key); +static void AES_Add_Round_Key(unsigned char *Round_Key); +static unsigned char AES_Sub_Byte(unsigned char Byte); +static void AES_Shift_Rows(); +static void AES_Mix_Collums(); +static void AES_Calculate_Round_Key(unsigned char Round, unsigned char *Round_Key); +static void Send_State(); + +/* +***************************************************************************************** +* Description : Function for encrypting data using AES-128 +* +* Arguments : *Data Data to encrypt is a 16 byte long arry +* *Key Key to encrypt data with is a 16 byte long arry +***************************************************************************************** +*/ +void lmic_aes_encrypt(unsigned char *Data, unsigned char *Key) +{ + unsigned char i; + unsigned char Row,Collum; + unsigned char Round = 0x00; + unsigned char Round_Key[16]; + + //Copy input to State arry + for(Collum = 0; Collum < 4; Collum++) + { + for(Row = 0; Row < 4; Row++) + { + State[Row][Collum] = Data[Row + (4*Collum)]; + } + } + + //Copy key to round key + for(i = 0; i < 16; i++) + { + Round_Key[i] = Key[i]; + } + + //Add round key + AES_Add_Round_Key(Round_Key); + + //Preform 9 full rounds + for(Round = 1; Round < 10; Round++) + { + //Preform Byte substitution with S table + for(Collum = 0; Collum < 4; Collum++) + { + for(Row = 0; Row < 4; Row++) + { + State[Row][Collum] = AES_Sub_Byte(State[Row][Collum]); + } + } + + //Preform Row Shift + AES_Shift_Rows(); + + //Mix Collums + AES_Mix_Collums(); + + //Calculate new round key + AES_Calculate_Round_Key(Round,Round_Key); + + //Add round key + AES_Add_Round_Key(Round_Key); + } + + //Last round whitout mix collums + //Preform Byte substitution with S table + for(Collum = 0; Collum < 4; Collum++) + { + for(Row = 0; Row < 4; Row++) + { + State[Row][Collum] = AES_Sub_Byte(State[Row][Collum]); + } + } + + //Shift rows + AES_Shift_Rows(); + + //Calculate new round key + AES_Calculate_Round_Key(Round,Round_Key); + + //Add round Key + AES_Add_Round_Key(Round_Key); + + //Copy the State into the data array + for(Collum = 0; Collum < 4; Collum++) + { + for(Row = 0; Row < 4; Row++) + { + Data[Row + (4*Collum)] = State[Row][Collum]; + } + } + +} + +/* +***************************************************************************************** +* Description : Function that add's the round key for the current round +* +* Arguments : *Round_Key 16 byte long array holding the Round Key +***************************************************************************************** +*/ +static void AES_Add_Round_Key(unsigned char *Round_Key) +{ + unsigned char Row,Collum; + + for(Collum = 0; Collum < 4; Collum++) + { + for(Row = 0; Row < 4; Row++) + { + State[Row][Collum] = State[Row][Collum] ^ Round_Key[Row + (4*Collum)]; + } + } +} + +/* +***************************************************************************************** +* Description : Function that substitutes a byte with a byte from the S_Table +* +* Arguments : Byte The byte that will be substituted +* +* Return : The return is the found byte in the S_Table +***************************************************************************************** +*/ +static unsigned char AES_Sub_Byte(unsigned char Byte) +{ + unsigned char S_Row,S_Collum; + unsigned char S_Byte; + + //Split byte up in Row and Collum + S_Row = ((Byte >> 4) & 0x0F); + S_Collum = (Byte & 0x0F); + + //Find the correct byte in the S_Table + S_Byte = TABLE_GET_U1_TWODIM(S_Table, S_Row, S_Collum); + + return S_Byte; +} + +/* +***************************************************************************************** +* Description : Function that preforms the shift row operation described in the AES standard +***************************************************************************************** +*/ +static void AES_Shift_Rows() +{ + unsigned char Buffer; + + //Row 0 doesn't change + + //Shift Row 1 one left + //Store firt byte in buffer + Buffer = State[1][0]; + //Shift all bytes + State[1][0] = State[1][1]; + State[1][1] = State[1][2]; + State[1][2] = State[1][3]; + State[1][3] = Buffer; + + //Shift row 2 two left + Buffer = State[2][0]; + State[2][0] = State[2][2]; + State[2][2] = Buffer; + Buffer = State[2][1]; + State[2][1] = State[2][3]; + State[2][3] = Buffer; + + //Shift row 3 three left + Buffer = State[3][3]; + State[3][3] = State[3][2]; + State[3][2] = State[3][1]; + State[3][1] = State[3][0]; + State[3][0] = Buffer; +} + +/* +***************************************************************************************** +* Description : Function that preforms the Mix Collums operation described in the AES standard +***************************************************************************************** +*/ +static void AES_Mix_Collums() +{ + unsigned char Row,Collum; + unsigned char a[4], b[4]; + for(Collum = 0; Collum < 4; Collum++) + { + for(Row = 0; Row < 4; Row++) + { + a[Row] = State[Row][Collum]; + b[Row] = (State[Row][Collum] << 1); + + if((State[Row][Collum] & 0x80) == 0x80) + { + b[Row] = b[Row] ^ 0x1B; + } + } + State[0][Collum] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; + State[1][Collum] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; + State[2][Collum] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; + State[3][Collum] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; + } +} + +/* +***************************************************************************************** +* Description : Function that calculaties the round key for the current round +* +* Arguments : Round Number of current Round +* *Round_Key 16 byte long array holding the Round Key +***************************************************************************************** +*/ +static void AES_Calculate_Round_Key(unsigned char Round, unsigned char *Round_Key) +{ + unsigned char i,j; + unsigned char b; + unsigned char Temp[4]; + unsigned char Buffer; + unsigned char Rcon; + + //Calculate first Temp + //Copy laste byte from previous key + for(i = 0; i < 4; i++) + { + Temp[i] = Round_Key[i+12]; + } + + //Rotate Temp + Buffer = Temp[0]; + Temp[0] = Temp[1]; + Temp[1] = Temp[2]; + Temp[2] = Temp[3]; + Temp[3] = Buffer; + + //Substitute Temp + for(i = 0; i < 4; i++) + { + Temp[i] = AES_Sub_Byte(Temp[i]); + } + + //Calculate Rcon + Rcon = 0x01; + while(Round != 1) + { + b = Rcon & 0x80; + Rcon = Rcon << 1; + if(b == 0x80) + { + Rcon = Rcon ^ 0x1b; + } + Round--; + } + + //XOR Rcon + Temp[0] = Temp[0] ^ Rcon; + + //Calculate new key + for(i = 0; i < 4; i++) + { + for(j = 0; j < 4; j++) + { + Round_Key[j + (4*i)] = Round_Key[j + (4*i)] ^ Temp[j]; + Temp[j] = Round_Key[j + (4*i)]; + } + } +} + +#endif // defined(USE_IDEETRON_AES) diff --git a/libraries/IBM_LMIC_framework/src/aes/lmic.c b/libraries/IBM_LMIC_framework/src/aes/lmic.c new file mode 100644 index 0000000..0da7c80 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/aes/lmic.c @@ -0,0 +1,370 @@ +/******************************************************************************* + * Copyright (c) 2014-2015 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Zurich Research Lab - initial API, implementation and documentation + *******************************************************************************/ + +#include "../lmic/oslmic.h" + +#if defined(USE_ORIGINAL_AES) + +#define AES_MICSUB 0x30 // internal use only + +static CONST_TABLE(u4_t, AES_RCON)[10] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 +}; + +static CONST_TABLE(u1_t, AES_S)[256] = { + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16, +}; + +static CONST_TABLE(u4_t, AES_E1)[256] = { + 0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554, + 0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A, + 0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B, + 0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B, + 0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F, + 0x6834345C, 0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F, + 0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5, + 0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F, + 0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB, + 0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497, + 0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED, + 0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A, + 0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594, + 0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3, + 0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504, + 0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D, + 0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739, + 0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395, + 0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883, + 0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76, + 0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4, + 0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B, + 0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0, + 0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818, + 0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651, + 0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85, + 0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12, + 0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9, + 0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7, + 0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A, + 0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, 0x844242C6, 0xD06868B8, + 0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A, +}; + +static CONST_TABLE(u4_t, AES_E2)[256] = { + 0xA5C66363, 0x84F87C7C, 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5, + 0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, 0xE64DABAB, 0x9AEC7676, + 0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0, + 0xEC41ADAD, 0x67B3D4D4, 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0, + 0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, 0x02F5F7F7, 0x4F83CCCC, + 0x5C683434, 0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515, + 0x0C080404, 0x5295C7C7, 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A, + 0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, 0xCD7FB2B2, 0x9FEA7575, + 0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0, + 0xF6A45252, 0x4D763B3B, 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484, + 0xF5A65353, 0x68B9D1D1, 0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, 0xC879B1B1, 0xEDB65B5B, + 0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF, + 0x6BBBD0D0, 0x2AC5EFEF, 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585, + 0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, 0xBA259F9F, 0xE34BA8A8, + 0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5, + 0xDF63BCBC, 0xC177B6B6, 0x75AFDADA, 0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2, + 0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, 0xCC884444, 0x392E1717, + 0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373, + 0xA0C06060, 0x98198181, 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888, + 0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, 0x1D160B0B, 0x76ADDBDB, + 0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A, 0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C, + 0x5D9FC2C2, 0x6EBDD3D3, 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979, + 0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, 0xD29C4E4E, 0xE049A9A9, + 0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808, + 0xD56FBABA, 0x88F07878, 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6, + 0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B, 0xDC61BDBD, 0x860D8B8B, 0x850F8A8A, + 0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E, + 0xA3C26161, 0x5F6A3535, 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E, + 0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, 0x89078E8E, 0xA7339494, + 0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF, + 0x8F038C8C, 0xF859A1A1, 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6, 0xC6844242, 0xB8D06868, + 0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, 0xD66DBBBB, 0x3A2C1616, +}; + +static CONST_TABLE(u4_t, AES_E3)[256] = { + 0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5, + 0x30506030, 0x01030201, 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76, + 0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, 0x47C98E47, 0xF00BFBF0, + 0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0, + 0xB7C275B7, 0xFD1CE1FD, 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC, + 0x345C6834, 0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, 0x31536231, 0x153F2A15, + 0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A, + 0x07090E07, 0x12362412, 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75, + 0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, 0x5AEEB45A, 0xA0FB5BA0, + 0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384, + 0x53F5A653, 0xD168B9D1, 0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B, + 0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, 0x58E8B058, 0xCF4A85CF, + 0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185, + 0x45CF8A45, 0xF910E9F9, 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8, + 0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, 0x38487038, 0xF504F1F5, + 0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA, 0x21634221, 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2, + 0xCD4C81CD, 0x0C14180C, 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17, + 0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, 0x192B3219, 0x7395E673, + 0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88, + 0x46CA8C46, 0xEE29C7EE, 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB, + 0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A, 0x49DB9249, 0x060A0C06, 0x246C4824, 0x5CE4B85C, + 0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279, + 0xE732D5E7, 0xC8438BC8, 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9, + 0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, 0xAEE947AE, 0x08181008, + 0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6, + 0xE823CBE8, 0xDD7CA1DD, 0x749CE874, 0x1F213E1F, 0x4BDD964B, 0xBDDC61BD, 0x8B860D8B, 0x8A850F8A, + 0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, 0xF601F7F6, 0x0E121C0E, + 0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E, + 0xE138D9E1, 0xF813EBF8, 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394, + 0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, 0x28785028, 0xDF7AA5DF, + 0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, 0xBFDA65BF, 0xE631D7E6, 0x42C68442, 0x68B8D068, + 0x41C38241, 0x99B02999, 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16, +}; + +static CONST_TABLE(u4_t, AES_E4)[256] = { + 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, + 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, + 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, + 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, + 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, + 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, + 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, + 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, + 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, + 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, + 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, + 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, + 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, + 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, + 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, + 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, + 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, + 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, + 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, + 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, + 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, + 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, + 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, + 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, + 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, + 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, + 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, + 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, + 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, + 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, + 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, + 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C, +}; + +#define msbf4_read(p) ((p)[0]<<24 | (p)[1]<<16 | (p)[2]<<8 | (p)[3]) +#define msbf4_write(p,v) (p)[0]=(v)>>24,(p)[1]=(v)>>16,(p)[2]=(v)>>8,(p)[3]=(v) +#define swapmsbf(x) ( (x&0xFF)<<24 | (x&0xFF00)<<8 | (x&0xFF0000)>>8 | (x>>24) ) + +#define u1(v) ((u1_t)(v)) + +#define AES_key4(r1,r2,r3,r0,i) r1 = ki[i+1]; \ + r2 = ki[i+2]; \ + r3 = ki[i+3]; \ + r0 = ki[i] + +#define AES_expr4(r1,r2,r3,r0,i) r1 ^= TABLE_GET_U4(AES_E4, u1(i)); \ + r2 ^= TABLE_GET_U4(AES_E3, u1(i>>8)); \ + r3 ^= TABLE_GET_U4(AES_E2, u1(i>>16)); \ + r0 ^= TABLE_GET_U4(AES_E1, (i>>24)) + +#define AES_expr(a,r0,r1,r2,r3,i) a = ki[i]; \ + a ^= ((u4_t)TABLE_GET_U1(AES_S, r0>>24 )<<24); \ + a ^= ((u4_t)TABLE_GET_U1(AES_S, u1(r1>>16))<<16); \ + a ^= ((u4_t)TABLE_GET_U1(AES_S, u1(r2>> 8))<< 8); \ + a ^= (u4_t)TABLE_GET_U1(AES_S, u1(r3) ) + +// global area for passing parameters (aux, key) and for storing round keys +u4_t AESAUX[16/sizeof(u4_t)]; +u4_t AESKEY[11*16/sizeof(u4_t)]; + +// generate 1+10 roundkeys for encryption with 128-bit key +// read 128-bit key from AESKEY in MSBF, generate roundkey words in place +static void aesroundkeys () { + int i; + u4_t b; + + for( i=0; i<4; i++) { + AESKEY[i] = swapmsbf(AESKEY[i]); + } + + b = AESKEY[3]; + for( ; i<44; i++ ) { + if( i%4==0 ) { + // b = SubWord(RotWord(b)) xor Rcon[i/4] + b = ((u4_t)TABLE_GET_U1(AES_S, u1(b >> 16)) << 24) ^ + ((u4_t)TABLE_GET_U1(AES_S, u1(b >> 8)) << 16) ^ + ((u4_t)TABLE_GET_U1(AES_S, u1(b) ) << 8) ^ + ((u4_t)TABLE_GET_U1(AES_S, b >> 24 ) ) ^ + TABLE_GET_U4(AES_RCON, (i-4)/4); + } + AESKEY[i] = b ^= AESKEY[i-4]; + } +} + +u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) { + + aesroundkeys(); + + if( mode & AES_MICNOAUX ) { + AESAUX[0] = AESAUX[1] = AESAUX[2] = AESAUX[3] = 0; + } else { + AESAUX[0] = swapmsbf(AESAUX[0]); + AESAUX[1] = swapmsbf(AESAUX[1]); + AESAUX[2] = swapmsbf(AESAUX[2]); + AESAUX[3] = swapmsbf(AESAUX[3]); + } + + while( (signed char)len > 0 ) { + u4_t a0, a1, a2, a3; + u4_t t0, t1, t2, t3; + u4_t *ki, *ke; + + // load input block + if( (mode & AES_CTR) || ((mode & AES_MIC) && (mode & AES_MICNOAUX)==0) ) { // load CTR block or first MIC block + a0 = AESAUX[0]; + a1 = AESAUX[1]; + a2 = AESAUX[2]; + a3 = AESAUX[3]; + } + else if( (mode & AES_MIC) && len <= 16 ) { // last MIC block + a0 = a1 = a2 = a3 = 0; // load null block + mode |= ((len == 16) ? 1 : 2) << 4; // set MICSUB: CMAC subkey K1 or K2 + } else + LOADDATA: { // load data block (partially) + for(t0=0; t0<16; t0++) { + t1 = (t1<<8) | ((t0> 4) != 0 ) { // last block + do { + // compute CMAC subkey K1 and K2 + t0 = a0 >> 31; // save MSB + a0 = (a0 << 1) | (a1 >> 31); + a1 = (a1 << 1) | (a2 >> 31); + a2 = (a2 << 1) | (a3 >> 31); + a3 = (a3 << 1); + if( t0 ) a3 ^= 0x87; + } while( --t1 ); + + AESAUX[0] ^= a0; + AESAUX[1] ^= a1; + AESAUX[2] ^= a2; + AESAUX[3] ^= a3; + mode &= ~AES_MICSUB; + goto LOADDATA; + } else { + // save cipher block as new iv + AESAUX[0] = a0; + AESAUX[1] = a1; + AESAUX[2] = a2; + AESAUX[3] = a3; + } + } else { // CIPHER + if( mode & AES_CTR ) { // xor block (partially) + t0 = (len > 16) ? 16: len; + for(t1=0; t1>24); + a0 <<= 8; + if((t1&3)==3) { + a0 = a1; + a1 = a2; + a2 = a3; + } + } + // update counter + AESAUX[3]++; + } else { // ECB + // store block + msbf4_write(buf+0, a0); + msbf4_write(buf+4, a1); + msbf4_write(buf+8, a2); + msbf4_write(buf+12, a3); + } + } + + // update block state + if( (mode & AES_MIC)==0 || (mode & AES_MICNOAUX) ) { + buf += 16; + len -= 16; + } + mode |= AES_MICNOAUX; + } + return AESAUX[0]; +} + +#endif diff --git a/libraries/IBM_LMIC_framework/src/aes/other.c b/libraries/IBM_LMIC_framework/src/aes/other.c new file mode 100644 index 0000000..8ab2be1 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/aes/other.c @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2016 Matthijs Kooijman + * + * LICENSE + * + * Permission is hereby granted, free of charge, to anyone + * obtaining a copy of this document and accompanying files, + * to do whatever they want with them without any restriction, + * including, but not limited to, copying, modification and + * redistribution. + * + * NO WARRANTY OF ANY KIND IS PROVIDED. + *******************************************************************************/ + +/* + * The original LMIC AES implementation integrates raw AES encryption + * with CMAC and AES-CTR in a single piece of code. Most other AES + * implementations (only) offer raw single block AES encryption, so this + * file contains an implementation of CMAC and AES-CTR, and offers the + * same API through the os_aes() function as the original AES + * implementation. This file assumes that there is an encryption + * function available with this signature: + * + * extern "C" void lmic_aes_encrypt(u1_t *data, u1_t *key); + * + * That takes a single 16-byte buffer and encrypts it wit the given + * 16-byte key. + */ + +#include "../lmic/oslmic.h" + +#if !defined(USE_ORIGINAL_AES) + +// This should be defined elsewhere +void lmic_aes_encrypt(u1_t *data, u1_t *key); + +// global area for passing parameters (aux, key) +u4_t AESAUX[16/sizeof(u4_t)]; +u4_t AESKEY[16/sizeof(u4_t)]; + +// Shift the given buffer left one bit +static void shift_left(xref2u1_t buf, u1_t len) { + while (len--) { + u1_t next = len ? buf[1] : 0; + + u1_t val = (*buf << 1); + if (next & 0x80) + val |= 1; + *buf++ = val; + } +} + +// Apply RFC4493 CMAC, using AESKEY as the key. If prepend_aux is true, +// AESAUX is prepended to the message. AESAUX is used as working memory +// in any case. The CMAC result is returned in AESAUX as well. +static void os_aes_cmac(xref2u1_t buf, u2_t len, u1_t prepend_aux) { + if (prepend_aux) + lmic_aes_encrypt(AESaux, AESkey); + else + memset (AESaux, 0, 16); + + while (len > 0) { + u1_t need_padding = 0; + for (u1_t i = 0; i < 16; ++i, ++buf, --len) { + if (len == 0) { + // The message is padded with 0x80 and then zeroes. + // Since zeroes are no-op for xor, we can just skip them + // and leave AESAUX unchanged for them. + AESaux[i] ^= 0x80; + need_padding = 1; + break; + } + AESaux[i] ^= *buf; + } + + if (len == 0) { + // Final block, xor with K1 or K2. K1 and K2 are calculated + // by encrypting the all-zeroes block and then applying some + // shifts and xor on that. + u1_t final_key[16]; + memset(final_key, 0, sizeof(final_key)); + lmic_aes_encrypt(final_key, AESkey); + + // Calculate K1 + u1_t msb = final_key[0] & 0x80; + shift_left(final_key, sizeof(final_key)); + if (msb) + final_key[sizeof(final_key)-1] ^= 0x87; + + // If the final block was not complete, calculate K2 from K1 + if (need_padding) { + msb = final_key[0] & 0x80; + shift_left(final_key, sizeof(final_key)); + if (msb) + final_key[sizeof(final_key)-1] ^= 0x87; + } + + // Xor with K1 or K2 + for (u1_t i = 0; i < sizeof(final_key); ++i) + AESaux[i] ^= final_key[i]; + } + + lmic_aes_encrypt(AESaux, AESkey); + } +} + +// Run AES-CTR using the key in AESKEY and using AESAUX as the +// counter block. The last byte of the counter block will be incremented +// for every block. The given buffer will be encrypted in place. +static void os_aes_ctr (xref2u1_t buf, u2_t len) { + u1_t ctr[16]; + while (len) { + // Encrypt the counter block with the selected key + memcpy(ctr, AESaux, sizeof(ctr)); + lmic_aes_encrypt(ctr, AESkey); + + // Xor the payload with the resulting ciphertext + for (u1_t i = 0; i < 16 && len > 0; i++, len--, buf++) + *buf ^= ctr[i]; + + // Increment the block index byte + AESaux[15]++; + } +} + + +#endif // !defined(USE_ORIGINAL_AES) diff --git a/libraries/IBM_LMIC_framework/src/hal/hal.cpp b/libraries/IBM_LMIC_framework/src/hal/hal.cpp new file mode 100644 index 0000000..53bf359 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/hal/hal.cpp @@ -0,0 +1,253 @@ +/******************************************************************************* + * Copyright (c) 2015 Matthijs Kooijman + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * This the HAL to run LMIC on top of the Arduino environment. + *******************************************************************************/ + +#include +#include +#include "../lmic.h" +#include "hal.h" +#include + +// ----------------------------------------------------------------------------- +// I/O + +static void hal_io_init () { + // NSS and DIO0 are required, DIO1 is required for LoRa, DIO2 for FSK + ASSERT(lmic_pins.nss != LMIC_UNUSED_PIN); + ASSERT(lmic_pins.dio[0] != LMIC_UNUSED_PIN); + ASSERT(lmic_pins.dio[1] != LMIC_UNUSED_PIN || lmic_pins.dio[2] != LMIC_UNUSED_PIN); + + pinMode(lmic_pins.nss, OUTPUT); + if (lmic_pins.rxtx != LMIC_UNUSED_PIN) + pinMode(lmic_pins.rxtx, OUTPUT); + if (lmic_pins.rst != LMIC_UNUSED_PIN) + pinMode(lmic_pins.rst, OUTPUT); + + pinMode(lmic_pins.dio[0], INPUT); + if (lmic_pins.dio[1] != LMIC_UNUSED_PIN) + pinMode(lmic_pins.dio[1], INPUT); + if (lmic_pins.dio[2] != LMIC_UNUSED_PIN) + pinMode(lmic_pins.dio[2], INPUT); +} + +// val == 1 => tx 1 +void hal_pin_rxtx (u1_t val) { + if (lmic_pins.rxtx != LMIC_UNUSED_PIN) + digitalWrite(lmic_pins.rxtx, val); +} + +// set radio RST pin to given value (or keep floating!) +void hal_pin_rst (u1_t val) { + if (lmic_pins.rst == LMIC_UNUSED_PIN) + return; + + if(val == 0 || val == 1) { // drive pin + pinMode(lmic_pins.rst, OUTPUT); + digitalWrite(lmic_pins.rst, val); + } else { // keep pin floating + pinMode(lmic_pins.rst, INPUT); + } +} + +static bool dio_states[NUM_DIO] = {0}; + +static void hal_io_check() { + uint8_t i; + for (i = 0; i < NUM_DIO; ++i) { + if (lmic_pins.dio[i] == LMIC_UNUSED_PIN) + continue; + + if (dio_states[i] != digitalRead(lmic_pins.dio[i])) { + dio_states[i] = !dio_states[i]; + if (dio_states[i]) + radio_irq_handler(i); + } + } +} + +// ----------------------------------------------------------------------------- +// SPI + +static const SPISettings settings(10E6, MSBFIRST, SPI_MODE0); + +static void hal_spi_init () { + SPI.begin(); +} + +void hal_pin_nss (u1_t val) { + if (!val) + SPI.beginTransaction(settings); + else + SPI.endTransaction(); + + //Serial.println(val?">>":"<<"); + digitalWrite(lmic_pins.nss, val); +} + +// perform SPI transaction with radio +u1_t hal_spi (u1_t out) { + u1_t res = SPI.transfer(out); +/* + Serial.print(">"); + Serial.print(out, HEX); + Serial.print("<"); + Serial.println(res, HEX); + */ + return res; +} + +// ----------------------------------------------------------------------------- +// TIME + +static void hal_time_init () { + // Nothing to do +} + +u4_t hal_ticks () { + // Because micros() is scaled down in this function, micros() will + // overflow before the tick timer should, causing the tick timer to + // miss a significant part of its values if not corrected. To fix + // this, the "overflow" serves as an overflow area for the micros() + // counter. It consists of three parts: + // - The US_PER_OSTICK upper bits are effectively an extension for + // the micros() counter and are added to the result of this + // function. + // - The next bit overlaps with the most significant bit of + // micros(). This is used to detect micros() overflows. + // - The remaining bits are always zero. + // + // By comparing the overlapping bit with the corresponding bit in + // the micros() return value, overflows can be detected and the + // upper bits are incremented. This is done using some clever + // bitwise operations, to remove the need for comparisons and a + // jumps, which should result in efficient code. By avoiding shifts + // other than by multiples of 8 as much as possible, this is also + // efficient on AVR (which only has 1-bit shifts). + static uint8_t overflow = 0; + + // Scaled down timestamp. The top US_PER_OSTICK_EXPONENT bits are 0, + // the others will be the lower bits of our return value. + uint32_t scaled = micros() >> US_PER_OSTICK_EXPONENT; + // Most significant byte of scaled + uint8_t msb = scaled >> 24; + // Mask pointing to the overlapping bit in msb and overflow. + const uint8_t mask = (1 << (7 - US_PER_OSTICK_EXPONENT)); + // Update overflow. If the overlapping bit is different + // between overflow and msb, it is added to the stored value, + // so the overlapping bit becomes equal again and, if it changed + // from 1 to 0, the upper bits are incremented. + overflow += (msb ^ overflow) & mask; + + // Return the scaled value with the upper bits of stored added. The + // overlapping bit will be equal and the lower bits will be 0, so + // bitwise or is a no-op for them. + return scaled | ((uint32_t)overflow << 24); + + // 0 leads to correct, but overly complex code (it could just return + // micros() unmodified), 8 leaves no room for the overlapping bit. + static_assert(US_PER_OSTICK_EXPONENT > 0 && US_PER_OSTICK_EXPONENT < 8, "Invalid US_PER_OSTICK_EXPONENT value"); +} + +// Returns the number of ticks until time. Negative values indicate that +// time has already passed. +static s4_t delta_time(u4_t time) { + return (s4_t)(time - hal_ticks()); +} + +void hal_waitUntil (u4_t time) { + s4_t delta = delta_time(time); + // From delayMicroseconds docs: Currently, the largest value that + // will produce an accurate delay is 16383. + while (delta > (16000 / US_PER_OSTICK)) { + delay(16); + delta -= (16000 / US_PER_OSTICK); + } + if (delta > 0) + delayMicroseconds(delta * US_PER_OSTICK); +} + +// check and rewind for target time +u1_t hal_checkTimer (u4_t time) { + // No need to schedule wakeup, since we're not sleeping + return delta_time(time) <= 0; +} + +static uint8_t irqlevel = 0; + +void hal_disableIRQs () { + noInterrupts(); + irqlevel++; +} + +void hal_enableIRQs () { + if(--irqlevel == 0) { + interrupts(); + + // Instead of using proper interrupts (which are a bit tricky + // and/or not available on all pins on AVR), just poll the pin + // values. Since os_runloop disables and re-enables interrupts, + // putting this here makes sure we check at least once every + // loop. + // + // As an additional bonus, this prevents the can of worms that + // we would otherwise get for running SPI transfers inside ISRs + hal_io_check(); + } +} + +void hal_sleep () { + // Not implemented +} + +// ----------------------------------------------------------------------------- + +#if defined(LMIC_PRINTF_TO) +static int uart_putchar (char c, FILE *) +{ + LMIC_PRINTF_TO.write(c) ; + return 0 ; +} + +void hal_printf_init() { + // create a FILE structure to reference our UART output function + static FILE uartout; + memset(&uartout, 0, sizeof(uartout)); + + // fill in the UART file descriptor with pointer to writer. + fdev_setup_stream (&uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); + + // The uart is the standard output device STDOUT. + stdout = &uartout ; +} +#endif // defined(LMIC_PRINTF_TO) + +void hal_init () { + // configure radio I/O and interrupt handler + hal_io_init(); + // configure radio SPI + hal_spi_init(); + // configure timer and interrupt handler + hal_time_init(); +#if defined(LMIC_PRINTF_TO) + // printf support + hal_printf_init(); +#endif +} + +void hal_failed (const char *file, u2_t line) { +#if defined(LMIC_FAILURE_TO) + LMIC_FAILURE_TO.println("FAILURE "); + LMIC_FAILURE_TO.print(file); + LMIC_FAILURE_TO.print(':'); + LMIC_FAILURE_TO.println(line); + LMIC_FAILURE_TO.flush(); +#endif + hal_disableIRQs(); + while(1); +} diff --git a/libraries/IBM_LMIC_framework/src/hal/hal.h b/libraries/IBM_LMIC_framework/src/hal/hal.h new file mode 100644 index 0000000..e096569 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/hal/hal.h @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2015 Matthijs Kooijman + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * This the HAL to run LMIC on top of the Arduino environment. + *******************************************************************************/ +#ifndef _hal_hal_h_ +#define _hal_hal_h_ + +static const int NUM_DIO = 3; + +struct lmic_pinmap { + u1_t nss; + u1_t rxtx; + u1_t rst; + u1_t dio[NUM_DIO]; +}; + +// Use this for any unused pins. +const u1_t LMIC_UNUSED_PIN = 0xff; + +// Declared here, to be defined an initialized by the application +extern const lmic_pinmap lmic_pins; + +#endif // _hal_hal_h_ diff --git a/libraries/IBM_LMIC_framework/src/lmic.h b/libraries/IBM_LMIC_framework/src/lmic.h new file mode 100644 index 0000000..f2c7935 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/lmic.h @@ -0,0 +1,9 @@ +#ifdef __cplusplus +extern "C"{ +#endif + +#include "lmic/lmic.h" + +#ifdef __cplusplus +} +#endif diff --git a/libraries/IBM_LMIC_framework/src/lmic/aes.c b/libraries/IBM_LMIC_framework/src/lmic/aes.c new file mode 100644 index 0000000..ac1cf3e --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/lmic/aes.c @@ -0,0 +1,367 @@ +/******************************************************************************* + * Copyright (c) 2014-2015 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Zurich Research Lab - initial API, implementation and documentation + *******************************************************************************/ + +#include "oslmic.h" + +#define AES_MICSUB 0x30 // internal use only + +static CONST_TABLE(u4_t, AES_RCON)[10] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 +}; + +static CONST_TABLE(u1_t, AES_S)[256] = { + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16, +}; + +static CONST_TABLE(u4_t, AES_E1)[256] = { + 0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554, + 0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A, + 0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B, + 0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B, + 0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F, + 0x6834345C, 0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F, + 0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5, + 0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F, + 0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB, + 0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497, + 0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED, + 0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A, + 0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594, + 0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3, + 0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504, + 0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D, + 0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739, + 0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395, + 0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883, + 0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76, + 0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4, + 0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B, + 0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0, + 0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818, + 0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651, + 0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85, + 0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12, + 0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9, + 0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7, + 0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A, + 0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, 0x844242C6, 0xD06868B8, + 0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A, +}; + +static CONST_TABLE(u4_t, AES_E2)[256] = { + 0xA5C66363, 0x84F87C7C, 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5, + 0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, 0xE64DABAB, 0x9AEC7676, + 0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0, + 0xEC41ADAD, 0x67B3D4D4, 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0, + 0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, 0x02F5F7F7, 0x4F83CCCC, + 0x5C683434, 0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515, + 0x0C080404, 0x5295C7C7, 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A, + 0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, 0xCD7FB2B2, 0x9FEA7575, + 0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0, + 0xF6A45252, 0x4D763B3B, 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484, + 0xF5A65353, 0x68B9D1D1, 0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, 0xC879B1B1, 0xEDB65B5B, + 0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF, + 0x6BBBD0D0, 0x2AC5EFEF, 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585, + 0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, 0xBA259F9F, 0xE34BA8A8, + 0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5, + 0xDF63BCBC, 0xC177B6B6, 0x75AFDADA, 0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2, + 0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, 0xCC884444, 0x392E1717, + 0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373, + 0xA0C06060, 0x98198181, 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888, + 0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, 0x1D160B0B, 0x76ADDBDB, + 0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A, 0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C, + 0x5D9FC2C2, 0x6EBDD3D3, 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979, + 0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, 0xD29C4E4E, 0xE049A9A9, + 0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808, + 0xD56FBABA, 0x88F07878, 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6, + 0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B, 0xDC61BDBD, 0x860D8B8B, 0x850F8A8A, + 0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E, + 0xA3C26161, 0x5F6A3535, 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E, + 0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, 0x89078E8E, 0xA7339494, + 0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF, + 0x8F038C8C, 0xF859A1A1, 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6, 0xC6844242, 0xB8D06868, + 0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, 0xD66DBBBB, 0x3A2C1616, +}; + +static CONST_TABLE(u4_t, AES_E3)[256] = { + 0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5, + 0x30506030, 0x01030201, 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76, + 0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, 0x47C98E47, 0xF00BFBF0, + 0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0, + 0xB7C275B7, 0xFD1CE1FD, 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC, + 0x345C6834, 0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, 0x31536231, 0x153F2A15, + 0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A, + 0x07090E07, 0x12362412, 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75, + 0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, 0x5AEEB45A, 0xA0FB5BA0, + 0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384, + 0x53F5A653, 0xD168B9D1, 0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B, + 0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, 0x58E8B058, 0xCF4A85CF, + 0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185, + 0x45CF8A45, 0xF910E9F9, 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8, + 0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, 0x38487038, 0xF504F1F5, + 0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA, 0x21634221, 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2, + 0xCD4C81CD, 0x0C14180C, 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17, + 0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, 0x192B3219, 0x7395E673, + 0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88, + 0x46CA8C46, 0xEE29C7EE, 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB, + 0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A, 0x49DB9249, 0x060A0C06, 0x246C4824, 0x5CE4B85C, + 0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279, + 0xE732D5E7, 0xC8438BC8, 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9, + 0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, 0xAEE947AE, 0x08181008, + 0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6, + 0xE823CBE8, 0xDD7CA1DD, 0x749CE874, 0x1F213E1F, 0x4BDD964B, 0xBDDC61BD, 0x8B860D8B, 0x8A850F8A, + 0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, 0xF601F7F6, 0x0E121C0E, + 0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E, + 0xE138D9E1, 0xF813EBF8, 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394, + 0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, 0x28785028, 0xDF7AA5DF, + 0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, 0xBFDA65BF, 0xE631D7E6, 0x42C68442, 0x68B8D068, + 0x41C38241, 0x99B02999, 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16, +}; + +static CONST_TABLE(u4_t, AES_E4)[256] = { + 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, + 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, + 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, + 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, + 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, + 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, + 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, + 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, + 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, + 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, + 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, + 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, + 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, + 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, + 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, + 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, + 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, + 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, + 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, + 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, + 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, + 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, + 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, + 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, + 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, + 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, + 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, + 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, + 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, + 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, + 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, + 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C, +}; + +#define msbf4_read(p) ((p)[0]<<24 | (p)[1]<<16 | (p)[2]<<8 | (p)[3]) +#define msbf4_write(p,v) (p)[0]=(v)>>24,(p)[1]=(v)>>16,(p)[2]=(v)>>8,(p)[3]=(v) +#define swapmsbf(x) ( (x&0xFF)<<24 | (x&0xFF00)<<8 | (x&0xFF0000)>>8 | (x>>24) ) + +#define u1(v) ((u1_t)(v)) + +#define AES_key4(r1,r2,r3,r0,i) r1 = ki[i+1]; \ + r2 = ki[i+2]; \ + r3 = ki[i+3]; \ + r0 = ki[i] + +#define AES_expr4(r1,r2,r3,r0,i) r1 ^= TABLE_GET_U4(AES_E4, u1(i)); \ + r2 ^= TABLE_GET_U4(AES_E3, u1(i>>8)); \ + r3 ^= TABLE_GET_U4(AES_E2, u1(i>>16)); \ + r0 ^= TABLE_GET_U4(AES_E1, (i>>24)) + +#define AES_expr(a,r0,r1,r2,r3,i) a = ki[i]; \ + a ^= ((u4_t)TABLE_GET_U1(AES_S, r0>>24 )<<24); \ + a ^= ((u4_t)TABLE_GET_U1(AES_S, u1(r1>>16))<<16); \ + a ^= ((u4_t)TABLE_GET_U1(AES_S, u1(r2>> 8))<< 8); \ + a ^= (u4_t)TABLE_GET_U1(AES_S, u1(r3) ) + +// global area for passing parameters (aux, key) and for storing round keys +u4_t AESAUX[16/sizeof(u4_t)]; +u4_t AESKEY[11*16/sizeof(u4_t)]; + +// generate 1+10 roundkeys for encryption with 128-bit key +// read 128-bit key from AESKEY in MSBF, generate roundkey words in place +static void aesroundkeys () { + int i; + u4_t b; + + for( i=0; i<4; i++) { + AESKEY[i] = swapmsbf(AESKEY[i]); + } + + b = AESKEY[3]; + for( ; i<44; i++ ) { + if( i%4==0 ) { + // b = SubWord(RotWord(b)) xor Rcon[i/4] + b = ((u4_t)TABLE_GET_U1(AES_S, u1(b >> 16)) << 24) ^ + ((u4_t)TABLE_GET_U1(AES_S, u1(b >> 8)) << 16) ^ + ((u4_t)TABLE_GET_U1(AES_S, u1(b) ) << 8) ^ + ((u4_t)TABLE_GET_U1(AES_S, b >> 24 ) ) ^ + TABLE_GET_U4(AES_RCON, (i-4)/4); + } + AESKEY[i] = b ^= AESKEY[i-4]; + } +} + +u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) { + + aesroundkeys(); + + if( mode & AES_MICNOAUX ) { + AESAUX[0] = AESAUX[1] = AESAUX[2] = AESAUX[3] = 0; + } else { + AESAUX[0] = swapmsbf(AESAUX[0]); + AESAUX[1] = swapmsbf(AESAUX[1]); + AESAUX[2] = swapmsbf(AESAUX[2]); + AESAUX[3] = swapmsbf(AESAUX[3]); + } + + while( (signed char)len > 0 ) { + u4_t a0, a1, a2, a3; + u4_t t0, t1, t2, t3; + u4_t *ki, *ke; + + // load input block + if( (mode & AES_CTR) || ((mode & AES_MIC) && (mode & AES_MICNOAUX)==0) ) { // load CTR block or first MIC block + a0 = AESAUX[0]; + a1 = AESAUX[1]; + a2 = AESAUX[2]; + a3 = AESAUX[3]; + } + else if( (mode & AES_MIC) && len <= 16 ) { // last MIC block + a0 = a1 = a2 = a3 = 0; // load null block + mode |= ((len == 16) ? 1 : 2) << 4; // set MICSUB: CMAC subkey K1 or K2 + } else + LOADDATA: { // load data block (partially) + for(t0=0; t0<16; t0++) { + t1 = (t1<<8) | ((t0> 4) != 0 ) { // last block + do { + // compute CMAC subkey K1 and K2 + t0 = a0 >> 31; // save MSB + a0 = (a0 << 1) | (a1 >> 31); + a1 = (a1 << 1) | (a2 >> 31); + a2 = (a2 << 1) | (a3 >> 31); + a3 = (a3 << 1); + if( t0 ) a3 ^= 0x87; + } while( --t1 ); + + AESAUX[0] ^= a0; + AESAUX[1] ^= a1; + AESAUX[2] ^= a2; + AESAUX[3] ^= a3; + mode &= ~AES_MICSUB; + goto LOADDATA; + } else { + // save cipher block as new iv + AESAUX[0] = a0; + AESAUX[1] = a1; + AESAUX[2] = a2; + AESAUX[3] = a3; + } + } else { // CIPHER + if( mode & AES_CTR ) { // xor block (partially) + t0 = (len > 16) ? 16: len; + for(t1=0; t1>24); + a0 <<= 8; + if((t1&3)==3) { + a0 = a1; + a1 = a2; + a2 = a3; + } + } + // update counter + AESAUX[3]++; + } else { // ECB + // store block + msbf4_write(buf+0, a0); + msbf4_write(buf+4, a1); + msbf4_write(buf+8, a2); + msbf4_write(buf+12, a3); + } + } + + // update block state + if( (mode & AES_MIC)==0 || (mode & AES_MICNOAUX) ) { + buf += 16; + len -= 16; + } + mode |= AES_MICNOAUX; + } + return AESAUX[0]; +} + diff --git a/libraries/IBM_LMIC_framework/src/lmic/config.h b/libraries/IBM_LMIC_framework/src/lmic/config.h new file mode 100644 index 0000000..23e705b --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/lmic/config.h @@ -0,0 +1,83 @@ +#ifndef _lmic_config_h_ +#define _lmic_config_h_ + +// In the original LMIC code, these config values were defined on the +// gcc commandline. Since Arduino does not allow easily modifying the +// compiler commandline, use this file instead. + +#define CFG_eu868 1 +//#define CFG_us915 1 +// This is the SX1272/SX1273 radio, which is also used on the HopeRF +// RFM92 boards. +//#define CFG_sx1272_radio 1 +// This is the SX1276/SX1277/SX1278/SX1279 radio, which is also used on +// the HopeRF RFM95 boards. +#define CFG_sx1276_radio 1 + +// 16 μs per tick +// LMIC requires ticks to be 15.5μs - 100 μs long +#define US_PER_OSTICK_EXPONENT 4 +#define US_PER_OSTICK (1 << US_PER_OSTICK_EXPONENT) +#define OSTICKS_PER_SEC (1000000 / US_PER_OSTICK) + +// Set this to 1 to enable some basic debug output (using printf) about +// RF settings used during transmission and reception. Set to 2 to +// enable more verbose output. Make sure that printf is actually +// configured (e.g. on AVR it is not by default), otherwise using it can +// cause crashing. +#define LMIC_DEBUG_LEVEL 0 + +// Enable this to allow using printf() to print to the given serial port +// (or any other Print object). This can be easy for debugging. The +// current implementation only works on AVR, though. +//#define LMIC_PRINTF_TO Serial + +// Any runtime assertion failures are printed to this serial port (or +// any other Print object). If this is unset, any failures just silently +// halt execution. +#define LMIC_FAILURE_TO Serial + +// Uncomment this to disable all code related to joining +//#define DISABLE_JOIN +// Uncomment this to disable all code related to ping +//#define DISABLE_PING +// Uncomment this to disable all code related to beacon tracking. +// Requires ping to be disabled too +//#define DISABLE_BEACONS + +// Uncomment these to disable the corresponding MAC commands. +// Class A +//#define DISABLE_MCMD_DCAP_REQ // duty cycle cap +//#define DISABLE_MCMD_DN2P_SET // 2nd DN window param +//#define DISABLE_MCMD_SNCH_REQ // set new channel +// Class B +//#define DISABLE_MCMD_PING_SET // set ping freq, automatically disabled by DISABLE_PING +//#define DISABLE_MCMD_BCNI_ANS // next beacon start, automatical disabled by DISABLE_BEACON + +// In LoRaWAN, a gateway applies I/Q inversion on TX, and nodes do the +// same on RX. This ensures that gateways can talk to nodes and vice +// versa, but gateways will not hear other gateways and nodes will not +// hear other nodes. By uncommenting this macro, this inversion is +// disabled and this node can hear other nodes. If two nodes both have +// this macro set, they can talk to each other (but they can no longer +// hear gateways). This should probably only be used when debugging +// and/or when talking to the radio directly (e.g. like in the "raw" +// example). +//#define DISABLE_INVERT_IQ_ON_RX + +// This allows choosing between multiple included AES implementations. +// Make sure exactly one of these is uncommented. +// +// This selects the original AES implementation included LMIC. This +// implementation is optimized for speed on 32-bit processors using +// fairly big lookup tables, but it takes up big amounts of flash on the +// AVR architecture. +// #define USE_ORIGINAL_AES +// +// This selects the AES implementation written by Ideetroon for their +// own LoRaWAN library. It also uses lookup tables, but smaller +// byte-oriented ones, making it use a lot less flash space (but it is +// also about twice as slow as the original). +#define USE_IDEETRON_AES + +#endif // _lmic_config_h_ diff --git a/libraries/IBM_LMIC_framework/src/lmic/hal.h b/libraries/IBM_LMIC_framework/src/lmic/hal.h new file mode 100644 index 0000000..e073ba8 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/lmic/hal.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2014-2015 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Zurich Research Lab - initial API, implementation and documentation + *******************************************************************************/ + +#ifndef _hal_hpp_ +#define _hal_hpp_ + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * initialize hardware (IO, SPI, TIMER, IRQ). + */ +void hal_init (void); + +/* + * drive radio NSS pin (0=low, 1=high). + */ +void hal_pin_nss (u1_t val); + +/* + * drive radio RX/TX pins (0=rx, 1=tx). + */ +void hal_pin_rxtx (u1_t val); + +/* + * control radio RST pin (0=low, 1=high, 2=floating) + */ +void hal_pin_rst (u1_t val); + +/* + * perform 8-bit SPI transaction with radio. + * - write given byte 'outval' + * - read byte and return value + */ +u1_t hal_spi (u1_t outval); + +/* + * disable all CPU interrupts. + * - might be invoked nested + * - will be followed by matching call to hal_enableIRQs() + */ +void hal_disableIRQs (void); + +/* + * enable CPU interrupts. + */ +void hal_enableIRQs (void); + +/* + * put system and CPU in low-power mode, sleep until interrupt. + */ +void hal_sleep (void); + +/* + * return 32-bit system time in ticks. + */ +u4_t hal_ticks (void); + +/* + * busy-wait until specified timestamp (in ticks) is reached. + */ +void hal_waitUntil (u4_t time); + +/* + * check and rewind timer for target time. + * - return 1 if target time is close + * - otherwise rewind timer for target time or full period and return 0 + */ +u1_t hal_checkTimer (u4_t targettime); + +/* + * perform fatal failure action. + * - called by assertions + * - action could be HALT or reboot + */ +void hal_failed (const char *file, u2_t line); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _hal_hpp_ diff --git a/libraries/IBM_LMIC_framework/src/lmic/lmic.c b/libraries/IBM_LMIC_framework/src/lmic/lmic.c new file mode 100644 index 0000000..3802028 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/lmic/lmic.c @@ -0,0 +1,2382 @@ +/******************************************************************************* + * Copyright (c) 2014-2015 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Zurich Research Lab - initial API, implementation and documentation + *******************************************************************************/ + +//! \file +#include "lmic.h" + +#if defined(DISABLE_BEACONS) && !defined(DISABLE_PING) +#error Ping needs beacon tracking +#endif + +#if !defined(MINRX_SYMS) +#define MINRX_SYMS 5 +#endif // !defined(MINRX_SYMS) +#define PAMBL_SYMS 8 +#define PAMBL_FSK 5 +#define PRERX_FSK 1 +#define RXLEN_FSK (1+5+2) + +#define BCN_INTV_osticks sec2osticks(BCN_INTV_sec) +#define TXRX_GUARD_osticks ms2osticks(TXRX_GUARD_ms) +#define JOIN_GUARD_osticks ms2osticks(JOIN_GUARD_ms) +#define DELAY_JACC1_osticks sec2osticks(DELAY_JACC1) +#define DELAY_JACC2_osticks sec2osticks(DELAY_JACC2) +#define DELAY_EXTDNW2_osticks sec2osticks(DELAY_EXTDNW2) +#define BCN_RESERVE_osticks ms2osticks(BCN_RESERVE_ms) +#define BCN_GUARD_osticks ms2osticks(BCN_GUARD_ms) +#define BCN_WINDOW_osticks ms2osticks(BCN_WINDOW_ms) +#define AIRTIME_BCN_osticks us2osticks(AIRTIME_BCN) +#if defined(CFG_eu868) +#define DNW2_SAFETY_ZONE ms2osticks(3000) +#endif +#if defined(CFG_us915) +#define DNW2_SAFETY_ZONE ms2osticks(750) +#endif + +// Special APIs - for development or testing +#define isTESTMODE() 0 + +DEFINE_LMIC; + + +// Fwd decls. +static void engineUpdate(void); +static void startScan (void); + + +// ================================================================================ +// BEG OS - default implementations for certain OS suport functions + +#if !defined(HAS_os_calls) + +#if !defined(os_rlsbf2) +u2_t os_rlsbf2 (xref2cu1_t buf) { + return (u2_t)((u2_t)buf[0] | ((u2_t)buf[1]<<8)); +} +#endif + +#if !defined(os_rlsbf4) +u4_t os_rlsbf4 (xref2cu1_t buf) { + return (u4_t)((u4_t)buf[0] | ((u4_t)buf[1]<<8) | ((u4_t)buf[2]<<16) | ((u4_t)buf[3]<<24)); +} +#endif + + +#if !defined(os_rmsbf4) +u4_t os_rmsbf4 (xref2cu1_t buf) { + return (u4_t)((u4_t)buf[3] | ((u4_t)buf[2]<<8) | ((u4_t)buf[1]<<16) | ((u4_t)buf[0]<<24)); +} +#endif + + +#if !defined(os_wlsbf2) +void os_wlsbf2 (xref2u1_t buf, u2_t v) { + buf[0] = v; + buf[1] = v>>8; +} +#endif + +#if !defined(os_wlsbf4) +void os_wlsbf4 (xref2u1_t buf, u4_t v) { + buf[0] = v; + buf[1] = v>>8; + buf[2] = v>>16; + buf[3] = v>>24; +} +#endif + +#if !defined(os_wmsbf4) +void os_wmsbf4 (xref2u1_t buf, u4_t v) { + buf[3] = v; + buf[2] = v>>8; + buf[1] = v>>16; + buf[0] = v>>24; +} +#endif + +#if !defined(os_getBattLevel) +u1_t os_getBattLevel (void) { + return MCMD_DEVS_BATT_NOINFO; +} +#endif + +#if !defined(os_crc16) +// New CRC-16 CCITT(XMODEM) checksum for beacons: +u2_t os_crc16 (xref2u1_t data, uint len) { + u2_t remainder = 0; + u2_t polynomial = 0x1021; + for( uint i = 0; i < len; i++ ) { + remainder ^= data[i] << 8; + for( u1_t bit = 8; bit > 0; bit--) { + if( (remainder & 0x8000) ) + remainder = (remainder << 1) ^ polynomial; + else + remainder <<= 1; + } + } + return remainder; +} +#endif + +#endif // !HAS_os_calls + +// END OS - default implementations for certain OS suport functions +// ================================================================================ + +// ================================================================================ +// BEG AES + +static void micB0 (u4_t devaddr, u4_t seqno, int dndir, int len) { + os_clearMem(AESaux,16); + AESaux[0] = 0x49; + AESaux[5] = dndir?1:0; + AESaux[15] = len; + os_wlsbf4(AESaux+ 6,devaddr); + os_wlsbf4(AESaux+10,seqno); +} + + +static int aes_verifyMic (xref2cu1_t key, u4_t devaddr, u4_t seqno, int dndir, xref2u1_t pdu, int len) { + micB0(devaddr, seqno, dndir, len); + os_copyMem(AESkey,key,16); + return os_aes(AES_MIC, pdu, len) == os_rmsbf4(pdu+len); +} + + +static void aes_appendMic (xref2cu1_t key, u4_t devaddr, u4_t seqno, int dndir, xref2u1_t pdu, int len) { + micB0(devaddr, seqno, dndir, len); + os_copyMem(AESkey,key,16); + // MSB because of internal structure of AES + os_wmsbf4(pdu+len, os_aes(AES_MIC, pdu, len)); +} + + +static void aes_appendMic0 (xref2u1_t pdu, int len) { + os_getDevKey(AESkey); + os_wmsbf4(pdu+len, os_aes(AES_MIC|AES_MICNOAUX, pdu, len)); // MSB because of internal structure of AES +} + + +static int aes_verifyMic0 (xref2u1_t pdu, int len) { + os_getDevKey(AESkey); + return os_aes(AES_MIC|AES_MICNOAUX, pdu, len) == os_rmsbf4(pdu+len); +} + + +static void aes_encrypt (xref2u1_t pdu, int len) { + os_getDevKey(AESkey); + os_aes(AES_ENC, pdu, len); +} + + +static void aes_cipher (xref2cu1_t key, u4_t devaddr, u4_t seqno, int dndir, xref2u1_t payload, int len) { + if( len <= 0 ) + return; + os_clearMem(AESaux, 16); + AESaux[0] = AESaux[15] = 1; // mode=cipher / dir=down / block counter=1 + AESaux[5] = dndir?1:0; + os_wlsbf4(AESaux+ 6,devaddr); + os_wlsbf4(AESaux+10,seqno); + os_copyMem(AESkey,key,16); + os_aes(AES_CTR, payload, len); +} + + +static void aes_sessKeys (u2_t devnonce, xref2cu1_t artnonce, xref2u1_t nwkkey, xref2u1_t artkey) { + os_clearMem(nwkkey, 16); + nwkkey[0] = 0x01; + os_copyMem(nwkkey+1, artnonce, LEN_ARTNONCE+LEN_NETID); + os_wlsbf2(nwkkey+1+LEN_ARTNONCE+LEN_NETID, devnonce); + os_copyMem(artkey, nwkkey, 16); + artkey[0] = 0x02; + + os_getDevKey(AESkey); + os_aes(AES_ENC, nwkkey, 16); + os_getDevKey(AESkey); + os_aes(AES_ENC, artkey, 16); +} + +// END AES +// ================================================================================ + + +// ================================================================================ +// BEG LORA + +#if defined(CFG_eu868) // ======================================== + +#define maxFrameLen(dr) ((dr)<=DR_SF9 ? TABLE_GET_U1(maxFrameLens, (dr)) : 0xFF) +CONST_TABLE(u1_t, maxFrameLens) [] = { 64,64,64,123 }; + +CONST_TABLE(u1_t, _DR2RPS_CRC)[] = { + ILLEGAL_RPS, + (u1_t)MAKERPS(SF12, BW125, CR_4_5, 0, 0), + (u1_t)MAKERPS(SF11, BW125, CR_4_5, 0, 0), + (u1_t)MAKERPS(SF10, BW125, CR_4_5, 0, 0), + (u1_t)MAKERPS(SF9, BW125, CR_4_5, 0, 0), + (u1_t)MAKERPS(SF8, BW125, CR_4_5, 0, 0), + (u1_t)MAKERPS(SF7, BW125, CR_4_5, 0, 0), + (u1_t)MAKERPS(SF7, BW250, CR_4_5, 0, 0), + (u1_t)MAKERPS(FSK, BW125, CR_4_5, 0, 0), + ILLEGAL_RPS +}; + +static CONST_TABLE(s1_t, TXPOWLEVELS)[] = { + 20, 14, 11, 8, 5, 2, 0,0, 0,0,0,0, 0,0,0,0 +}; +#define pow2dBm(mcmd_ladr_p1) (TABLE_GET_S1(TXPOWLEVELS, (mcmd_ladr_p1&MCMD_LADR_POW_MASK)>>MCMD_LADR_POW_SHIFT)) + +#elif defined(CFG_us915) // ======================================== + +#define maxFrameLen(dr) ((dr)<=DR_SF11CR ? TABLE_GET_U1(maxFrameLens, (dr)) : 0xFF) +CONST_TABLE(u1_t, maxFrameLens) [] = { 24,66,142,255,255,255,255,255, 66,142 }; + +CONST_TABLE(u1_t, _DR2RPS_CRC)[] = { + ILLEGAL_RPS, + MAKERPS(SF10, BW125, CR_4_5, 0, 0), + MAKERPS(SF9 , BW125, CR_4_5, 0, 0), + MAKERPS(SF8 , BW125, CR_4_5, 0, 0), + MAKERPS(SF7 , BW125, CR_4_5, 0, 0), + MAKERPS(SF8 , BW500, CR_4_5, 0, 0), + ILLEGAL_RPS , + ILLEGAL_RPS , + ILLEGAL_RPS , + MAKERPS(SF12, BW500, CR_4_5, 0, 0), + MAKERPS(SF11, BW500, CR_4_5, 0, 0), + MAKERPS(SF10, BW500, CR_4_5, 0, 0), + MAKERPS(SF9 , BW500, CR_4_5, 0, 0), + MAKERPS(SF8 , BW500, CR_4_5, 0, 0), + MAKERPS(SF7 , BW500, CR_4_5, 0, 0), + ILLEGAL_RPS +}; + +#define pow2dBm(mcmd_ladr_p1) ((s1_t)(30 - (((mcmd_ladr_p1)&MCMD_LADR_POW_MASK)<<1))) + +#endif // ================================================ + +static CONST_TABLE(u1_t, SENSITIVITY)[7][3] = { + // ------------bw---------- + // 125kHz 250kHz 500kHz + { 141-109, 141-109, 141-109 }, // FSK + { 141-127, 141-124, 141-121 }, // SF7 + { 141-129, 141-126, 141-123 }, // SF8 + { 141-132, 141-129, 141-126 }, // SF9 + { 141-135, 141-132, 141-129 }, // SF10 + { 141-138, 141-135, 141-132 }, // SF11 + { 141-141, 141-138, 141-135 } // SF12 +}; + +int getSensitivity (rps_t rps) { + return -141 + TABLE_GET_U1_TWODIM(SENSITIVITY, getSf(rps), getBw(rps)); +} + +ostime_t calcAirTime (rps_t rps, u1_t plen) { + u1_t bw = getBw(rps); // 0,1,2 = 125,250,500kHz + u1_t sf = getSf(rps); // 0=FSK, 1..6 = SF7..12 + if( sf == FSK ) { + return (plen+/*preamble*/5+/*syncword*/3+/*len*/1+/*crc*/2) * /*bits/byte*/8 + * (s4_t)OSTICKS_PER_SEC / /*kbit/s*/50000; + } + u1_t sfx = 4*(sf+(7-SF7)); + u1_t q = sfx - (sf >= SF11 ? 8 : 0); + int tmp = 8*plen - sfx + 28 + (getNocrc(rps)?0:16) - (getIh(rps)?20:0); + if( tmp > 0 ) { + tmp = (tmp + q - 1) / q; + tmp *= getCr(rps)+5; + tmp += 8; + } else { + tmp = 8; + } + tmp = (tmp<<2) + /*preamble*/49 /* 4 * (8 + 4.25) */; + // bw = 125000 = 15625 * 2^3 + // 250000 = 15625 * 2^4 + // 500000 = 15625 * 2^5 + // sf = 7..12 + // + // osticks = tmp * OSTICKS_PER_SEC * 1< counter reduced divisor 125000/8 => 15625 + // 2 => counter 2 shift on tmp + sfx = sf+(7-SF7) - (3+2) - bw; + int div = 15625; + if( sfx > 4 ) { + // prevent 32bit signed int overflow in last step + div >>= sfx-4; + sfx = 4; + } + // Need 32bit arithmetic for this last step + return (((ostime_t)tmp << sfx) * OSTICKS_PER_SEC + div/2) / div; +} + +extern inline rps_t updr2rps (dr_t dr); +extern inline rps_t dndr2rps (dr_t dr); +extern inline int isFasterDR (dr_t dr1, dr_t dr2); +extern inline int isSlowerDR (dr_t dr1, dr_t dr2); +extern inline dr_t incDR (dr_t dr); +extern inline dr_t decDR (dr_t dr); +extern inline dr_t assertDR (dr_t dr); +extern inline dr_t validDR (dr_t dr); +extern inline dr_t lowerDR (dr_t dr, u1_t n); + +extern inline sf_t getSf (rps_t params); +extern inline rps_t setSf (rps_t params, sf_t sf); +extern inline bw_t getBw (rps_t params); +extern inline rps_t setBw (rps_t params, bw_t cr); +extern inline cr_t getCr (rps_t params); +extern inline rps_t setCr (rps_t params, cr_t cr); +extern inline int getNocrc (rps_t params); +extern inline rps_t setNocrc (rps_t params, int nocrc); +extern inline int getIh (rps_t params); +extern inline rps_t setIh (rps_t params, int ih); +extern inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc); +extern inline int sameSfBw (rps_t r1, rps_t r2); + +// END LORA +// ================================================================================ + + +// Adjust DR for TX retries +// - indexed by retry count +// - return steps to lower DR +static CONST_TABLE(u1_t, DRADJUST)[2+TXCONF_ATTEMPTS] = { + // normal frames - 1st try / no retry + 0, + // confirmed frames + 0,0,1,0,1,0,1,0,0 +}; + + +// Table below defines the size of one symbol as +// symtime = 256us * 2^T(sf,bw) +// 256us is called one symunit. +// SF: +// BW: |__7___8___9__10__11__12 +// 125kHz | 2 3 4 5 6 7 +// 250kHz | 1 2 3 4 5 6 +// 500kHz | 0 1 2 3 4 5 +// +// Times for half symbol per DR +// Per DR table to minimize rounding errors +static CONST_TABLE(ostime_t, DR2HSYM_osticks)[] = { +#if defined(CFG_eu868) +#define dr2hsym(dr) (TABLE_GET_OSTIME(DR2HSYM_osticks, (dr))) + us2osticksRound(128<<7), // DR_SF12 + us2osticksRound(128<<6), // DR_SF11 + us2osticksRound(128<<5), // DR_SF10 + us2osticksRound(128<<4), // DR_SF9 + us2osticksRound(128<<3), // DR_SF8 + us2osticksRound(128<<2), // DR_SF7 + us2osticksRound(128<<1), // DR_SF7B + us2osticksRound(80) // FSK -- not used (time for 1/2 byte) +#elif defined(CFG_us915) +#define dr2hsym(dr) (TABLE_GET_OSTIME(DR2HSYM_osticks, (dr)&7)) // map DR_SFnCR -> 0-6 + us2osticksRound(128<<5), // DR_SF10 DR_SF12CR + us2osticksRound(128<<4), // DR_SF9 DR_SF11CR + us2osticksRound(128<<3), // DR_SF8 DR_SF10CR + us2osticksRound(128<<2), // DR_SF7 DR_SF9CR + us2osticksRound(128<<1), // DR_SF8C DR_SF8CR + us2osticksRound(128<<0) // ------ DR_SF7CR +#endif +}; + + +#if !defined(DISABLE_BEACONS) +static ostime_t calcRxWindow (u1_t secs, dr_t dr) { + ostime_t rxoff, err; + if( secs==0 ) { + // aka 128 secs (next becaon) + rxoff = LMIC.drift; + err = LMIC.lastDriftDiff; + } else { + // scheduled RX window within secs into current beacon period + rxoff = (LMIC.drift * (ostime_t)secs) >> BCN_INTV_exp; + err = (LMIC.lastDriftDiff * (ostime_t)secs) >> BCN_INTV_exp; + } + u1_t rxsyms = MINRX_SYMS; + err += (ostime_t)LMIC.maxDriftDiff * LMIC.missedBcns; + LMIC.rxsyms = MINRX_SYMS + (err / dr2hsym(dr)); + + return (rxsyms-PAMBL_SYMS) * dr2hsym(dr) + rxoff; +} + + +// Setup beacon RX parameters assuming we have an error of ms (aka +/-(ms/2)) +static void calcBcnRxWindowFromMillis (u1_t ms, bit_t ini) { + if( ini ) { + LMIC.drift = 0; + LMIC.maxDriftDiff = 0; + LMIC.missedBcns = 0; + LMIC.bcninfo.flags |= BCN_NODRIFT|BCN_NODDIFF; + } + ostime_t hsym = dr2hsym(DR_BCN); + LMIC.bcnRxsyms = MINRX_SYMS + ms2osticksCeil(ms) / hsym; + LMIC.bcnRxtime = LMIC.bcninfo.txtime + BCN_INTV_osticks - (LMIC.bcnRxsyms-PAMBL_SYMS) * hsym; +} +#endif // !DISABLE_BEACONS + + +#if !defined(DISABLE_PING) +// Setup scheduled RX window (ping/multicast slot) +static void rxschedInit (xref2rxsched_t rxsched) { + os_clearMem(AESkey,16); + os_clearMem(LMIC.frame+8,8); + os_wlsbf4(LMIC.frame, LMIC.bcninfo.time); + os_wlsbf4(LMIC.frame+4, LMIC.devaddr); + os_aes(AES_ENC,LMIC.frame,16); + u1_t intvExp = rxsched->intvExp; + ostime_t off = os_rlsbf2(LMIC.frame) & (0x0FFF >> (7 - intvExp)); // random offset (slot units) + rxsched->rxbase = (LMIC.bcninfo.txtime + + BCN_RESERVE_osticks + + ms2osticks(BCN_SLOT_SPAN_ms * off)); // random offset osticks + rxsched->slot = 0; + rxsched->rxtime = rxsched->rxbase - calcRxWindow(/*secs BCN_RESERVE*/2+(1<dr); + rxsched->rxsyms = LMIC.rxsyms; +} + + +static bit_t rxschedNext (xref2rxsched_t rxsched, ostime_t cando) { + again: + if( rxsched->rxtime - cando >= 0 ) + return 1; + u1_t slot; + if( (slot=rxsched->slot) >= 128 ) + return 0; + u1_t intv = 1<intvExp; + if( (rxsched->slot = (slot += (intv))) >= 128 ) + return 0; + rxsched->rxtime = rxsched->rxbase + + ((BCN_WINDOW_osticks * (ostime_t)slot) >> BCN_INTV_exp) + - calcRxWindow(/*secs BCN_RESERVE*/2+slot+intv,rxsched->dr); + rxsched->rxsyms = LMIC.rxsyms; + goto again; +} +#endif // !DISABLE_PING) + + +static ostime_t rndDelay (u1_t secSpan) { + u2_t r = os_getRndU2(); + ostime_t delay = r; + if( delay > OSTICKS_PER_SEC ) + delay = r % (u2_t)OSTICKS_PER_SEC; + if( secSpan > 0 ) + delay += ((u1_t)r % secSpan) * OSTICKS_PER_SEC; + return delay; +} + + +static void txDelay (ostime_t reftime, u1_t secSpan) { + reftime += rndDelay(secSpan); + if( LMIC.globalDutyRate == 0 || (reftime - LMIC.globalDutyAvail) > 0 ) { + LMIC.globalDutyAvail = reftime; + LMIC.opmode |= OP_RNDTX; + } +} + + +static void setDrJoin (u1_t reason, u1_t dr) { + EV(drChange, INFO, (e_.reason = reason, + e_.deveui = MAIN::CDEV->getEui(), + e_.dr = dr|DR_PAGE, + e_.txpow = LMIC.adrTxPow, + e_.prevdr = LMIC.datarate|DR_PAGE, + e_.prevtxpow = LMIC.adrTxPow)); + LMIC.datarate = dr; + DO_DEVDB(LMIC.datarate,datarate); +} + + +static void setDrTxpow (u1_t reason, u1_t dr, s1_t pow) { + EV(drChange, INFO, (e_.reason = reason, + e_.deveui = MAIN::CDEV->getEui(), + e_.dr = dr|DR_PAGE, + e_.txpow = pow, + e_.prevdr = LMIC.datarate|DR_PAGE, + e_.prevtxpow = LMIC.adrTxPow)); + + if( pow != KEEP_TXPOW ) + LMIC.adrTxPow = pow; + if( LMIC.datarate != dr ) { + LMIC.datarate = dr; + DO_DEVDB(LMIC.datarate,datarate); + LMIC.opmode |= OP_NEXTCHNL; + } +} + + +#if !defined(DISABLE_PING) +void LMIC_stopPingable (void) { + LMIC.opmode &= ~(OP_PINGABLE|OP_PINGINI); +} + + +void LMIC_setPingable (u1_t intvExp) { + // Change setting + LMIC.ping.intvExp = (intvExp & 0x7); + LMIC.opmode |= OP_PINGABLE; + // App may call LMIC_enableTracking() explicitely before + // Otherwise tracking is implicitly enabled here + if( (LMIC.opmode & (OP_TRACK|OP_SCAN)) == 0 && LMIC.bcninfoTries == 0 ) + LMIC_enableTracking(0); +} + +#endif // !DISABLE_PING + +#if defined(CFG_eu868) +// ================================================================================ +// +// BEG: EU868 related stuff +// +enum { NUM_DEFAULT_CHANNELS=3 }; +static CONST_TABLE(u4_t, iniChannelFreq)[6] = { + // Join frequencies and duty cycle limit (0.1%) + EU868_F1|BAND_MILLI, EU868_F2|BAND_MILLI, EU868_F3|BAND_MILLI, + // Default operational frequencies + EU868_F1|BAND_CENTI, EU868_F2|BAND_CENTI, EU868_F3|BAND_CENTI, +}; + +static void initDefaultChannels (bit_t join) { + os_clearMem(&LMIC.channelFreq, sizeof(LMIC.channelFreq)); + os_clearMem(&LMIC.channelDrMap, sizeof(LMIC.channelDrMap)); + os_clearMem(&LMIC.bands, sizeof(LMIC.bands)); + + LMIC.channelMap = 0x07; + u1_t su = join ? 0 : 3; + for( u1_t fu=0; fu<3; fu++,su++ ) { + LMIC.channelFreq[fu] = TABLE_GET_U4(iniChannelFreq, su); + LMIC.channelDrMap[fu] = DR_RANGE_MAP(DR_SF12,DR_SF7); + } + + LMIC.bands[BAND_MILLI].txcap = 1000; // 0.1% + LMIC.bands[BAND_MILLI].txpow = 14; + LMIC.bands[BAND_MILLI].lastchnl = os_getRndU1() % MAX_CHANNELS; + LMIC.bands[BAND_CENTI].txcap = 100; // 1% + LMIC.bands[BAND_CENTI].txpow = 14; + LMIC.bands[BAND_CENTI].lastchnl = os_getRndU1() % MAX_CHANNELS; + LMIC.bands[BAND_DECI ].txcap = 10; // 10% + LMIC.bands[BAND_DECI ].txpow = 27; + LMIC.bands[BAND_DECI ].lastchnl = os_getRndU1() % MAX_CHANNELS; + LMIC.bands[BAND_MILLI].avail = + LMIC.bands[BAND_CENTI].avail = + LMIC.bands[BAND_DECI ].avail = os_getTime(); +} + +bit_t LMIC_setupBand (u1_t bandidx, s1_t txpow, u2_t txcap) { + if( bandidx > BAND_AUX ) return 0; + band_t* b = &LMIC.bands[bandidx]; + b->txpow = txpow; + b->txcap = txcap; + b->avail = os_getTime(); + b->lastchnl = os_getRndU1() % MAX_CHANNELS; + return 1; +} + +bit_t LMIC_setupChannel (u1_t chidx, u4_t freq, u2_t drmap, s1_t band) { + if( chidx >= MAX_CHANNELS ) + return 0; + if( band == -1 ) { + if( freq >= 869400000 && freq <= 869650000 ) + freq |= BAND_DECI; // 10% 27dBm + else if( (freq >= 868000000 && freq <= 868600000) || + (freq >= 869700000 && freq <= 870000000) ) + freq |= BAND_CENTI; // 1% 14dBm + else + freq |= BAND_MILLI; // 0.1% 14dBm + } else { + if( band > BAND_AUX ) return 0; + freq = (freq&~3) | band; + } + LMIC.channelFreq [chidx] = freq; + LMIC.channelDrMap[chidx] = drmap==0 ? DR_RANGE_MAP(DR_SF12,DR_SF7) : drmap; + LMIC.channelMap |= 1<> 8) * 100; + if( freq < EU868_FREQ_MIN || freq > EU868_FREQ_MAX ) + freq = 0; + return freq; +} + +static u1_t mapChannels (u1_t chpage, u2_t chmap) { + // Bad page, disable all channel, enable non-existent + if( chpage != 0 || chmap==0 || (chmap & ~LMIC.channelMap) != 0 ) + return 0; // illegal input + for( u1_t chnl=0; chnltxpow; + band->avail = txbeg + airtime * band->txcap; + if( LMIC.globalDutyRate != 0 ) + LMIC.globalDutyAvail = txbeg + (airtime< 1 + lmic_printf("%lu: Updating info for TX at %lu, airtime will be %lu. Setting available time for band %d to %lu\n", os_getTime(), txbeg, airtime, freq & 0x3, band->avail); + if( LMIC.globalDutyRate != 0 ) + lmic_printf("%lu: Updating global duty avail to %lu\n", os_getTime(), LMIC.globalDutyAvail); + #endif +} + +static ostime_t nextTx (ostime_t now) { + u1_t bmap=0xF; + do { + ostime_t mintime = now + /*8h*/sec2osticks(28800); + u1_t band=0; + for( u1_t bi=0; bi<4; bi++ ) { + if( (bmap & (1< 0 ) { + #if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Considering band %d, which is available at %lu\n", os_getTime(), bi, LMIC.bands[bi].avail); + #endif + mintime = LMIC.bands[band = bi].avail; + } + } + // Find next channel in given band + u1_t chnl = LMIC.bands[band].lastchnl; + for( u1_t ci=0; ci= MAX_CHANNELS ) + chnl -= MAX_CHANNELS; + if( (LMIC.channelMap & (1< 1 + lmic_printf("%lu: No channel found in band %d\n", os_getTime(), band); + #endif + if( (bmap &= ~(1<>LMIC.datarate)); + #if LMIC_DEBUG_LEVEL > 1 + if (failed) + lmic_printf("%lu: Join failed\n", os_getTime()); + else + lmic_printf("%lu: Scheduling next join at %lu\n", os_getTime(), LMIC.txend); + #endif + // 1 - triggers EV_JOIN_FAILED event + return failed; +} +#endif // !DISABLE_JOIN + +// +// END: EU868 related stuff +// +// ================================================================================ +#elif defined(CFG_us915) +// ================================================================================ +// +// BEG: US915 related stuff +// + + +static void initDefaultChannels (void) { + for( u1_t i=0; i<4; i++ ) + LMIC.channelMap[i] = 0xFFFF; + LMIC.channelMap[4] = 0x00FF; +} + +static u4_t convFreq (xref2u1_t ptr) { + u4_t freq = (os_rlsbf4(ptr-1) >> 8) * 100; + if( freq < US915_FREQ_MIN || freq > US915_FREQ_MAX ) + freq = 0; + return freq; +} + +bit_t LMIC_setupChannel (u1_t chidx, u4_t freq, u2_t drmap, s1_t band) { + if( chidx < 72 || chidx >= 72+MAX_XCHANNELS ) + return 0; // channels 0..71 are hardwired + chidx -= 72; + LMIC.xchFreq[chidx] = freq; + LMIC.xchDrMap[chidx] = drmap==0 ? DR_RANGE_MAP(DR_SF10,DR_SF8C) : drmap; + LMIC.channelMap[chidx>>4] |= (1<<(chidx&0xF)); + return 1; +} + +void LMIC_disableChannel (u1_t channel) { + if( channel < 72+MAX_XCHANNELS ) + LMIC.channelMap[channel>>4] &= ~(1<<(channel&0xF)); +} + +void LMIC_enableChannel (u1_t channel) { + if( channel < 72+MAX_XCHANNELS ) + LMIC.channelMap[channel>>4] |= (1<<(channel&0xF)); +} + +void LMIC_enableSubBand (u1_t band) { + ASSERT(band < 8); + u1_t start = band * 8; + u1_t end = start + 8; + for (int channel=start; channel < end; ++channel ) + LMIC_enableChannel(channel); +} +void LMIC_disableSubBand (u1_t band) { + ASSERT(band < 8); + u1_t start = band * 8; + u1_t end = start + 8; + for (int channel=start; channel < end; ++channel ) + LMIC_disableChannel(channel); +} +void LMIC_selectSubBand (u1_t band) { + ASSERT(band < 8); + for (int b=0; b<8; ++b) { + if (band==b) + LMIC_enableSubBand(b); + else + LMIC_disableSubBand(b); + } +} + +static u1_t mapChannels (u1_t chpage, u2_t chmap) { + if( chpage == MCMD_LADR_CHP_125ON || chpage == MCMD_LADR_CHP_125OFF ) { + u2_t en125 = chpage == MCMD_LADR_CHP_125ON ? 0xFFFF : 0x0000; + for( u1_t u=0; u<4; u++ ) + LMIC.channelMap[u] = en125; + LMIC.channelMap[64/16] = chmap; + } else { + if( chpage >= (72+MAX_XCHANNELS+15)/16 ) + return 0; + LMIC.channelMap[chpage] = chmap; + } + return 1; +} + +static void updateTx (ostime_t txbeg) { + u1_t chnl = LMIC.txChnl; + if( chnl < 64 ) { + LMIC.freq = US915_125kHz_UPFBASE + chnl*US915_125kHz_UPFSTEP; + LMIC.txpow = 30; + return; + } + LMIC.txpow = 26; + if( chnl < 64+8 ) { + LMIC.freq = US915_500kHz_UPFBASE + (chnl-64)*US915_500kHz_UPFSTEP; + } else { + ASSERT(chnl < 64+8+MAX_XCHANNELS); + LMIC.freq = LMIC.xchFreq[chnl-72]; + } + + // Update global duty cycle stats + if( LMIC.globalDutyRate != 0 ) { + ostime_t airtime = calcAirTime(LMIC.rps, LMIC.dataLen); + LMIC.globalDutyAvail = txbeg + (airtime<= DR_SF8C ) { // 500kHz + u1_t map = LMIC.channelMap[64/16]&0xFF; + for( u1_t i=0; i<8; i++ ) { + if( (map & (1<<(++LMIC.chRnd & 7))) != 0 ) { + LMIC.txChnl = 64 + (LMIC.chRnd & 7); + return; + } + } + } else { // 125kHz + for( u1_t i=0; i<64; i++ ) { + u1_t chnl = ++LMIC.chRnd & 0x3F; + if( (LMIC.channelMap[(chnl >> 4)] & (1<<(chnl & 0xF))) != 0 ) { + LMIC.txChnl = chnl; + return; + } + } + } + // No feasible channel found! Keep old one. +} + +#if !defined(DISABLE_BEACONS) +static void setBcnRxParams (void) { + LMIC.dataLen = 0; + LMIC.freq = US915_500kHz_DNFBASE + LMIC.bcnChnl * US915_500kHz_DNFSTEP; + LMIC.rps = setIh(setNocrc(dndr2rps((dr_t)DR_BCN),1),LEN_BCN); +} +#endif // !DISABLE_BEACONS + +#define setRx1Params() { \ + LMIC.freq = US915_500kHz_DNFBASE + (LMIC.txChnl & 0x7) * US915_500kHz_DNFSTEP; \ + if( /* TX datarate */LMIC.dndr < DR_SF8C ) \ + LMIC.dndr += DR_SF10CR - DR_SF10; \ + else if( LMIC.dndr == DR_SF8C ) \ + LMIC.dndr = DR_SF7CR; \ + LMIC.rps = dndr2rps(LMIC.dndr); \ +} + +#if !defined(DISABLE_JOIN) +static void initJoinLoop (void) { + LMIC.chRnd = 0; + LMIC.txChnl = 0; + LMIC.adrTxPow = 20; + ASSERT((LMIC.opmode & OP_NEXTCHNL)==0); + LMIC.txend = os_getTime(); + setDrJoin(DRCHG_SET, DR_SF7); +} + +static ostime_t nextJoinState (void) { + // Try the following: + // SF7/8/9/10 on a random channel 0..63 + // SF8C on a random channel 64..71 + // + u1_t failed = 0; + if( LMIC.datarate != DR_SF8C ) { + LMIC.txChnl = 64+(LMIC.txChnl&7); + setDrJoin(DRCHG_SET, DR_SF8C); + } else { + LMIC.txChnl = os_getRndU1() & 0x3F; + s1_t dr = DR_SF7 - ++LMIC.txCnt; + if( dr < DR_SF10 ) { + dr = DR_SF10; + failed = 1; // All DR exhausted - signal failed + } + setDrJoin(DRCHG_SET, dr); + } + LMIC.opmode &= ~OP_NEXTCHNL; + LMIC.txend = os_getTime() + + (isTESTMODE() + // Avoid collision with JOIN ACCEPT being sent by GW (but we missed it - GW is still busy) + ? DNW2_SAFETY_ZONE + // Otherwise: randomize join (street lamp case): + // SF10:16, SF9=8,..SF8C:1secs + : rndDelay(16>>LMIC.datarate)); + // 1 - triggers EV_JOIN_FAILED event + return failed; +} +#endif // !DISABLE_JOIN + +// +// END: US915 related stuff +// +// ================================================================================ +#else +#error Unsupported frequency band! +#endif + + +static void runEngineUpdate (xref2osjob_t osjob) { + engineUpdate(); +} + + +static void reportEvent (ev_t ev) { + EV(devCond, INFO, (e_.reason = EV::devCond_t::LMIC_EV, + e_.eui = MAIN::CDEV->getEui(), + e_.info = ev)); + ON_LMIC_EVENT(ev); + engineUpdate(); +} + + +static void runReset (xref2osjob_t osjob) { + // Disable session + LMIC_reset(); +#if !defined(DISABLE_JOIN) + LMIC_startJoining(); +#endif // !DISABLE_JOIN + reportEvent(EV_RESET); +} + +static void stateJustJoined (void) { + LMIC.seqnoDn = LMIC.seqnoUp = 0; + LMIC.rejoinCnt = 0; + LMIC.dnConf = LMIC.adrChanged = LMIC.ladrAns = LMIC.devsAns = 0; +#if !defined(DISABLE_MCMD_SNCH_REQ) + LMIC.snchAns = 0; +#endif +#if !defined(DISABLE_MCMD_DN2P_SET) + LMIC.dn2Ans = 0; +#endif + LMIC.moreData = 0; +#if !defined(DISABLE_MCMD_DCAP_REQ) + LMIC.dutyCapAns = 0; +#endif +#if !defined(DISABLE_MCMD_PING_SET) && !defined(DISABLE_PING) + LMIC.pingSetAns = 0; +#endif + LMIC.upRepeat = 0; + LMIC.adrAckReq = LINK_CHECK_INIT; + LMIC.dn2Dr = DR_DNW2; + LMIC.dn2Freq = FREQ_DNW2; +#if !defined(DISABLE_BEACONS) + LMIC.bcnChnl = CHNL_BCN; +#endif +#if !defined(DISABLE_PING) + LMIC.ping.freq = FREQ_PING; + LMIC.ping.dr = DR_PING; +#endif +} + + +// ================================================================================ +// Decoding frames + + +#if !defined(DISABLE_BEACONS) +// Decode beacon - do not overwrite bcninfo unless we have a match! +static int decodeBeacon (void) { + ASSERT(LMIC.dataLen == LEN_BCN); // implicit header RX guarantees this + xref2u1_t d = LMIC.frame; + if( +#if CFG_eu868 + d[OFF_BCN_CRC1] != (u1_t)os_crc16(d,OFF_BCN_CRC1) +#elif CFG_us915 + os_rlsbf2(&d[OFF_BCN_CRC1]) != os_crc16(d,OFF_BCN_CRC1) +#endif + ) + return 0; // first (common) part fails CRC check + // First set of fields is ok + u4_t bcnnetid = os_rlsbf4(&d[OFF_BCN_NETID]) & 0xFFFFFF; + if( bcnnetid != LMIC.netid ) + return -1; // not the beacon we're looking for + + LMIC.bcninfo.flags &= ~(BCN_PARTIAL|BCN_FULL); + // Match - update bcninfo structure + LMIC.bcninfo.snr = LMIC.snr; + LMIC.bcninfo.rssi = LMIC.rssi; + LMIC.bcninfo.txtime = LMIC.rxtime - AIRTIME_BCN_osticks; + LMIC.bcninfo.time = os_rlsbf4(&d[OFF_BCN_TIME]); + LMIC.bcninfo.flags |= BCN_PARTIAL; + + // Check 2nd set + if( os_rlsbf2(&d[OFF_BCN_CRC2]) != os_crc16(d,OFF_BCN_CRC2) ) + return 1; + // Second set of fields is ok + LMIC.bcninfo.lat = (s4_t)os_rlsbf4(&d[OFF_BCN_LAT-1]) >> 8; // read as signed 24-bit + LMIC.bcninfo.lon = (s4_t)os_rlsbf4(&d[OFF_BCN_LON-1]) >> 8; // ditto + LMIC.bcninfo.info = d[OFF_BCN_INFO]; + LMIC.bcninfo.flags |= BCN_FULL; + return 2; +} +#endif // !DISABLE_BEACONS + + +static bit_t decodeFrame (void) { + xref2u1_t d = LMIC.frame; + u1_t hdr = d[0]; + u1_t ftype = hdr & HDR_FTYPE; + int dlen = LMIC.dataLen; + const char *window = (LMIC.txrxFlags & TXRX_DNW1) ? "RX1" : ((LMIC.txrxFlags & TXRX_DNW2) ? "RX2" : "Other"); + if( dlen < OFF_DAT_OPTS+4 || + (hdr & HDR_MAJOR) != HDR_MAJOR_V1 || + (ftype != HDR_FTYPE_DADN && ftype != HDR_FTYPE_DCDN) ) { + // Basic sanity checks failed + EV(specCond, WARN, (e_.reason = EV::specCond_t::UNEXPECTED_FRAME, + e_.eui = MAIN::CDEV->getEui(), + e_.info = dlen < 4 ? 0 : os_rlsbf4(&d[dlen-4]), + e_.info2 = hdr + (dlen<<8))); + norx: +#if LMIC_DEBUG_LEVEL > 0 + lmic_printf("%lu: Invalid downlink, window=%s\n", os_getTime(), window); +#endif + LMIC.dataLen = 0; + return 0; + } + // Validate exact frame length + // Note: device address was already read+evaluated in order to arrive here. + int fct = d[OFF_DAT_FCT]; + u4_t addr = os_rlsbf4(&d[OFF_DAT_ADDR]); + u4_t seqno = os_rlsbf2(&d[OFF_DAT_SEQNO]); + int olen = fct & FCT_OPTLEN; + int ackup = (fct & FCT_ACK) != 0 ? 1 : 0; // ACK last up frame + int poff = OFF_DAT_OPTS+olen; + int pend = dlen-4; // MIC + + if( addr != LMIC.devaddr ) { + EV(specCond, WARN, (e_.reason = EV::specCond_t::ALIEN_ADDRESS, + e_.eui = MAIN::CDEV->getEui(), + e_.info = addr, + e_.info2 = LMIC.devaddr)); + goto norx; + } + if( poff > pend ) { + EV(specCond, ERR, (e_.reason = EV::specCond_t::CORRUPTED_FRAME, + e_.eui = MAIN::CDEV->getEui(), + e_.info = 0x1000000 + (poff-pend) + (fct<<8) + (dlen<<16))); + goto norx; + } + + int port = -1; + int replayConf = 0; + + if( pend > poff ) + port = d[poff++]; + + seqno = LMIC.seqnoDn + (u2_t)(seqno - LMIC.seqnoDn); + + if( !aes_verifyMic(LMIC.nwkKey, LMIC.devaddr, seqno, /*dn*/1, d, pend) ) { + EV(spe3Cond, ERR, (e_.reason = EV::spe3Cond_t::CORRUPTED_MIC, + e_.eui1 = MAIN::CDEV->getEui(), + e_.info1 = Base::lsbf4(&d[pend]), + e_.info2 = seqno, + e_.info3 = LMIC.devaddr)); + goto norx; + } + if( seqno < LMIC.seqnoDn ) { + if( (s4_t)seqno > (s4_t)LMIC.seqnoDn ) { + EV(specCond, INFO, (e_.reason = EV::specCond_t::DNSEQNO_ROLL_OVER, + e_.eui = MAIN::CDEV->getEui(), + e_.info = LMIC.seqnoDn, + e_.info2 = seqno)); + goto norx; + } + if( seqno != LMIC.seqnoDn-1 || !LMIC.dnConf || ftype != HDR_FTYPE_DCDN ) { + EV(specCond, INFO, (e_.reason = EV::specCond_t::DNSEQNO_OBSOLETE, + e_.eui = MAIN::CDEV->getEui(), + e_.info = LMIC.seqnoDn, + e_.info2 = seqno)); + goto norx; + } + // Replay of previous sequence number allowed only if + // previous frame and repeated both requested confirmation + replayConf = 1; + } + else { + if( seqno > LMIC.seqnoDn ) { + EV(specCond, INFO, (e_.reason = EV::specCond_t::DNSEQNO_SKIP, + e_.eui = MAIN::CDEV->getEui(), + e_.info = LMIC.seqnoDn, + e_.info2 = seqno)); + } + LMIC.seqnoDn = seqno+1; // next number to be expected + DO_DEVDB(LMIC.seqnoDn,seqnoDn); + // DN frame requested confirmation - provide ACK once with next UP frame + LMIC.dnConf = (ftype == HDR_FTYPE_DCDN ? FCT_ACK : 0); + } + + if( LMIC.dnConf || (fct & FCT_MORE) ) + LMIC.opmode |= OP_POLL; + + // We heard from network + LMIC.adrChanged = LMIC.rejoinCnt = 0; + if( LMIC.adrAckReq != LINK_CHECK_OFF ) + LMIC.adrAckReq = LINK_CHECK_INIT; + + // Process OPTS + int m = LMIC.rssi - RSSI_OFF - getSensitivity(LMIC.rps); + LMIC.margin = m < 0 ? 0 : m > 254 ? 254 : m; + + xref2u1_t opts = &d[OFF_DAT_OPTS]; + int oidx = 0; + while( oidx < olen ) { + switch( opts[oidx] ) { + case MCMD_LCHK_ANS: { + //int gwmargin = opts[oidx+1]; + //int ngws = opts[oidx+2]; + oidx += 3; + continue; + } + case MCMD_LADR_REQ: { + u1_t p1 = opts[oidx+1]; // txpow + DR + u2_t chmap = os_rlsbf2(&opts[oidx+2]);// list of enabled channels + u1_t chpage = opts[oidx+4] & MCMD_LADR_CHPAGE_MASK; // channel page + u1_t uprpt = opts[oidx+4] & MCMD_LADR_REPEAT_MASK; // up repeat count + oidx += 5; + + LMIC.ladrAns = 0x80 | // Include an answer into next frame up + MCMD_LADR_ANS_POWACK | MCMD_LADR_ANS_CHACK | MCMD_LADR_ANS_DRACK; + if( !mapChannels(chpage, chmap) ) + LMIC.ladrAns &= ~MCMD_LADR_ANS_CHACK; + dr_t dr = (dr_t)(p1>>MCMD_LADR_DR_SHIFT); + if( !validDR(dr) ) { + LMIC.ladrAns &= ~MCMD_LADR_ANS_DRACK; + EV(specCond, ERR, (e_.reason = EV::specCond_t::BAD_MAC_CMD, + e_.eui = MAIN::CDEV->getEui(), + e_.info = Base::lsbf4(&d[pend]), + e_.info2 = Base::msbf4(&opts[oidx-4]))); + } + if( (LMIC.ladrAns & 0x7F) == (MCMD_LADR_ANS_POWACK | MCMD_LADR_ANS_CHACK | MCMD_LADR_ANS_DRACK) ) { + // Nothing went wrong - use settings + LMIC.upRepeat = uprpt; + setDrTxpow(DRCHG_NWKCMD, dr, pow2dBm(p1)); + } + LMIC.adrChanged = 1; // Trigger an ACK to NWK + continue; + } + case MCMD_DEVS_REQ: { + LMIC.devsAns = 1; + oidx += 1; + continue; + } + case MCMD_DN2P_SET: { +#if !defined(DISABLE_MCMD_DN2P_SET) + dr_t dr = (dr_t)(opts[oidx+1] & 0x0F); + u4_t freq = convFreq(&opts[oidx+2]); + LMIC.dn2Ans = 0x80; // answer pending + if( validDR(dr) ) + LMIC.dn2Ans |= MCMD_DN2P_ANS_DRACK; + if( freq != 0 ) + LMIC.dn2Ans |= MCMD_DN2P_ANS_CHACK; + if( LMIC.dn2Ans == (0x80|MCMD_DN2P_ANS_DRACK|MCMD_DN2P_ANS_CHACK) ) { + LMIC.dn2Dr = dr; + LMIC.dn2Freq = freq; + DO_DEVDB(LMIC.dn2Dr,dn2Dr); + DO_DEVDB(LMIC.dn2Freq,dn2Freq); + } +#endif // !DISABLE_MCMD_DN2P_SET + oidx += 5; + continue; + } + case MCMD_DCAP_REQ: { +#if !defined(DISABLE_MCMD_DCAP_REQ) + u1_t cap = opts[oidx+1]; + // A value cap=0xFF means device is OFF unless enabled again manually. + if( cap==0xFF ) + LMIC.opmode |= OP_SHUTDOWN; // stop any sending + LMIC.globalDutyRate = cap & 0xF; + LMIC.globalDutyAvail = os_getTime(); + DO_DEVDB(cap,dutyCap); + LMIC.dutyCapAns = 1; + oidx += 2; +#endif // !DISABLE_MCMD_DCAP_REQ + continue; + } + case MCMD_SNCH_REQ: { +#if !defined(DISABLE_MCMD_SNCH_REQ) + u1_t chidx = opts[oidx+1]; // channel + u4_t freq = convFreq(&opts[oidx+2]); // freq + u1_t drs = opts[oidx+5]; // datarate span + LMIC.snchAns = 0x80; + if( freq != 0 && LMIC_setupChannel(chidx, freq, DR_RANGE_MAP(drs&0xF,drs>>4), -1) ) + LMIC.snchAns |= MCMD_SNCH_ANS_DRACK|MCMD_SNCH_ANS_FQACK; +#endif // !DISABLE_MCMD_SNCH_REQ + oidx += 6; + continue; + } + case MCMD_PING_SET: { +#if !defined(DISABLE_MCMD_PING_SET) && !defined(DISABLE_PING) + u4_t freq = convFreq(&opts[oidx+1]); + u1_t flags = 0x80; + if( freq != 0 ) { + flags |= MCMD_PING_ANS_FQACK; + LMIC.ping.freq = freq; + DO_DEVDB(LMIC.ping.intvExp, pingIntvExp); + DO_DEVDB(LMIC.ping.freq, pingFreq); + DO_DEVDB(LMIC.ping.dr, pingDr); + } + LMIC.pingSetAns = flags; +#endif // !DISABLE_MCMD_PING_SET && !DISABLE_PING + oidx += 4; + continue; + } + case MCMD_BCNI_ANS: { +#if !defined(DISABLE_MCMD_BCNI_ANS) && !defined(DISABLE_BEACONS) + // Ignore if tracking already enabled + if( (LMIC.opmode & OP_TRACK) == 0 ) { + LMIC.bcnChnl = opts[oidx+3]; + // Enable tracking - bcninfoTries + LMIC.opmode |= OP_TRACK; + // Cleared later in txComplete handling - triggers EV_BEACON_FOUND + ASSERT(LMIC.bcninfoTries!=0); + // Setup RX parameters + LMIC.bcninfo.txtime = (LMIC.rxtime + + ms2osticks(os_rlsbf2(&opts[oidx+1]) * MCMD_BCNI_TUNIT) + + ms2osticksCeil(MCMD_BCNI_TUNIT/2) + - BCN_INTV_osticks); + LMIC.bcninfo.flags = 0; // txtime above cannot be used as reference (BCN_PARTIAL|BCN_FULL cleared) + calcBcnRxWindowFromMillis(MCMD_BCNI_TUNIT,1); // error of +/-N ms + + EV(lostFrame, INFO, (e_.reason = EV::lostFrame_t::MCMD_BCNI_ANS, + e_.eui = MAIN::CDEV->getEui(), + e_.lostmic = Base::lsbf4(&d[pend]), + e_.info = (LMIC.missedBcns | + (osticks2us(LMIC.bcninfo.txtime + BCN_INTV_osticks + - LMIC.bcnRxtime) << 8)), + e_.time = MAIN::CDEV->ostime2ustime(LMIC.bcninfo.txtime + BCN_INTV_osticks))); + } +#endif // !DISABLE_MCMD_BCNI_ANS && !DISABLE_BEACONS + oidx += 4; + continue; + } + } + EV(specCond, ERR, (e_.reason = EV::specCond_t::BAD_MAC_CMD, + e_.eui = MAIN::CDEV->getEui(), + e_.info = Base::lsbf4(&d[pend]), + e_.info2 = Base::msbf4(&opts[oidx]))); + break; + } + if( oidx != olen ) { + EV(specCond, ERR, (e_.reason = EV::specCond_t::CORRUPTED_FRAME, + e_.eui = MAIN::CDEV->getEui(), + e_.info = 0x1000000 + (oidx) + (olen<<8))); + } + + if( !replayConf ) { + // Handle payload only if not a replay + // Decrypt payload - if any + if( port >= 0 && pend-poff > 0 ) + aes_cipher(port <= 0 ? LMIC.nwkKey : LMIC.artKey, LMIC.devaddr, seqno, /*dn*/1, d+poff, pend-poff); + + EV(dfinfo, DEBUG, (e_.deveui = MAIN::CDEV->getEui(), + e_.devaddr = LMIC.devaddr, + e_.seqno = seqno, + e_.flags = (port < 0 ? EV::dfinfo_t::NOPORT : 0) | EV::dfinfo_t::DN, + e_.mic = Base::lsbf4(&d[pend]), + e_.hdr = d[LORA::OFF_DAT_HDR], + e_.fct = d[LORA::OFF_DAT_FCT], + e_.port = port, + e_.plen = dlen, + e_.opts.length = olen, + memcpy(&e_.opts[0], opts, olen))); + } else { + EV(specCond, INFO, (e_.reason = EV::specCond_t::DNSEQNO_REPLAY, + e_.eui = MAIN::CDEV->getEui(), + e_.info = Base::lsbf4(&d[pend]), + e_.info2 = seqno)); + } + + if( // NWK acks but we don't have a frame pending + (ackup && LMIC.txCnt == 0) || + // We sent up confirmed and we got a response in DNW1/DNW2 + // BUT it did not carry an ACK - this should never happen + // Do not resend and assume frame was not ACKed. + (!ackup && LMIC.txCnt != 0) ) { + EV(specCond, ERR, (e_.reason = EV::specCond_t::SPURIOUS_ACK, + e_.eui = MAIN::CDEV->getEui(), + e_.info = seqno, + e_.info2 = ackup)); + } + + if( LMIC.txCnt != 0 ) // we requested an ACK + LMIC.txrxFlags |= ackup ? TXRX_ACK : TXRX_NACK; + + if( port < 0 ) { + LMIC.txrxFlags |= TXRX_NOPORT; + LMIC.dataBeg = poff; + LMIC.dataLen = 0; + } else { + LMIC.txrxFlags |= TXRX_PORT; + LMIC.dataBeg = poff; + LMIC.dataLen = pend-poff; + } +#if LMIC_DEBUG_LEVEL > 0 + lmic_printf("%lu: Received downlink, window=%s, port=%d, ack=%d\n", os_getTime(), window, port, ackup); +#endif + return 1; +} + + +// ================================================================================ +// TX/RX transaction support + + +static void setupRx2 (void) { + LMIC.txrxFlags = TXRX_DNW2; + LMIC.rps = dndr2rps(LMIC.dn2Dr); + LMIC.freq = LMIC.dn2Freq; + LMIC.dataLen = 0; + os_radio(RADIO_RX); +} + + +static void schedRx12 (ostime_t delay, osjobcb_t func, u1_t dr) { + ostime_t hsym = dr2hsym(dr); + + LMIC.rxsyms = MINRX_SYMS; + + // If a clock error is specified, compensate for it by extending the + // receive window + if (LMIC.clockError != 0) { + // Calculate how much the clock will drift maximally after delay has + // passed. This indicates the amount of time we can be early + // _or_ late. + ostime_t drift = (int64_t)delay * LMIC.clockError / MAX_CLOCK_ERROR; + + // Increase the receive window by twice the maximum drift (to + // compensate for a slow or a fast clock). + // decrease the rxtime to compensate for. Note that hsym is a + // *half* symbol time, so the factor 2 is hidden. First check if + // this would overflow (which can happen if the drift is very + // high, or the symbol time is low at high datarates). + if ((255 - LMIC.rxsyms) * hsym < drift) + LMIC.rxsyms = 255; + else + LMIC.rxsyms += drift / hsym; + + } + + // Center the receive window on the center of the expected preamble + // (again note that hsym is half a sumbol time, so no /2 needed) + LMIC.rxtime = LMIC.txend + delay + PAMBL_SYMS * hsym - LMIC.rxsyms * hsym; + + os_setTimedCallback(&LMIC.osjob, LMIC.rxtime - RX_RAMPUP, func); +} + +static void setupRx1 (osjobcb_t func) { + LMIC.txrxFlags = TXRX_DNW1; + // Turn LMIC.rps from TX over to RX + LMIC.rps = setNocrc(LMIC.rps,1); + LMIC.dataLen = 0; + LMIC.osjob.func = func; + os_radio(RADIO_RX); +} + + +// Called by HAL once TX complete and delivers exact end of TX time stamp in LMIC.rxtime +static void txDone (ostime_t delay, osjobcb_t func) { +#if !defined(DISABLE_PING) + if( (LMIC.opmode & (OP_TRACK|OP_PINGABLE|OP_PINGINI)) == (OP_TRACK|OP_PINGABLE) ) { + rxschedInit(&LMIC.ping); // note: reuses LMIC.frame buffer! + LMIC.opmode |= OP_PINGINI; + } +#endif // !DISABLE_PING + + // Change RX frequency / rps (US only) before we increment txChnl + setRx1Params(); + // LMIC.rxsyms carries the TX datarate (can be != LMIC.datarate [confirm retries etc.]) + // Setup receive - LMIC.rxtime is preloaded with 1.5 symbols offset to tune + // into the middle of the 8 symbols preamble. +#if defined(CFG_eu868) + if( /* TX datarate */LMIC.rxsyms == DR_FSK ) { + LMIC.rxtime = LMIC.txend + delay - PRERX_FSK*us2osticksRound(160); + LMIC.rxsyms = RXLEN_FSK; + os_setTimedCallback(&LMIC.osjob, LMIC.rxtime - RX_RAMPUP, func); + } + else +#endif + { + schedRx12(delay, func, LMIC.dndr); + } +} + + +// ======================================== Join frames + + +#if !defined(DISABLE_JOIN) +static void onJoinFailed (xref2osjob_t osjob) { + // Notify app - must call LMIC_reset() to stop joining + // otherwise join procedure continues. + reportEvent(EV_JOIN_FAILED); +} + + +static bit_t processJoinAccept (void) { + ASSERT(LMIC.txrxFlags != TXRX_DNW1 || LMIC.dataLen != 0); + ASSERT((LMIC.opmode & OP_TXRXPEND)!=0); + + if( LMIC.dataLen == 0 ) { + nojoinframe: + if( (LMIC.opmode & OP_JOINING) == 0 ) { + ASSERT((LMIC.opmode & OP_REJOIN) != 0); + // REJOIN attempt for roaming + LMIC.opmode &= ~(OP_REJOIN|OP_TXRXPEND); + if( LMIC.rejoinCnt < 10 ) + LMIC.rejoinCnt++; + reportEvent(EV_REJOIN_FAILED); + return 1; + } + LMIC.opmode &= ~OP_TXRXPEND; + ostime_t delay = nextJoinState(); + EV(devCond, DEBUG, (e_.reason = EV::devCond_t::NO_JACC, + e_.eui = MAIN::CDEV->getEui(), + e_.info = LMIC.datarate|DR_PAGE, + e_.info2 = osticks2ms(delay))); + // Build next JOIN REQUEST with next engineUpdate call + // Optionally, report join failed. + // Both after a random/chosen amount of ticks. + os_setTimedCallback(&LMIC.osjob, os_getTime()+delay, + (delay&1) != 0 + ? FUNC_ADDR(onJoinFailed) // one JOIN iteration done and failed + : FUNC_ADDR(runEngineUpdate)); // next step to be delayed + return 1; + } + u1_t hdr = LMIC.frame[0]; + u1_t dlen = LMIC.dataLen; + u4_t mic = os_rlsbf4(&LMIC.frame[dlen-4]); // safe before modified by encrypt! + if( (dlen != LEN_JA && dlen != LEN_JAEXT) + || (hdr & (HDR_FTYPE|HDR_MAJOR)) != (HDR_FTYPE_JACC|HDR_MAJOR_V1) ) { + EV(specCond, ERR, (e_.reason = EV::specCond_t::UNEXPECTED_FRAME, + e_.eui = MAIN::CDEV->getEui(), + e_.info = dlen < 4 ? 0 : mic, + e_.info2 = hdr + (dlen<<8))); + badframe: + if( (LMIC.txrxFlags & TXRX_DNW1) != 0 ) + return 0; + goto nojoinframe; + } + aes_encrypt(LMIC.frame+1, dlen-1); + if( !aes_verifyMic0(LMIC.frame, dlen-4) ) { + EV(specCond, ERR, (e_.reason = EV::specCond_t::JOIN_BAD_MIC, + e_.info = mic)); + goto badframe; + } + + u4_t addr = os_rlsbf4(LMIC.frame+OFF_JA_DEVADDR); + LMIC.devaddr = addr; + LMIC.netid = os_rlsbf4(&LMIC.frame[OFF_JA_NETID]) & 0xFFFFFF; + +#if defined(CFG_eu868) + initDefaultChannels(0); +#endif + if( dlen > LEN_JA ) { +#if defined(CFG_us915) + goto badframe; +#endif + dlen = OFF_CFLIST; + for( u1_t chidx=3; chidx<8; chidx++, dlen+=3 ) { + u4_t freq = convFreq(&LMIC.frame[dlen]); + if( freq ) { + LMIC_setupChannel(chidx, freq, 0, -1); +#if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Setup channel, idx=%d, freq=%lu\n", os_getTime(), chidx, (unsigned long)freq); +#endif + } + } + } + + // already incremented when JOIN REQ got sent off + aes_sessKeys(LMIC.devNonce-1, &LMIC.frame[OFF_JA_ARTNONCE], LMIC.nwkKey, LMIC.artKey); + DO_DEVDB(LMIC.netid, netid); + DO_DEVDB(LMIC.devaddr, devaddr); + DO_DEVDB(LMIC.nwkKey, nwkkey); + DO_DEVDB(LMIC.artKey, artkey); + + EV(joininfo, INFO, (e_.arteui = MAIN::CDEV->getArtEui(), + e_.deveui = MAIN::CDEV->getEui(), + e_.devaddr = LMIC.devaddr, + e_.oldaddr = oldaddr, + e_.nonce = LMIC.devNonce-1, + e_.mic = mic, + e_.reason = ((LMIC.opmode & OP_REJOIN) != 0 + ? EV::joininfo_t::REJOIN_ACCEPT + : EV::joininfo_t::ACCEPT))); + + ASSERT((LMIC.opmode & (OP_JOINING|OP_REJOIN))!=0); + if( (LMIC.opmode & OP_REJOIN) != 0 ) { + // Lower DR every try below current UP DR + LMIC.datarate = lowerDR(LMIC.datarate, LMIC.rejoinCnt); + } + LMIC.opmode &= ~(OP_JOINING|OP_TRACK|OP_REJOIN|OP_TXRXPEND|OP_PINGINI) | OP_NEXTCHNL; + LMIC.txCnt = 0; + stateJustJoined(); + LMIC.dn2Dr = LMIC.frame[OFF_JA_DLSET] & 0x0F; + LMIC.rxDelay = LMIC.frame[OFF_JA_RXDLY]; + if (LMIC.rxDelay == 0) LMIC.rxDelay = 1; + reportEvent(EV_JOINED); + return 1; +} + + +static void processRx2Jacc (xref2osjob_t osjob) { + if( LMIC.dataLen == 0 ) + LMIC.txrxFlags = 0; // nothing in 1st/2nd DN slot + processJoinAccept(); +} + + +static void setupRx2Jacc (xref2osjob_t osjob) { + LMIC.osjob.func = FUNC_ADDR(processRx2Jacc); + setupRx2(); +} + + +static void processRx1Jacc (xref2osjob_t osjob) { + if( LMIC.dataLen == 0 || !processJoinAccept() ) + schedRx12(DELAY_JACC2_osticks, FUNC_ADDR(setupRx2Jacc), LMIC.dn2Dr); +} + + +static void setupRx1Jacc (xref2osjob_t osjob) { + setupRx1(FUNC_ADDR(processRx1Jacc)); +} + + +static void jreqDone (xref2osjob_t osjob) { + txDone(DELAY_JACC1_osticks, FUNC_ADDR(setupRx1Jacc)); +} + +#endif // !DISABLE_JOIN + +// ======================================== Data frames + +// Fwd decl. +static bit_t processDnData(void); + +static void processRx2DnData (xref2osjob_t osjob) { + if( LMIC.dataLen == 0 ) { + LMIC.txrxFlags = 0; // nothing in 1st/2nd DN slot + // It could be that the gateway *is* sending a reply, but we + // just didn't pick it up. To avoid TX'ing again while the + // gateay is not listening anyway, delay the next transmission + // until DNW2_SAFETY_ZONE from now, and add up to 2 seconds of + // extra randomization. + txDelay(os_getTime() + DNW2_SAFETY_ZONE, 2); + } + processDnData(); +} + + +static void setupRx2DnData (xref2osjob_t osjob) { + LMIC.osjob.func = FUNC_ADDR(processRx2DnData); + setupRx2(); +} + + +static void processRx1DnData (xref2osjob_t osjob) { + if( LMIC.dataLen == 0 || !processDnData() ) + schedRx12(sec2osticks(LMIC.rxDelay +(int)DELAY_EXTDNW2), FUNC_ADDR(setupRx2DnData), LMIC.dn2Dr); +} + + +static void setupRx1DnData (xref2osjob_t osjob) { + setupRx1(FUNC_ADDR(processRx1DnData)); +} + + +static void updataDone (xref2osjob_t osjob) { + txDone(sec2osticks(LMIC.rxDelay), FUNC_ADDR(setupRx1DnData)); +} + +// ======================================== + + +static void buildDataFrame (void) { + bit_t txdata = ((LMIC.opmode & (OP_TXDATA|OP_POLL)) != OP_POLL); + u1_t dlen = txdata ? LMIC.pendTxLen : 0; + + // Piggyback MAC options + // Prioritize by importance + int end = OFF_DAT_OPTS; +#if !defined(DISABLE_PING) + if( (LMIC.opmode & (OP_TRACK|OP_PINGABLE)) == (OP_TRACK|OP_PINGABLE) ) { + // Indicate pingability in every UP frame + LMIC.frame[end] = MCMD_PING_IND; + LMIC.frame[end+1] = LMIC.ping.dr | (LMIC.ping.intvExp<<4); + end += 2; + } +#endif // !DISABLE_PING +#if !defined(DISABLE_MCMD_DCAP_REQ) + if( LMIC.dutyCapAns ) { + LMIC.frame[end] = MCMD_DCAP_ANS; + end += 1; + LMIC.dutyCapAns = 0; + } +#endif // !DISABLE_MCMD_DCAP_REQ +#if !defined(DISABLE_MCMD_DN2P_SET) + if( LMIC.dn2Ans ) { + LMIC.frame[end+0] = MCMD_DN2P_ANS; + LMIC.frame[end+1] = LMIC.dn2Ans & ~MCMD_DN2P_ANS_RFU; + end += 2; + LMIC.dn2Ans = 0; + } +#endif // !DISABLE_MCMD_DN2P_SET + if( LMIC.devsAns ) { // answer to device status + LMIC.frame[end+0] = MCMD_DEVS_ANS; + LMIC.frame[end+1] = os_getBattLevel(); + LMIC.frame[end+2] = LMIC.margin; + end += 3; + LMIC.devsAns = 0; + } + if( LMIC.ladrAns ) { // answer to ADR change + LMIC.frame[end+0] = MCMD_LADR_ANS; + LMIC.frame[end+1] = LMIC.ladrAns & ~MCMD_LADR_ANS_RFU; + end += 2; + LMIC.ladrAns = 0; + } +#if !defined(DISABLE_BEACONS) + if( LMIC.bcninfoTries > 0 ) { + LMIC.frame[end] = MCMD_BCNI_REQ; + end += 1; + } +#endif // !DISABLE_BEACONS + if( LMIC.adrChanged ) { + if( LMIC.adrAckReq < 0 ) + LMIC.adrAckReq = 0; + LMIC.adrChanged = 0; + } +#if !defined(DISABLE_MCMD_PING_SET) && !defined(DISABLE_PING) + if( LMIC.pingSetAns != 0 ) { + LMIC.frame[end+0] = MCMD_PING_ANS; + LMIC.frame[end+1] = LMIC.pingSetAns & ~MCMD_PING_ANS_RFU; + end += 2; + LMIC.pingSetAns = 0; + } +#endif // !DISABLE_MCMD_PING_SET && !DISABLE_PING +#if !defined(DISABLE_MCMD_SNCH_REQ) + if( LMIC.snchAns ) { + LMIC.frame[end+0] = MCMD_SNCH_ANS; + LMIC.frame[end+1] = LMIC.snchAns & ~MCMD_SNCH_ANS_RFU; + end += 2; + LMIC.snchAns = 0; + } +#endif // !DISABLE_MCMD_SNCH_REQ + ASSERT(end <= OFF_DAT_OPTS+16); + + u1_t flen = end + (txdata ? 5+dlen : 4); + if( flen > MAX_LEN_FRAME ) { + // Options and payload too big - delay payload + txdata = 0; + flen = end+4; + } + LMIC.frame[OFF_DAT_HDR] = HDR_FTYPE_DAUP | HDR_MAJOR_V1; + LMIC.frame[OFF_DAT_FCT] = (LMIC.dnConf | LMIC.adrEnabled + | (LMIC.adrAckReq >= 0 ? FCT_ADRARQ : 0) + | (end-OFF_DAT_OPTS)); + os_wlsbf4(LMIC.frame+OFF_DAT_ADDR, LMIC.devaddr); + + if( LMIC.txCnt == 0 ) { + LMIC.seqnoUp += 1; + DO_DEVDB(LMIC.seqnoUp,seqnoUp); + } else { + EV(devCond, INFO, (e_.reason = EV::devCond_t::RE_TX, + e_.eui = MAIN::CDEV->getEui(), + e_.info = LMIC.seqnoUp-1, + e_.info2 = ((LMIC.txCnt+1) | + (TABLE_GET_U1(DRADJUST, LMIC.txCnt+1) << 8) | + ((LMIC.datarate|DR_PAGE)<<16)))); + } + os_wlsbf2(LMIC.frame+OFF_DAT_SEQNO, LMIC.seqnoUp-1); + + // Clear pending DN confirmation + LMIC.dnConf = 0; + + if( txdata ) { + if( LMIC.pendTxConf ) { + // Confirmed only makes sense if we have a payload (or at least a port) + LMIC.frame[OFF_DAT_HDR] = HDR_FTYPE_DCUP | HDR_MAJOR_V1; + if( LMIC.txCnt == 0 ) LMIC.txCnt = 1; + } + LMIC.frame[end] = LMIC.pendTxPort; + os_copyMem(LMIC.frame+end+1, LMIC.pendTxData, dlen); + aes_cipher(LMIC.pendTxPort==0 ? LMIC.nwkKey : LMIC.artKey, + LMIC.devaddr, LMIC.seqnoUp-1, + /*up*/0, LMIC.frame+end+1, dlen); + } + aes_appendMic(LMIC.nwkKey, LMIC.devaddr, LMIC.seqnoUp-1, /*up*/0, LMIC.frame, flen-4); + + EV(dfinfo, DEBUG, (e_.deveui = MAIN::CDEV->getEui(), + e_.devaddr = LMIC.devaddr, + e_.seqno = LMIC.seqnoUp-1, + e_.flags = (LMIC.pendTxPort < 0 ? EV::dfinfo_t::NOPORT : EV::dfinfo_t::NOP), + e_.mic = Base::lsbf4(&LMIC.frame[flen-4]), + e_.hdr = LMIC.frame[LORA::OFF_DAT_HDR], + e_.fct = LMIC.frame[LORA::OFF_DAT_FCT], + e_.port = LMIC.pendTxPort, + e_.plen = txdata ? dlen : 0, + e_.opts.length = end-LORA::OFF_DAT_OPTS, + memcpy(&e_.opts[0], LMIC.frame+LORA::OFF_DAT_OPTS, end-LORA::OFF_DAT_OPTS))); + LMIC.dataLen = flen; +} + + +#if !defined(DISABLE_BEACONS) +// Callback from HAL during scan mode or when job timer expires. +static void onBcnRx (xref2osjob_t job) { + // If we arrive via job timer make sure to put radio to rest. + os_radio(RADIO_RST); + os_clearCallback(&LMIC.osjob); + if( LMIC.dataLen == 0 ) { + // Nothing received - timeout + LMIC.opmode &= ~(OP_SCAN | OP_TRACK); + reportEvent(EV_SCAN_TIMEOUT); + return; + } + if( decodeBeacon() <= 0 ) { + // Something is wrong with the beacon - continue scan + LMIC.dataLen = 0; + os_radio(RADIO_RXON); + os_setTimedCallback(&LMIC.osjob, LMIC.bcninfo.txtime, FUNC_ADDR(onBcnRx)); + return; + } + // Found our 1st beacon + // We don't have a previous beacon to calc some drift - assume + // an max error of 13ms = 128sec*100ppm which is roughly +/-100ppm + calcBcnRxWindowFromMillis(13,1); + LMIC.opmode &= ~OP_SCAN; // turn SCAN off + LMIC.opmode |= OP_TRACK; // auto enable tracking + reportEvent(EV_BEACON_FOUND); // can be disabled in callback +} + + +// Enable receiver to listen to incoming beacons +// netid defines when scan stops (any or specific beacon) +// This mode ends with events: EV_SCAN_TIMEOUT/EV_SCAN_BEACON +// Implicitely cancels any pending TX/RX transaction. +// Also cancels an onpoing joining procedure. +static void startScan (void) { + ASSERT(LMIC.devaddr!=0 && (LMIC.opmode & OP_JOINING)==0); + if( (LMIC.opmode & OP_SHUTDOWN) != 0 ) + return; + // Cancel onging TX/RX transaction + LMIC.txCnt = LMIC.dnConf = LMIC.bcninfo.flags = 0; + LMIC.opmode = (LMIC.opmode | OP_SCAN) & ~(OP_TXRXPEND); + setBcnRxParams(); + LMIC.rxtime = LMIC.bcninfo.txtime = os_getTime() + sec2osticks(BCN_INTV_sec+1); + os_setTimedCallback(&LMIC.osjob, LMIC.rxtime, FUNC_ADDR(onBcnRx)); + os_radio(RADIO_RXON); +} + + +bit_t LMIC_enableTracking (u1_t tryBcnInfo) { + if( (LMIC.opmode & (OP_SCAN|OP_TRACK|OP_SHUTDOWN)) != 0 ) + return 0; // already in progress or failed to enable + // If BCN info requested from NWK then app has to take are + // of sending data up so that MCMD_BCNI_REQ can be attached. + if( (LMIC.bcninfoTries = tryBcnInfo) == 0 ) + startScan(); + return 1; // enabled +} + + +void LMIC_disableTracking (void) { + LMIC.opmode &= ~(OP_SCAN|OP_TRACK); + LMIC.bcninfoTries = 0; + engineUpdate(); +} +#endif // !DISABLE_BEACONS + + +// ================================================================================ +// +// Join stuff +// +// ================================================================================ + +#if !defined(DISABLE_JOIN) +static void buildJoinRequest (u1_t ftype) { + // Do not use pendTxData since we might have a pending + // user level frame in there. Use RX holding area instead. + xref2u1_t d = LMIC.frame; + d[OFF_JR_HDR] = ftype; + os_getArtEui(d + OFF_JR_ARTEUI); + os_getDevEui(d + OFF_JR_DEVEUI); + os_wlsbf2(d + OFF_JR_DEVNONCE, LMIC.devNonce); + aes_appendMic0(d, OFF_JR_MIC); + + EV(joininfo,INFO,(e_.deveui = MAIN::CDEV->getEui(), + e_.arteui = MAIN::CDEV->getArtEui(), + e_.nonce = LMIC.devNonce, + e_.oldaddr = LMIC.devaddr, + e_.mic = Base::lsbf4(&d[LORA::OFF_JR_MIC]), + e_.reason = ((LMIC.opmode & OP_REJOIN) != 0 + ? EV::joininfo_t::REJOIN_REQUEST + : EV::joininfo_t::REQUEST))); + LMIC.dataLen = LEN_JR; + LMIC.devNonce++; + DO_DEVDB(LMIC.devNonce,devNonce); +} + +static void startJoining (xref2osjob_t osjob) { + reportEvent(EV_JOINING); +} + +// Start join procedure if not already joined. +bit_t LMIC_startJoining (void) { + if( LMIC.devaddr == 0 ) { + // There should be no TX/RX going on + ASSERT((LMIC.opmode & (OP_POLL|OP_TXRXPEND)) == 0); + // Lift any previous duty limitation + LMIC.globalDutyRate = 0; + // Cancel scanning + LMIC.opmode &= ~(OP_SCAN|OP_REJOIN|OP_LINKDEAD|OP_NEXTCHNL); + // Setup state + LMIC.rejoinCnt = LMIC.txCnt = 0; + initJoinLoop(); + LMIC.opmode |= OP_JOINING; + // reportEvent will call engineUpdate which then starts sending JOIN REQUESTS + os_setCallback(&LMIC.osjob, FUNC_ADDR(startJoining)); + return 1; + } + return 0; // already joined +} +#endif // !DISABLE_JOIN + + +// ================================================================================ +// +// +// +// ================================================================================ + +#if !defined(DISABLE_PING) +static void processPingRx (xref2osjob_t osjob) { + if( LMIC.dataLen != 0 ) { + LMIC.txrxFlags = TXRX_PING; + if( decodeFrame() ) { + reportEvent(EV_RXCOMPLETE); + return; + } + } + // Pick next ping slot + engineUpdate(); +} +#endif // !DISABLE_PING + + +static bit_t processDnData (void) { + ASSERT((LMIC.opmode & OP_TXRXPEND)!=0); + + if( LMIC.dataLen == 0 ) { + norx: + if( LMIC.txCnt != 0 ) { + if( LMIC.txCnt < TXCONF_ATTEMPTS ) { + LMIC.txCnt += 1; + setDrTxpow(DRCHG_NOACK, lowerDR(LMIC.datarate, TABLE_GET_U1(DRADJUST, LMIC.txCnt)), KEEP_TXPOW); + // Schedule another retransmission + txDelay(LMIC.rxtime, RETRY_PERIOD_secs); + LMIC.opmode &= ~OP_TXRXPEND; + engineUpdate(); + return 1; + } + LMIC.txrxFlags = TXRX_NACK | TXRX_NOPORT; + } else { + // Nothing received - implies no port + LMIC.txrxFlags = TXRX_NOPORT; + } + if( LMIC.adrAckReq != LINK_CHECK_OFF ) + LMIC.adrAckReq += 1; + LMIC.dataBeg = LMIC.dataLen = 0; + txcomplete: + LMIC.opmode &= ~(OP_TXDATA|OP_TXRXPEND); + if( (LMIC.txrxFlags & (TXRX_DNW1|TXRX_DNW2|TXRX_PING)) != 0 && (LMIC.opmode & OP_LINKDEAD) != 0 ) { + LMIC.opmode &= ~OP_LINKDEAD; + reportEvent(EV_LINK_ALIVE); + } + reportEvent(EV_TXCOMPLETE); + // If we haven't heard from NWK in a while although we asked for a sign + // assume link is dead - notify application and keep going + if( LMIC.adrAckReq > LINK_CHECK_DEAD ) { + // We haven't heard from NWK for some time although we + // asked for a response for some time - assume we're disconnected. Lower DR one notch. + EV(devCond, ERR, (e_.reason = EV::devCond_t::LINK_DEAD, + e_.eui = MAIN::CDEV->getEui(), + e_.info = LMIC.adrAckReq)); + setDrTxpow(DRCHG_NOADRACK, decDR((dr_t)LMIC.datarate), KEEP_TXPOW); + LMIC.adrAckReq = LINK_CHECK_CONT; + LMIC.opmode |= OP_REJOIN|OP_LINKDEAD; + reportEvent(EV_LINK_DEAD); + } +#if !defined(DISABLE_BEACONS) + // If this falls to zero the NWK did not answer our MCMD_BCNI_REQ commands - try full scan + if( LMIC.bcninfoTries > 0 ) { + if( (LMIC.opmode & OP_TRACK) != 0 ) { + reportEvent(EV_BEACON_FOUND); + LMIC.bcninfoTries = 0; + } + else if( --LMIC.bcninfoTries == 0 ) { + startScan(); // NWK did not answer - try scan + } + } +#endif // !DISABLE_BEACONS + return 1; + } + if( !decodeFrame() ) { + if( (LMIC.txrxFlags & TXRX_DNW1) != 0 ) + return 0; + goto norx; + } + goto txcomplete; +} + + +#if !defined(DISABLE_BEACONS) +static void processBeacon (xref2osjob_t osjob) { + ostime_t lasttx = LMIC.bcninfo.txtime; // save here - decodeBeacon might overwrite + u1_t flags = LMIC.bcninfo.flags; + ev_t ev; + + if( LMIC.dataLen != 0 && decodeBeacon() >= 1 ) { + ev = EV_BEACON_TRACKED; + if( (flags & (BCN_PARTIAL|BCN_FULL)) == 0 ) { + // We don't have a previous beacon to calc some drift - assume + // an max error of 13ms = 128sec*100ppm which is roughly +/-100ppm + calcBcnRxWindowFromMillis(13,0); + goto rev; + } + // We have a previous BEACON to calculate some drift + s2_t drift = BCN_INTV_osticks - (LMIC.bcninfo.txtime - lasttx); + if( LMIC.missedBcns > 0 ) { + drift = LMIC.drift + (drift - LMIC.drift) / (LMIC.missedBcns+1); + } + if( (LMIC.bcninfo.flags & BCN_NODRIFT) == 0 ) { + s2_t diff = LMIC.drift - drift; + if( diff < 0 ) diff = -diff; + LMIC.lastDriftDiff = diff; + if( LMIC.maxDriftDiff < diff ) + LMIC.maxDriftDiff = diff; + LMIC.bcninfo.flags &= ~BCN_NODDIFF; + } + LMIC.drift = drift; + LMIC.missedBcns = LMIC.rejoinCnt = 0; + LMIC.bcninfo.flags &= ~BCN_NODRIFT; + EV(devCond,INFO,(e_.reason = EV::devCond_t::CLOCK_DRIFT, + e_.eui = MAIN::CDEV->getEui(), + e_.info = drift, + e_.info2 = /*occasion BEACON*/0)); + ASSERT((LMIC.bcninfo.flags & (BCN_PARTIAL|BCN_FULL)) != 0); + } else { + ev = EV_BEACON_MISSED; + LMIC.bcninfo.txtime += BCN_INTV_osticks - LMIC.drift; + LMIC.bcninfo.time += BCN_INTV_sec; + LMIC.missedBcns++; + // Delay any possible TX after surmised beacon - it's there although we missed it + txDelay(LMIC.bcninfo.txtime + BCN_RESERVE_osticks, 4); + if( LMIC.missedBcns > MAX_MISSED_BCNS ) + LMIC.opmode |= OP_REJOIN; // try if we can roam to another network + if( LMIC.bcnRxsyms > MAX_RXSYMS ) { + LMIC.opmode &= ~(OP_TRACK|OP_PINGABLE|OP_PINGINI|OP_REJOIN); + reportEvent(EV_LOST_TSYNC); + return; + } + } + LMIC.bcnRxtime = LMIC.bcninfo.txtime + BCN_INTV_osticks - calcRxWindow(0,DR_BCN); + LMIC.bcnRxsyms = LMIC.rxsyms; + rev: +#if CFG_us915 + LMIC.bcnChnl = (LMIC.bcnChnl+1) & 7; +#endif +#if !defined(DISABLE_PING) + if( (LMIC.opmode & OP_PINGINI) != 0 ) + rxschedInit(&LMIC.ping); // note: reuses LMIC.frame buffer! +#endif // !DISABLE_PING + reportEvent(ev); +} + + +static void startRxBcn (xref2osjob_t osjob) { + LMIC.osjob.func = FUNC_ADDR(processBeacon); + os_radio(RADIO_RX); +} +#endif // !DISABLE_BEACONS + + +#if !defined(DISABLE_PING) +static void startRxPing (xref2osjob_t osjob) { + LMIC.osjob.func = FUNC_ADDR(processPingRx); + os_radio(RADIO_RX); +} +#endif // !DISABLE_PING + + +// Decide what to do next for the MAC layer of a device +static void engineUpdate (void) { +#if LMIC_DEBUG_LEVEL > 0 + lmic_printf("%lu: engineUpdate, opmode=0x%x\n", os_getTime(), LMIC.opmode); +#endif + // Check for ongoing state: scan or TX/RX transaction + if( (LMIC.opmode & (OP_SCAN|OP_TXRXPEND|OP_SHUTDOWN)) != 0 ) + return; + +#if !defined(DISABLE_JOIN) + if( LMIC.devaddr == 0 && (LMIC.opmode & OP_JOINING) == 0 ) { + LMIC_startJoining(); + return; + } +#endif // !DISABLE_JOIN + + ostime_t now = os_getTime(); + ostime_t rxtime = 0; + ostime_t txbeg = 0; + +#if !defined(DISABLE_BEACONS) + if( (LMIC.opmode & OP_TRACK) != 0 ) { + // We are tracking a beacon + ASSERT( now + RX_RAMPUP - LMIC.bcnRxtime <= 0 ); + rxtime = LMIC.bcnRxtime - RX_RAMPUP; + } +#endif // !DISABLE_BEACONS + + if( (LMIC.opmode & (OP_JOINING|OP_REJOIN|OP_TXDATA|OP_POLL)) != 0 ) { + // Need to TX some data... + // Assuming txChnl points to channel which first becomes available again. + bit_t jacc = ((LMIC.opmode & (OP_JOINING|OP_REJOIN)) != 0 ? 1 : 0); + #if LMIC_DEBUG_LEVEL > 1 + if (jacc) + lmic_printf("%lu: Uplink join pending\n", os_getTime()); + else + lmic_printf("%lu: Uplink data pending\n", os_getTime()); + #endif + // Find next suitable channel and return availability time + if( (LMIC.opmode & OP_NEXTCHNL) != 0 ) { + txbeg = LMIC.txend = nextTx(now); + LMIC.opmode &= ~OP_NEXTCHNL; + #if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Airtime available at %lu (channel duty limit)\n", os_getTime(), txbeg); + #endif + } else { + txbeg = LMIC.txend; + #if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Airtime available at %lu (previously determined)\n", os_getTime(), txbeg); + #endif + } + // Delayed TX or waiting for duty cycle? + if( (LMIC.globalDutyRate != 0 || (LMIC.opmode & OP_RNDTX) != 0) && (txbeg - LMIC.globalDutyAvail) < 0 ) { + txbeg = LMIC.globalDutyAvail; + #if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Airtime available at %lu (global duty limit)\n", os_getTime(), txbeg); + #endif + } +#if !defined(DISABLE_BEACONS) + // If we're tracking a beacon... + // then make sure TX-RX transaction is complete before beacon + if( (LMIC.opmode & OP_TRACK) != 0 && + txbeg + (jacc ? JOIN_GUARD_osticks : TXRX_GUARD_osticks) - rxtime > 0 ) { + + #if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Awaiting beacon before uplink\n", os_getTime()); + #endif + + // Not enough time to complete TX-RX before beacon - postpone after beacon. + // In order to avoid clustering of postponed TX right after beacon randomize start! + txDelay(rxtime + BCN_RESERVE_osticks, 16); + txbeg = 0; + goto checkrx; + } +#endif // !DISABLE_BEACONS + // Earliest possible time vs overhead to setup radio + if( txbeg - (now + TX_RAMPUP) < 0 ) { + #if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Ready for uplink\n", os_getTime()); + #endif + // We could send right now! + txbeg = now; + dr_t txdr = (dr_t)LMIC.datarate; +#if !defined(DISABLE_JOIN) + if( jacc ) { + u1_t ftype; + if( (LMIC.opmode & OP_REJOIN) != 0 ) { + txdr = lowerDR(txdr, LMIC.rejoinCnt); + ftype = HDR_FTYPE_REJOIN; + } else { + ftype = HDR_FTYPE_JREQ; + } + buildJoinRequest(ftype); + LMIC.osjob.func = FUNC_ADDR(jreqDone); + } else +#endif // !DISABLE_JOIN + { + if( LMIC.seqnoDn >= 0xFFFFFF80 ) { + // Imminent roll over - proactively reset MAC + EV(specCond, INFO, (e_.reason = EV::specCond_t::DNSEQNO_ROLL_OVER, + e_.eui = MAIN::CDEV->getEui(), + e_.info = LMIC.seqnoDn, + e_.info2 = 0)); + // Device has to react! NWK will not roll over and just stop sending. + // Thus, we have N frames to detect a possible lock up. + reset: + os_setCallback(&LMIC.osjob, FUNC_ADDR(runReset)); + return; + } + if( (LMIC.txCnt==0 && LMIC.seqnoUp == 0xFFFFFFFF) ) { + // Roll over of up seq counter + EV(specCond, ERR, (e_.reason = EV::specCond_t::UPSEQNO_ROLL_OVER, + e_.eui = MAIN::CDEV->getEui(), + e_.info2 = LMIC.seqnoUp)); + // Do not run RESET event callback from here! + // App code might do some stuff after send unaware of RESET. + goto reset; + } + buildDataFrame(); + LMIC.osjob.func = FUNC_ADDR(updataDone); + } + LMIC.rps = setCr(updr2rps(txdr), (cr_t)LMIC.errcr); + LMIC.dndr = txdr; // carry TX datarate (can be != LMIC.datarate) over to txDone/setupRx1 + LMIC.opmode = (LMIC.opmode & ~(OP_POLL|OP_RNDTX)) | OP_TXRXPEND | OP_NEXTCHNL; + updateTx(txbeg); + os_radio(RADIO_TX); + return; + } + #if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Uplink delayed until %lu\n", os_getTime(), txbeg); + #endif + // Cannot yet TX + if( (LMIC.opmode & OP_TRACK) == 0 ) + goto txdelay; // We don't track the beacon - nothing else to do - so wait for the time to TX + // Consider RX tasks + if( txbeg == 0 ) // zero indicates no TX pending + txbeg += 1; // TX delayed by one tick (insignificant amount of time) + } else { + // No TX pending - no scheduled RX + if( (LMIC.opmode & OP_TRACK) == 0 ) + return; + } + +#if !defined(DISABLE_BEACONS) + // Are we pingable? + checkrx: +#if !defined(DISABLE_PING) + if( (LMIC.opmode & OP_PINGINI) != 0 ) { + // One more RX slot in this beacon period? + if( rxschedNext(&LMIC.ping, now+RX_RAMPUP) ) { + if( txbeg != 0 && (txbeg - LMIC.ping.rxtime) < 0 ) + goto txdelay; + LMIC.rxsyms = LMIC.ping.rxsyms; + LMIC.rxtime = LMIC.ping.rxtime; + LMIC.freq = LMIC.ping.freq; + LMIC.rps = dndr2rps(LMIC.ping.dr); + LMIC.dataLen = 0; + ASSERT(LMIC.rxtime - now+RX_RAMPUP >= 0 ); + os_setTimedCallback(&LMIC.osjob, LMIC.rxtime - RX_RAMPUP, FUNC_ADDR(startRxPing)); + return; + } + // no - just wait for the beacon + } +#endif // !DISABLE_PING + + if( txbeg != 0 && (txbeg - rxtime) < 0 ) + goto txdelay; + + setBcnRxParams(); + LMIC.rxsyms = LMIC.bcnRxsyms; + LMIC.rxtime = LMIC.bcnRxtime; + if( now - rxtime >= 0 ) { + LMIC.osjob.func = FUNC_ADDR(processBeacon); + os_radio(RADIO_RX); + return; + } + os_setTimedCallback(&LMIC.osjob, rxtime, FUNC_ADDR(startRxBcn)); + return; +#endif // !DISABLE_BEACONS + + txdelay: + EV(devCond, INFO, (e_.reason = EV::devCond_t::TX_DELAY, + e_.eui = MAIN::CDEV->getEui(), + e_.info = osticks2ms(txbeg-now), + e_.info2 = LMIC.seqnoUp-1)); + os_setTimedCallback(&LMIC.osjob, txbeg-TX_RAMPUP, FUNC_ADDR(runEngineUpdate)); +} + + +void LMIC_setAdrMode (bit_t enabled) { + LMIC.adrEnabled = enabled ? FCT_ADREN : 0; +} + + +// Should we have/need an ext. API like this? +void LMIC_setDrTxpow (dr_t dr, s1_t txpow) { + setDrTxpow(DRCHG_SET, dr, txpow); +} + + +void LMIC_shutdown (void) { + os_clearCallback(&LMIC.osjob); + os_radio(RADIO_RST); + LMIC.opmode |= OP_SHUTDOWN; +} + + +void LMIC_reset (void) { + EV(devCond, INFO, (e_.reason = EV::devCond_t::LMIC_EV, + e_.eui = MAIN::CDEV->getEui(), + e_.info = EV_RESET)); + os_radio(RADIO_RST); + os_clearCallback(&LMIC.osjob); + + os_clearMem((xref2u1_t)&LMIC,SIZEOFEXPR(LMIC)); + LMIC.devaddr = 0; + LMIC.devNonce = os_getRndU2(); + LMIC.opmode = OP_NONE; + LMIC.errcr = CR_4_5; + LMIC.adrEnabled = FCT_ADREN; + LMIC.dn2Dr = DR_DNW2; // we need this for 2nd DN window of join accept + LMIC.dn2Freq = FREQ_DNW2; // ditto + LMIC.rxDelay = DELAY_DNW1; +#if !defined(DISABLE_PING) + LMIC.ping.freq = FREQ_PING; // defaults for ping + LMIC.ping.dr = DR_PING; // ditto + LMIC.ping.intvExp = 0xFF; +#endif // !DISABLE_PING +#if defined(CFG_us915) + initDefaultChannels(); +#endif + DO_DEVDB(LMIC.devaddr, devaddr); + DO_DEVDB(LMIC.devNonce, devNonce); + DO_DEVDB(LMIC.dn2Dr, dn2Dr); + DO_DEVDB(LMIC.dn2Freq, dn2Freq); +#if !defined(DISABLE_PING) + DO_DEVDB(LMIC.ping.freq, pingFreq); + DO_DEVDB(LMIC.ping.dr, pingDr); + DO_DEVDB(LMIC.ping.intvExp, pingIntvExp); +#endif // !DISABLE_PING +} + + +void LMIC_init (void) { + LMIC.opmode = OP_SHUTDOWN; +} + + +void LMIC_clrTxData (void) { + LMIC.opmode &= ~(OP_TXDATA|OP_TXRXPEND|OP_POLL); + LMIC.pendTxLen = 0; + if( (LMIC.opmode & (OP_JOINING|OP_SCAN)) != 0 ) // do not interfere with JOINING + return; + os_clearCallback(&LMIC.osjob); + os_radio(RADIO_RST); + engineUpdate(); +} + + +void LMIC_setTxData (void) { + LMIC.opmode |= OP_TXDATA; + if( (LMIC.opmode & OP_JOINING) == 0 ) + LMIC.txCnt = 0; // cancel any ongoing TX/RX retries + engineUpdate(); +} + + +// +int LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed) { + if( dlen > SIZEOFEXPR(LMIC.pendTxData) ) + return -2; + if( data != (xref2u1_t)0 ) + os_copyMem(LMIC.pendTxData, data, dlen); + LMIC.pendTxConf = confirmed; + LMIC.pendTxPort = port; + LMIC.pendTxLen = dlen; + LMIC_setTxData(); + return 0; +} + + +// Send a payload-less message to signal device is alive +void LMIC_sendAlive (void) { + LMIC.opmode |= OP_POLL; + engineUpdate(); +} + + +// Check if other networks are around. +void LMIC_tryRejoin (void) { + LMIC.opmode |= OP_REJOIN; + engineUpdate(); +} + +//! \brief Setup given session keys +//! and put the MAC in a state as if +//! a join request/accept would have negotiated just these keys. +//! It is crucial that the combinations `devaddr/nwkkey` and `devaddr/artkey` +//! are unique within the network identified by `netid`. +//! NOTE: on Harvard architectures when session keys are in flash: +//! Caller has to fill in LMIC.{nwk,art}Key before and pass {nwk,art}Key are NULL +//! \param netid a 24 bit number describing the network id this device is using +//! \param devaddr the 32 bit session address of the device. It is strongly recommended +//! to ensure that different devices use different numbers with high probability. +//! \param nwkKey the 16 byte network session key used for message integrity. +//! If NULL the caller has copied the key into `LMIC.nwkKey` before. +//! \param artKey the 16 byte application router session key used for message confidentiality. +//! If NULL the caller has copied the key into `LMIC.artKey` before. +void LMIC_setSession (u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t artKey) { + LMIC.netid = netid; + LMIC.devaddr = devaddr; + if( nwkKey != (xref2u1_t)0 ) + os_copyMem(LMIC.nwkKey, nwkKey, 16); + if( artKey != (xref2u1_t)0 ) + os_copyMem(LMIC.artKey, artKey, 16); + +#if defined(CFG_eu868) + initDefaultChannels(0); +#endif + + LMIC.opmode &= ~(OP_JOINING|OP_TRACK|OP_REJOIN|OP_TXRXPEND|OP_PINGINI); + LMIC.opmode |= OP_NEXTCHNL; + stateJustJoined(); + DO_DEVDB(LMIC.netid, netid); + DO_DEVDB(LMIC.devaddr, devaddr); + DO_DEVDB(LMIC.nwkKey, nwkkey); + DO_DEVDB(LMIC.artKey, artkey); + DO_DEVDB(LMIC.seqnoUp, seqnoUp); + DO_DEVDB(LMIC.seqnoDn, seqnoDn); +} + +// Enable/disable link check validation. +// LMIC sets the ADRACKREQ bit in UP frames if there were no DN frames +// for a while. It expects the network to provide a DN message to prove +// connectivity with a span of UP frames. If this no such prove is coming +// then the datarate is lowered and a LINK_DEAD event is generated. +// This mode can be disabled and no connectivity prove (ADRACKREQ) is requested +// nor is the datarate changed. +// This must be called only if a session is established (e.g. after EV_JOINED) +void LMIC_setLinkCheckMode (bit_t enabled) { + LMIC.adrChanged = 0; + LMIC.adrAckReq = enabled ? LINK_CHECK_INIT : LINK_CHECK_OFF; +} + +// Sets the max clock error to compensate for (defaults to 0, which +// allows for +/- 640 at SF7BW250). MAX_CLOCK_ERROR represents +/-100%, +// so e.g. for a +/-1% error you would pass MAX_CLOCK_ERROR * 1 / 100. +void LMIC_setClockError(u2_t error) { + LMIC.clockError = error; +} diff --git a/libraries/IBM_LMIC_framework/src/lmic/lmic.h b/libraries/IBM_LMIC_framework/src/lmic/lmic.h new file mode 100644 index 0000000..55c8e12 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/lmic/lmic.h @@ -0,0 +1,320 @@ +/******************************************************************************* + * Copyright (c) 2014-2015 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Zurich Research Lab - initial API, implementation and documentation + *******************************************************************************/ + +//! @file +//! @brief LMIC API + +#ifndef _lmic_h_ +#define _lmic_h_ + +#include "oslmic.h" +#include "lorabase.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +// LMIC version +#define LMIC_VERSION_MAJOR 1 +#define LMIC_VERSION_MINOR 5 +#define LMIC_VERSION_BUILD 1431528305 + +enum { MAX_FRAME_LEN = 64 }; //!< Library cap on max frame length +enum { TXCONF_ATTEMPTS = 8 }; //!< Transmit attempts for confirmed frames +enum { MAX_MISSED_BCNS = 20 }; // threshold for triggering rejoin requests +enum { MAX_RXSYMS = 100 }; // stop tracking beacon beyond this + +enum { LINK_CHECK_CONT = 12 , // continue with this after reported dead link + LINK_CHECK_DEAD = 24 , // after this UP frames and no response from NWK assume link is dead + LINK_CHECK_INIT = -12 , // UP frame count until we inc datarate + LINK_CHECK_OFF =-128 }; // link check disabled + +enum { TIME_RESYNC = 6*128 }; // secs +enum { TXRX_GUARD_ms = 6000 }; // msecs - don't start TX-RX transaction before beacon +enum { JOIN_GUARD_ms = 9000 }; // msecs - don't start Join Req/Acc transaction before beacon +enum { TXRX_BCNEXT_secs = 2 }; // secs - earliest start after beacon time +enum { RETRY_PERIOD_secs = 3 }; // secs - random period for retrying a confirmed send + +#if defined(CFG_eu868) // EU868 spectrum ==================================================== + +enum { MAX_CHANNELS = 16 }; //!< Max supported channels +enum { MAX_BANDS = 4 }; + +enum { LIMIT_CHANNELS = (1<<4) }; // EU868 will never have more channels +//! \internal +struct band_t { + u2_t txcap; // duty cycle limitation: 1/txcap + s1_t txpow; // maximum TX power + u1_t lastchnl; // last used channel + ostime_t avail; // channel is blocked until this time +}; +TYPEDEF_xref2band_t; //!< \internal + +#elif defined(CFG_us915) // US915 spectrum ================================================= + +enum { MAX_XCHANNELS = 2 }; // extra channels in RAM, channels 0-71 are immutable +enum { MAX_TXPOW_125kHz = 30 }; + +#endif // ========================================================================== + +// Keep in sync with evdefs.hpp::drChange +enum { DRCHG_SET, DRCHG_NOJACC, DRCHG_NOACK, DRCHG_NOADRACK, DRCHG_NWKCMD }; +enum { KEEP_TXPOW = -128 }; + + +#if !defined(DISABLE_PING) +//! \internal +struct rxsched_t { + u1_t dr; + u1_t intvExp; // 0..7 + u1_t slot; // runs from 0 to 128 + u1_t rxsyms; + ostime_t rxbase; + ostime_t rxtime; // start of next spot + u4_t freq; +}; +TYPEDEF_xref2rxsched_t; //!< \internal +#endif // !DISABLE_PING + + +#if !defined(DISABLE_BEACONS) +//! Parsing and tracking states of beacons. +enum { BCN_NONE = 0x00, //!< No beacon received + BCN_PARTIAL = 0x01, //!< Only first (common) part could be decoded (info,lat,lon invalid/previous) + BCN_FULL = 0x02, //!< Full beacon decoded + BCN_NODRIFT = 0x04, //!< No drift value measured yet + BCN_NODDIFF = 0x08 }; //!< No differential drift measured yet +//! Information about the last and previous beacons. +struct bcninfo_t { + ostime_t txtime; //!< Time when the beacon was sent + s1_t rssi; //!< Adjusted RSSI value of last received beacon + s1_t snr; //!< Scaled SNR value of last received beacon + u1_t flags; //!< Last beacon reception and tracking states. See BCN_* values. + u4_t time; //!< GPS time in seconds of last beacon (received or surrogate) + // + u1_t info; //!< Info field of last beacon (valid only if BCN_FULL set) + s4_t lat; //!< Lat field of last beacon (valid only if BCN_FULL set) + s4_t lon; //!< Lon field of last beacon (valid only if BCN_FULL set) +}; +#endif // !DISABLE_BEACONS + +// purpose of receive window - lmic_t.rxState +enum { RADIO_RST=0, RADIO_TX=1, RADIO_RX=2, RADIO_RXON=3 }; +// Netid values / lmic_t.netid +enum { NETID_NONE=(int)~0U, NETID_MASK=(int)0xFFFFFF }; +// MAC operation modes (lmic_t.opmode). +enum { OP_NONE = 0x0000, + OP_SCAN = 0x0001, // radio scan to find a beacon + OP_TRACK = 0x0002, // track my networks beacon (netid) + OP_JOINING = 0x0004, // device joining in progress (blocks other activities) + OP_TXDATA = 0x0008, // TX user data (buffered in pendTxData) + OP_POLL = 0x0010, // send empty UP frame to ACK confirmed DN/fetch more DN data + OP_REJOIN = 0x0020, // occasionally send JOIN REQUEST + OP_SHUTDOWN = 0x0040, // prevent MAC from doing anything + OP_TXRXPEND = 0x0080, // TX/RX transaction pending + OP_RNDTX = 0x0100, // prevent TX lining up after a beacon + OP_PINGINI = 0x0200, // pingable is initialized and scheduling active + OP_PINGABLE = 0x0400, // we're pingable + OP_NEXTCHNL = 0x0800, // find a new channel + OP_LINKDEAD = 0x1000, // link was reported as dead + OP_TESTMODE = 0x2000, // developer test mode +}; +// TX-RX transaction flags - report back to user +enum { TXRX_ACK = 0x80, // confirmed UP frame was acked + TXRX_NACK = 0x40, // confirmed UP frame was not acked + TXRX_NOPORT = 0x20, // set if a frame with a port was RXed, clr if no frame/no port + TXRX_PORT = 0x10, // set if a frame with a port was RXed, LMIC.frame[LMIC.dataBeg-1] => port + TXRX_DNW1 = 0x01, // received in 1st DN slot + TXRX_DNW2 = 0x02, // received in 2dn DN slot + TXRX_PING = 0x04 }; // received in a scheduled RX slot +// Event types for event callback +enum _ev_t { EV_SCAN_TIMEOUT=1, EV_BEACON_FOUND, + EV_BEACON_MISSED, EV_BEACON_TRACKED, EV_JOINING, + EV_JOINED, EV_RFU1, EV_JOIN_FAILED, EV_REJOIN_FAILED, + EV_TXCOMPLETE, EV_LOST_TSYNC, EV_RESET, + EV_RXCOMPLETE, EV_LINK_DEAD, EV_LINK_ALIVE }; +typedef enum _ev_t ev_t; + +enum { + // This value represents 100% error in LMIC.clockError + MAX_CLOCK_ERROR = 65536, +}; + +struct lmic_t { + // Radio settings TX/RX (also accessed by HAL) + ostime_t txend; + ostime_t rxtime; + u4_t freq; + s1_t rssi; + s1_t snr; + rps_t rps; + u1_t rxsyms; + u1_t dndr; + s1_t txpow; // dBm + + osjob_t osjob; + + // Channel scheduling +#if defined(CFG_eu868) + band_t bands[MAX_BANDS]; + u4_t channelFreq[MAX_CHANNELS]; + u2_t channelDrMap[MAX_CHANNELS]; + u2_t channelMap; +#elif defined(CFG_us915) + u4_t xchFreq[MAX_XCHANNELS]; // extra channel frequencies (if device is behind a repeater) + u2_t xchDrMap[MAX_XCHANNELS]; // extra channel datarate ranges ---XXX: ditto + u2_t channelMap[(72+MAX_XCHANNELS+15)/16]; // enabled bits + u2_t chRnd; // channel randomizer +#endif + u1_t txChnl; // channel for next TX + u1_t globalDutyRate; // max rate: 1/2^k + ostime_t globalDutyAvail; // time device can send again + + u4_t netid; // current network id (~0 - none) + u2_t opmode; + u1_t upRepeat; // configured up repeat + s1_t adrTxPow; // ADR adjusted TX power + u1_t datarate; // current data rate + u1_t errcr; // error coding rate (used for TX only) + u1_t rejoinCnt; // adjustment for rejoin datarate +#if !defined(DISABLE_BEACONS) + s2_t drift; // last measured drift + s2_t lastDriftDiff; + s2_t maxDriftDiff; +#endif + + u2_t clockError; // Inaccuracy in the clock. CLOCK_ERROR_MAX + // represents +/-100% error + + u1_t pendTxPort; + u1_t pendTxConf; // confirmed data + u1_t pendTxLen; // +0x80 = confirmed + u1_t pendTxData[MAX_LEN_PAYLOAD]; + + u2_t devNonce; // last generated nonce + u1_t nwkKey[16]; // network session key + u1_t artKey[16]; // application router session key + devaddr_t devaddr; + u4_t seqnoDn; // device level down stream seqno + u4_t seqnoUp; + + u1_t dnConf; // dn frame confirm pending: LORA::FCT_ACK or 0 + s1_t adrAckReq; // counter until we reset data rate (0=off) + u1_t adrChanged; + + u1_t rxDelay; // Rx delay after TX + + u1_t margin; + bit_t ladrAns; // link adr adapt answer pending + bit_t devsAns; // device status answer pending + u1_t adrEnabled; + u1_t moreData; // NWK has more data pending +#if !defined(DISABLE_MCMD_DCAP_REQ) + bit_t dutyCapAns; // have to ACK duty cycle settings +#endif +#if !defined(DISABLE_MCMD_SNCH_REQ) + u1_t snchAns; // answer set new channel +#endif + // 2nd RX window (after up stream) + u1_t dn2Dr; + u4_t dn2Freq; +#if !defined(DISABLE_MCMD_DN2P_SET) + u1_t dn2Ans; // 0=no answer pend, 0x80+ACKs +#endif + + // Class B state +#if !defined(DISABLE_BEACONS) + u1_t missedBcns; // unable to track last N beacons + u1_t bcninfoTries; // how often to try (scan mode only) +#endif +#if !defined(DISABLE_MCMD_PING_SET) && !defined(DISABLE_PING) + u1_t pingSetAns; // answer set cmd and ACK bits +#endif +#if !defined(DISABLE_PING) + rxsched_t ping; // pingable setup +#endif + + // Public part of MAC state + u1_t txCnt; + u1_t txrxFlags; // transaction flags (TX-RX combo) + u1_t dataBeg; // 0 or start of data (dataBeg-1 is port) + u1_t dataLen; // 0 no data or zero length data, >0 byte count of data + u1_t frame[MAX_LEN_FRAME]; + +#if !defined(DISABLE_BEACONS) + u1_t bcnChnl; + u1_t bcnRxsyms; // + ostime_t bcnRxtime; + bcninfo_t bcninfo; // Last received beacon info +#endif +}; +//! \var struct lmic_t LMIC +//! The state of LMIC MAC layer is encapsulated in this variable. +DECLARE_LMIC; //!< \internal + +//! Construct a bit map of allowed datarates from drlo to drhi (both included). +#define DR_RANGE_MAP(drlo,drhi) (((u2_t)0xFFFF<<(drlo)) & ((u2_t)0xFFFF>>(15-(drhi)))) +#if defined(CFG_eu868) +enum { BAND_MILLI=0, BAND_CENTI=1, BAND_DECI=2, BAND_AUX=3 }; +bit_t LMIC_setupBand (u1_t bandidx, s1_t txpow, u2_t txcap); +#endif +bit_t LMIC_setupChannel (u1_t channel, u4_t freq, u2_t drmap, s1_t band); +void LMIC_disableChannel (u1_t channel); +#if defined(CFG_us915) +void LMIC_enableChannel (u1_t channel); +void LMIC_enableSubBand (u1_t band); +void LMIC_disableSubBand (u1_t band); +void LMIC_selectSubBand (u1_t band); +#endif + +void LMIC_setDrTxpow (dr_t dr, s1_t txpow); // set default/start DR/txpow +void LMIC_setAdrMode (bit_t enabled); // set ADR mode (if mobile turn off) +#if !defined(DISABLE_JOIN) +bit_t LMIC_startJoining (void); +#endif + +void LMIC_shutdown (void); +void LMIC_init (void); +void LMIC_reset (void); +void LMIC_clrTxData (void); +void LMIC_setTxData (void); +int LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed); +void LMIC_sendAlive (void); + +#if !defined(DISABLE_BEACONS) +bit_t LMIC_enableTracking (u1_t tryBcnInfo); +void LMIC_disableTracking (void); +#endif + +#if !defined(DISABLE_PING) +void LMIC_stopPingable (void); +void LMIC_setPingable (u1_t intvExp); +#endif +#if !defined(DISABLE_JOIN) +void LMIC_tryRejoin (void); +#endif + +void LMIC_setSession (u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t artKey); +void LMIC_setLinkCheckMode (bit_t enabled); +void LMIC_setClockError(u2_t error); + +// Declare onEvent() function, to make sure any definition will have the +// C conventions, even when in a C++ file. +DECL_ON_LMIC_EVENT; + +// Special APIs - for development or testing +// !!!See implementation for caveats!!! + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _lmic_h_ diff --git a/libraries/IBM_LMIC_framework/src/lmic/lorabase.h b/libraries/IBM_LMIC_framework/src/lmic/lorabase.h new file mode 100644 index 0000000..4274610 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/lmic/lorabase.h @@ -0,0 +1,391 @@ +/******************************************************************************* + * Copyright (c) 2014-2015 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Zurich Research Lab - initial API, implementation and documentation + *******************************************************************************/ + +#ifndef _lorabase_h_ +#define _lorabase_h_ + +#ifdef __cplusplus +extern "C"{ +#endif + +// ================================================================================ +// BEG: Keep in sync with lorabase.hpp +// + +enum _cr_t { CR_4_5=0, CR_4_6, CR_4_7, CR_4_8 }; +enum _sf_t { FSK=0, SF7, SF8, SF9, SF10, SF11, SF12, SFrfu }; +enum _bw_t { BW125=0, BW250, BW500, BWrfu }; +typedef u1_t cr_t; +typedef u1_t sf_t; +typedef u1_t bw_t; +typedef u1_t dr_t; +// Radio parameter set (encodes SF/BW/CR/IH/NOCRC) +typedef u2_t rps_t; +TYPEDEF_xref2rps_t; + +enum { ILLEGAL_RPS = 0xFF }; +enum { DR_PAGE_EU868 = 0x00 }; +enum { DR_PAGE_US915 = 0x10 }; + +// Global maximum frame length +enum { STD_PREAMBLE_LEN = 8 }; +enum { MAX_LEN_FRAME = 64 }; +enum { LEN_DEVNONCE = 2 }; +enum { LEN_ARTNONCE = 3 }; +enum { LEN_NETID = 3 }; +enum { DELAY_JACC1 = 5 }; // in secs +enum { DELAY_DNW1 = 1 }; // in secs down window #1 +enum { DELAY_EXTDNW2 = 1 }; // in secs +enum { DELAY_JACC2 = DELAY_JACC1+(int)DELAY_EXTDNW2 }; // in secs +enum { DELAY_DNW2 = DELAY_DNW1 +(int)DELAY_EXTDNW2 }; // in secs down window #1 +enum { BCN_INTV_exp = 7 }; +enum { BCN_INTV_sec = 1<> 3) & 0x3); } +inline rps_t setBw (rps_t params, bw_t cr) { return (rps_t)((params & ~0x18) | (cr<<3)); } +inline cr_t getCr (rps_t params) { return (cr_t)((params >> 5) & 0x3); } +inline rps_t setCr (rps_t params, cr_t cr) { return (rps_t)((params & ~0x60) | (cr<<5)); } +inline int getNocrc(rps_t params) { return ((params >> 7) & 0x1); } +inline rps_t setNocrc(rps_t params, int nocrc) { return (rps_t)((params & ~0x80) | (nocrc<<7)); } +inline int getIh (rps_t params) { return ((params >> 8) & 0xFF); } +inline rps_t setIh (rps_t params, int ih) { return (rps_t)((params & ~0xFF00) | (ih<<8)); } +inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc) { + return sf | (bw<<3) | (cr<<5) | (nocrc?(1<<7):0) | ((ih&0xFF)<<8); +} +#define MAKERPS(sf,bw,cr,ih,nocrc) ((rps_t)((sf) | ((bw)<<3) | ((cr)<<5) | ((nocrc)?(1<<7):0) | ((ih&0xFF)<<8))) +// Two frames with params r1/r2 would interfere on air: same SFx + BWx +inline int sameSfBw(rps_t r1, rps_t r2) { return ((r1^r2)&0x1F) == 0; } + +extern CONST_TABLE(u1_t, _DR2RPS_CRC)[]; +inline rps_t updr2rps (dr_t dr) { return (rps_t)TABLE_GET_U1(_DR2RPS_CRC, dr+1); } +inline rps_t dndr2rps (dr_t dr) { return setNocrc(updr2rps(dr),1); } +inline int isFasterDR (dr_t dr1, dr_t dr2) { return dr1 > dr2; } +inline int isSlowerDR (dr_t dr1, dr_t dr2) { return dr1 < dr2; } +inline dr_t incDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+2)==ILLEGAL_RPS ? dr : (dr_t)(dr+1); } // increase data rate +inline dr_t decDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr )==ILLEGAL_RPS ? dr : (dr_t)(dr-1); } // decrease data rate +inline dr_t assertDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+1)==ILLEGAL_RPS ? DR_DFLTMIN : dr; } // force into a valid DR +inline bit_t validDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+1)!=ILLEGAL_RPS; } // in range +inline dr_t lowerDR (dr_t dr, u1_t n) { while(n--){dr=decDR(dr);} return dr; } // decrease data rate by n steps + +// +// BEG: Keep in sync with lorabase.hpp +// ================================================================================ + + +// Convert between dBm values and power codes (MCMD_LADR_XdBm) +s1_t pow2dBm (u1_t mcmd_ladr_p1); +// Calculate airtime +ostime_t calcAirTime (rps_t rps, u1_t plen); +// Sensitivity at given SF/BW +int getSensitivity (rps_t rps); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _lorabase_h_ diff --git a/libraries/IBM_LMIC_framework/src/lmic/oslmic.c b/libraries/IBM_LMIC_framework/src/lmic/oslmic.c new file mode 100644 index 0000000..ec6c19f --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/lmic/oslmic.c @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2014-2015 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Zurich Research Lab - initial API, implementation and documentation + *******************************************************************************/ + +#include "lmic.h" +#include + +// RUNTIME STATE +static struct { + osjob_t* scheduledjobs; + osjob_t* runnablejobs; +} OS; + +void os_init () { + memset(&OS, 0x00, sizeof(OS)); + hal_init(); + radio_init(); + LMIC_init(); +} + +ostime_t os_getTime () { + return hal_ticks(); +} + +static u1_t unlinkjob (osjob_t** pnext, osjob_t* job) { + for( ; *pnext; pnext = &((*pnext)->next)) { + if(*pnext == job) { // unlink + *pnext = job->next; + return 1; + } + } + return 0; +} + +// clear scheduled job +void os_clearCallback (osjob_t* job) { + hal_disableIRQs(); + u1_t res = unlinkjob(&OS.scheduledjobs, job) || unlinkjob(&OS.runnablejobs, job); + hal_enableIRQs(); + #if LMIC_DEBUG_LEVEL > 1 + if (res) + lmic_printf("%lu: Cleared job %p\n", os_getTime(), job); + #endif +} + +// schedule immediately runnable job +void os_setCallback (osjob_t* job, osjobcb_t cb) { + osjob_t** pnext; + hal_disableIRQs(); + // remove if job was already queued + os_clearCallback(job); + // fill-in job + job->func = cb; + job->next = NULL; + // add to end of run queue + for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next)); + *pnext = job; + hal_enableIRQs(); + #if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Scheduled job %p, cb %p ASAP\n", os_getTime(), job, cb); + #endif +} + +// schedule timed job +void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) { + osjob_t** pnext; + hal_disableIRQs(); + // remove if job was already queued + os_clearCallback(job); + // fill-in job + job->deadline = time; + job->func = cb; + job->next = NULL; + // insert into schedule + for(pnext=&OS.scheduledjobs; *pnext; pnext=&((*pnext)->next)) { + if((*pnext)->deadline - time > 0) { // (cmp diff, not abs!) + // enqueue before next element and stop + job->next = *pnext; + break; + } + } + *pnext = job; + hal_enableIRQs(); + #if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Scheduled job %p, cb %p at %lu\n", os_getTime(), job, cb, time); + #endif +} + +// execute jobs from timer and from run queue +void os_runloop () { + while(1) { + os_runloop_once(); + } +} + +void os_runloop_once() { + #if LMIC_DEBUG_LEVEL > 1 + bool has_deadline = false; + #endif + osjob_t* j = NULL; + hal_disableIRQs(); + // check for runnable jobs + if(OS.runnablejobs) { + j = OS.runnablejobs; + OS.runnablejobs = j->next; + } else if(OS.scheduledjobs && hal_checkTimer(OS.scheduledjobs->deadline)) { // check for expired timed jobs + j = OS.scheduledjobs; + OS.scheduledjobs = j->next; + #if LMIC_DEBUG_LEVEL > 1 + has_deadline = true; + #endif + } else { // nothing pending + hal_sleep(); // wake by irq (timer already restarted) + } + hal_enableIRQs(); + if(j) { // run job callback + #if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: Running job %p, cb %p, deadline %lu\n", os_getTime(), j, j->func, has_deadline ? j->deadline : 0); + #endif + j->func(j); + } +} diff --git a/libraries/IBM_LMIC_framework/src/lmic/oslmic.h b/libraries/IBM_LMIC_framework/src/lmic/oslmic.h new file mode 100644 index 0000000..678d16b --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/lmic/oslmic.h @@ -0,0 +1,288 @@ +/******************************************************************************* + * Copyright (c) 2014-2015 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Zurich Research Lab - initial API, implementation and documentation + *******************************************************************************/ + +//! \file +#ifndef _oslmic_h_ +#define _oslmic_h_ + +// Dependencies required for the LoRa MAC in C to run. +// These settings can be adapted to the underlying system. +// You should not, however, change the lmic.[hc] + +#include "config.h" +#include +#include + +#ifdef __cplusplus +extern "C"{ +#endif + +//================================================================================ +//================================================================================ +// Target platform as C library +typedef uint8_t bit_t; +typedef uint8_t u1_t; +typedef int8_t s1_t; +typedef uint16_t u2_t; +typedef int16_t s2_t; +typedef uint32_t u4_t; +typedef int32_t s4_t; +typedef unsigned int uint; +typedef const char* str_t; + +#include +#include "hal.h" +#define EV(a,b,c) /**/ +#define DO_DEVDB(field1,field2) /**/ +#if !defined(CFG_noassert) +#define ASSERT(cond) if(!(cond)) hal_failed(__FILE__, __LINE__) +#else +#define ASSERT(cond) /**/ +#endif + +#define os_clearMem(a,b) memset(a,0,b) +#define os_copyMem(a,b,c) memcpy(a,b,c) + +typedef struct osjob_t osjob_t; +typedef struct band_t band_t; +typedef struct chnldef_t chnldef_t; +typedef struct rxsched_t rxsched_t; +typedef struct bcninfo_t bcninfo_t; +typedef const u1_t* xref2cu1_t; +typedef u1_t* xref2u1_t; +#define TYPEDEF_xref2rps_t typedef rps_t* xref2rps_t +#define TYPEDEF_xref2rxsched_t typedef rxsched_t* xref2rxsched_t +#define TYPEDEF_xref2chnldef_t typedef chnldef_t* xref2chnldef_t +#define TYPEDEF_xref2band_t typedef band_t* xref2band_t +#define TYPEDEF_xref2osjob_t typedef osjob_t* xref2osjob_t + +#define SIZEOFEXPR(x) sizeof(x) + +#define ON_LMIC_EVENT(ev) onEvent(ev) +#define DECL_ON_LMIC_EVENT void onEvent(ev_t e) + +extern u4_t AESAUX[]; +extern u4_t AESKEY[]; +#define AESkey ((u1_t*)AESKEY) +#define AESaux ((u1_t*)AESAUX) +#define FUNC_ADDR(func) (&(func)) + +u1_t radio_rand1 (void); +#define os_getRndU1() radio_rand1() + +#define DEFINE_LMIC struct lmic_t LMIC +#define DECLARE_LMIC extern struct lmic_t LMIC + +void radio_init (void); +void radio_irq_handler (u1_t dio); +void os_init (void); +void os_runloop (void); +void os_runloop_once (void); + +//================================================================================ + + +#ifndef RX_RAMPUP +#define RX_RAMPUP (us2osticks(2000)) +#endif +#ifndef TX_RAMPUP +#define TX_RAMPUP (us2osticks(2000)) +#endif + +#ifndef OSTICKS_PER_SEC +#define OSTICKS_PER_SEC 32768 +#elif OSTICKS_PER_SEC < 10000 || OSTICKS_PER_SEC > 64516 +#error Illegal OSTICKS_PER_SEC - must be in range [10000:64516]. One tick must be 15.5us .. 100us long. +#endif + +typedef s4_t ostime_t; + +#if !HAS_ostick_conv +#define us2osticks(us) ((ostime_t)( ((int64_t)(us) * OSTICKS_PER_SEC) / 1000000)) +#define ms2osticks(ms) ((ostime_t)( ((int64_t)(ms) * OSTICKS_PER_SEC) / 1000)) +#define sec2osticks(sec) ((ostime_t)( (int64_t)(sec) * OSTICKS_PER_SEC)) +#define osticks2ms(os) ((s4_t)(((os)*(int64_t)1000 ) / OSTICKS_PER_SEC)) +#define osticks2us(os) ((s4_t)(((os)*(int64_t)1000000 ) / OSTICKS_PER_SEC)) +// Special versions +#define us2osticksCeil(us) ((ostime_t)( ((int64_t)(us) * OSTICKS_PER_SEC + 999999) / 1000000)) +#define us2osticksRound(us) ((ostime_t)( ((int64_t)(us) * OSTICKS_PER_SEC + 500000) / 1000000)) +#define ms2osticksCeil(ms) ((ostime_t)( ((int64_t)(ms) * OSTICKS_PER_SEC + 999) / 1000)) +#define ms2osticksRound(ms) ((ostime_t)( ((int64_t)(ms) * OSTICKS_PER_SEC + 500) / 1000)) +#endif + + +struct osjob_t; // fwd decl. +typedef void (*osjobcb_t) (struct osjob_t*); +struct osjob_t { + struct osjob_t* next; + ostime_t deadline; + osjobcb_t func; +}; +TYPEDEF_xref2osjob_t; + + +#ifndef HAS_os_calls + +#ifndef os_getDevKey +void os_getDevKey (xref2u1_t buf); +#endif +#ifndef os_getArtEui +void os_getArtEui (xref2u1_t buf); +#endif +#ifndef os_getDevEui +void os_getDevEui (xref2u1_t buf); +#endif +#ifndef os_setCallback +void os_setCallback (xref2osjob_t job, osjobcb_t cb); +#endif +#ifndef os_setTimedCallback +void os_setTimedCallback (xref2osjob_t job, ostime_t time, osjobcb_t cb); +#endif +#ifndef os_clearCallback +void os_clearCallback (xref2osjob_t job); +#endif +#ifndef os_getTime +ostime_t os_getTime (void); +#endif +#ifndef os_getTimeSecs +uint os_getTimeSecs (void); +#endif +#ifndef os_radio +void os_radio (u1_t mode); +#endif +#ifndef os_getBattLevel +u1_t os_getBattLevel (void); +#endif + +#ifndef os_rlsbf4 +//! Read 32-bit quantity from given pointer in little endian byte order. +u4_t os_rlsbf4 (xref2cu1_t buf); +#endif +#ifndef os_wlsbf4 +//! Write 32-bit quntity into buffer in little endian byte order. +void os_wlsbf4 (xref2u1_t buf, u4_t value); +#endif +#ifndef os_rmsbf4 +//! Read 32-bit quantity from given pointer in big endian byte order. +u4_t os_rmsbf4 (xref2cu1_t buf); +#endif +#ifndef os_wmsbf4 +//! Write 32-bit quntity into buffer in big endian byte order. +void os_wmsbf4 (xref2u1_t buf, u4_t value); +#endif +#ifndef os_rlsbf2 +//! Read 16-bit quantity from given pointer in little endian byte order. +u2_t os_rlsbf2 (xref2cu1_t buf); +#endif +#ifndef os_wlsbf2 +//! Write 16-bit quntity into buffer in little endian byte order. +void os_wlsbf2 (xref2u1_t buf, u2_t value); +#endif + +//! Get random number (default impl for u2_t). +#ifndef os_getRndU2 +#define os_getRndU2() ((u2_t)((os_getRndU1()<<8)|os_getRndU1())) +#endif +#ifndef os_crc16 +u2_t os_crc16 (xref2u1_t d, uint len); +#endif + +#endif // !HAS_os_calls + +// ====================================================================== +// Table support +// These macros for defining a table of constants and retrieving values +// from it makes it easier for other platforms (like AVR) to optimize +// table accesses. +// Use CONST_TABLE() whenever declaring or defining a table, and +// TABLE_GET_xx whenever accessing its values. The actual name of the +// declared variable will be modified to prevent accidental direct +// access. The accessor macros forward to an inline function to allow +// proper type checking of the array element type. + +// Helper to add a prefix to the table name +#define RESOLVE_TABLE(table) constant_table_ ## table + +// Accessors for table elements +#define TABLE_GET_U1(table, index) table_get_u1(RESOLVE_TABLE(table), index) +#define TABLE_GET_S1(table, index) table_get_s1(RESOLVE_TABLE(table), index) +#define TABLE_GET_U2(table, index) table_get_u2(RESOLVE_TABLE(table), index) +#define TABLE_GET_S2(table, index) table_get_s2(RESOLVE_TABLE(table), index) +#define TABLE_GET_U4(table, index) table_get_u4(RESOLVE_TABLE(table), index) +#define TABLE_GET_S4(table, index) table_get_s4(RESOLVE_TABLE(table), index) +#define TABLE_GET_OSTIME(table, index) table_get_ostime(RESOLVE_TABLE(table), index) +#define TABLE_GET_U1_TWODIM(table, index1, index2) table_get_u1(RESOLVE_TABLE(table)[index1], index2) + +#if defined(__AVR__) + #include + // Macro to define the getter functions. This loads data from + // progmem using pgm_read_xx, or accesses memory directly when the + // index is a constant so gcc can optimize it away; + #define TABLE_GETTER(postfix, type, pgm_type) \ + inline type table_get ## postfix(const type *table, size_t index) { \ + if (__builtin_constant_p(table[index])) \ + return table[index]; \ + return pgm_read_ ## pgm_type(&table[index]); \ + } + + TABLE_GETTER(_u1, u1_t, byte); + TABLE_GETTER(_s1, s1_t, byte); + TABLE_GETTER(_u2, u2_t, word); + TABLE_GETTER(_s2, s2_t, word); + TABLE_GETTER(_u4, u4_t, dword); + TABLE_GETTER(_s4, s4_t, dword); + + // This assumes ostime_t is 4 bytes, so error out if it is not + typedef int check_sizeof_ostime_t[(sizeof(ostime_t) == 4) ? 0 : -1]; + TABLE_GETTER(_ostime, ostime_t, dword); + + // For AVR, store constants in PROGMEM, saving on RAM usage + #define CONST_TABLE(type, name) const type PROGMEM RESOLVE_TABLE(name) + + #define lmic_printf(fmt, ...) printf_P(PSTR(fmt), ## __VA_ARGS__) +#else + inline u1_t table_get_u1(const u1_t *table, size_t index) { return table[index]; } + inline s1_t table_get_s1(const s1_t *table, size_t index) { return table[index]; } + inline u2_t table_get_u2(const u2_t *table, size_t index) { return table[index]; } + inline s2_t table_get_s2(const s2_t *table, size_t index) { return table[index]; } + inline u4_t table_get_u4(const u4_t *table, size_t index) { return table[index]; } + inline s4_t table_get_s4(const s4_t *table, size_t index) { return table[index]; } + inline ostime_t table_get_ostime(const ostime_t *table, size_t index) { return table[index]; } + + // Declare a table + #define CONST_TABLE(type, name) const type RESOLVE_TABLE(name) + #define lmic_printf printf +#endif + +// ====================================================================== +// AES support +// !!Keep in sync with lorabase.hpp!! + +#ifndef AES_ENC // if AES_ENC is defined as macro all other values must be too +#define AES_ENC 0x00 +#define AES_DEC 0x01 +#define AES_MIC 0x02 +#define AES_CTR 0x04 +#define AES_MICNOAUX 0x08 +#endif +#ifndef AESkey // if AESkey is defined as macro all other values must be too +extern xref2u1_t AESkey; +extern xref2u1_t AESaux; +#endif +#ifndef os_aes +u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len); +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _oslmic_h_ diff --git a/libraries/IBM_LMIC_framework/src/lmic/radio.c b/libraries/IBM_LMIC_framework/src/lmic/radio.c new file mode 100644 index 0000000..c394754 --- /dev/null +++ b/libraries/IBM_LMIC_framework/src/lmic/radio.c @@ -0,0 +1,851 @@ +/******************************************************************************* + * Copyright (c) 2014-2015 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Zurich Research Lab - initial API, implementation and documentation + *******************************************************************************/ + +#include "lmic.h" + +// ---------------------------------------- +// Registers Mapping +#define RegFifo 0x00 // common +#define RegOpMode 0x01 // common +#define FSKRegBitrateMsb 0x02 +#define FSKRegBitrateLsb 0x03 +#define FSKRegFdevMsb 0x04 +#define FSKRegFdevLsb 0x05 +#define RegFrfMsb 0x06 // common +#define RegFrfMid 0x07 // common +#define RegFrfLsb 0x08 // common +#define RegPaConfig 0x09 // common +#define RegPaRamp 0x0A // common +#define RegOcp 0x0B // common +#define RegLna 0x0C // common +#define FSKRegRxConfig 0x0D +#define LORARegFifoAddrPtr 0x0D +#define FSKRegRssiConfig 0x0E +#define LORARegFifoTxBaseAddr 0x0E +#define FSKRegRssiCollision 0x0F +#define LORARegFifoRxBaseAddr 0x0F +#define FSKRegRssiThresh 0x10 +#define LORARegFifoRxCurrentAddr 0x10 +#define FSKRegRssiValue 0x11 +#define LORARegIrqFlagsMask 0x11 +#define FSKRegRxBw 0x12 +#define LORARegIrqFlags 0x12 +#define FSKRegAfcBw 0x13 +#define LORARegRxNbBytes 0x13 +#define FSKRegOokPeak 0x14 +#define LORARegRxHeaderCntValueMsb 0x14 +#define FSKRegOokFix 0x15 +#define LORARegRxHeaderCntValueLsb 0x15 +#define FSKRegOokAvg 0x16 +#define LORARegRxPacketCntValueMsb 0x16 +#define LORARegRxpacketCntValueLsb 0x17 +#define LORARegModemStat 0x18 +#define LORARegPktSnrValue 0x19 +#define FSKRegAfcFei 0x1A +#define LORARegPktRssiValue 0x1A +#define FSKRegAfcMsb 0x1B +#define LORARegRssiValue 0x1B +#define FSKRegAfcLsb 0x1C +#define LORARegHopChannel 0x1C +#define FSKRegFeiMsb 0x1D +#define LORARegModemConfig1 0x1D +#define FSKRegFeiLsb 0x1E +#define LORARegModemConfig2 0x1E +#define FSKRegPreambleDetect 0x1F +#define LORARegSymbTimeoutLsb 0x1F +#define FSKRegRxTimeout1 0x20 +#define LORARegPreambleMsb 0x20 +#define FSKRegRxTimeout2 0x21 +#define LORARegPreambleLsb 0x21 +#define FSKRegRxTimeout3 0x22 +#define LORARegPayloadLength 0x22 +#define FSKRegRxDelay 0x23 +#define LORARegPayloadMaxLength 0x23 +#define FSKRegOsc 0x24 +#define LORARegHopPeriod 0x24 +#define FSKRegPreambleMsb 0x25 +#define LORARegFifoRxByteAddr 0x25 +#define LORARegModemConfig3 0x26 +#define FSKRegPreambleLsb 0x26 +#define FSKRegSyncConfig 0x27 +#define LORARegFeiMsb 0x28 +#define FSKRegSyncValue1 0x28 +#define LORAFeiMib 0x29 +#define FSKRegSyncValue2 0x29 +#define LORARegFeiLsb 0x2A +#define FSKRegSyncValue3 0x2A +#define FSKRegSyncValue4 0x2B +#define LORARegRssiWideband 0x2C +#define FSKRegSyncValue5 0x2C +#define FSKRegSyncValue6 0x2D +#define FSKRegSyncValue7 0x2E +#define FSKRegSyncValue8 0x2F +#define FSKRegPacketConfig1 0x30 +#define FSKRegPacketConfig2 0x31 +#define LORARegDetectOptimize 0x31 +#define FSKRegPayloadLength 0x32 +#define FSKRegNodeAdrs 0x33 +#define LORARegInvertIQ 0x33 +#define FSKRegBroadcastAdrs 0x34 +#define FSKRegFifoThresh 0x35 +#define FSKRegSeqConfig1 0x36 +#define FSKRegSeqConfig2 0x37 +#define LORARegDetectionThreshold 0x37 +#define FSKRegTimerResol 0x38 +#define FSKRegTimer1Coef 0x39 +#define LORARegSyncWord 0x39 +#define FSKRegTimer2Coef 0x3A +#define FSKRegImageCal 0x3B +#define FSKRegTemp 0x3C +#define FSKRegLowBat 0x3D +#define FSKRegIrqFlags1 0x3E +#define FSKRegIrqFlags2 0x3F +#define RegDioMapping1 0x40 // common +#define RegDioMapping2 0x41 // common +#define RegVersion 0x42 // common +// #define RegAgcRef 0x43 // common +// #define RegAgcThresh1 0x44 // common +// #define RegAgcThresh2 0x45 // common +// #define RegAgcThresh3 0x46 // common +// #define RegPllHop 0x4B // common +// #define RegTcxo 0x58 // common +#define RegPaDac 0x5A // common +// #define RegPll 0x5C // common +// #define RegPllLowPn 0x5E // common +// #define RegFormerTemp 0x6C // common +// #define RegBitRateFrac 0x70 // common + +// ---------------------------------------- +// spread factors and mode for RegModemConfig2 +#define SX1272_MC2_FSK 0x00 +#define SX1272_MC2_SF7 0x70 +#define SX1272_MC2_SF8 0x80 +#define SX1272_MC2_SF9 0x90 +#define SX1272_MC2_SF10 0xA0 +#define SX1272_MC2_SF11 0xB0 +#define SX1272_MC2_SF12 0xC0 +// bandwidth for RegModemConfig1 +#define SX1272_MC1_BW_125 0x00 +#define SX1272_MC1_BW_250 0x40 +#define SX1272_MC1_BW_500 0x80 +// coding rate for RegModemConfig1 +#define SX1272_MC1_CR_4_5 0x08 +#define SX1272_MC1_CR_4_6 0x10 +#define SX1272_MC1_CR_4_7 0x18 +#define SX1272_MC1_CR_4_8 0x20 +#define SX1272_MC1_IMPLICIT_HEADER_MODE_ON 0x04 // required for receive +#define SX1272_MC1_RX_PAYLOAD_CRCON 0x02 +#define SX1272_MC1_LOW_DATA_RATE_OPTIMIZE 0x01 // mandated for SF11 and SF12 +// transmit power configuration for RegPaConfig +#define SX1272_PAC_PA_SELECT_PA_BOOST 0x80 +#define SX1272_PAC_PA_SELECT_RFIO_PIN 0x00 + + +// sx1276 RegModemConfig1 +#define SX1276_MC1_BW_125 0x70 +#define SX1276_MC1_BW_250 0x80 +#define SX1276_MC1_BW_500 0x90 +#define SX1276_MC1_CR_4_5 0x02 +#define SX1276_MC1_CR_4_6 0x04 +#define SX1276_MC1_CR_4_7 0x06 +#define SX1276_MC1_CR_4_8 0x08 + +#define SX1276_MC1_IMPLICIT_HEADER_MODE_ON 0x01 + +// sx1276 RegModemConfig2 +#define SX1276_MC2_RX_PAYLOAD_CRCON 0x04 + +// sx1276 RegModemConfig3 +#define SX1276_MC3_LOW_DATA_RATE_OPTIMIZE 0x08 +#define SX1276_MC3_AGCAUTO 0x04 + +// preamble for lora networks (nibbles swapped) +#define LORA_MAC_PREAMBLE 0x34 + +#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1 0x0A +#ifdef CFG_sx1276_radio +#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x70 +#elif CFG_sx1272_radio +#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x74 +#endif + + + +// ---------------------------------------- +// Constants for radio registers +#define OPMODE_LORA 0x80 +#define OPMODE_MASK 0x07 +#define OPMODE_SLEEP 0x00 +#define OPMODE_STANDBY 0x01 +#define OPMODE_FSTX 0x02 +#define OPMODE_TX 0x03 +#define OPMODE_FSRX 0x04 +#define OPMODE_RX 0x05 +#define OPMODE_RX_SINGLE 0x06 +#define OPMODE_CAD 0x07 + +// ---------------------------------------- +// Bits masking the corresponding IRQs from the radio +#define IRQ_LORA_RXTOUT_MASK 0x80 +#define IRQ_LORA_RXDONE_MASK 0x40 +#define IRQ_LORA_CRCERR_MASK 0x20 +#define IRQ_LORA_HEADER_MASK 0x10 +#define IRQ_LORA_TXDONE_MASK 0x08 +#define IRQ_LORA_CDDONE_MASK 0x04 +#define IRQ_LORA_FHSSCH_MASK 0x02 +#define IRQ_LORA_CDDETD_MASK 0x01 + +#define IRQ_FSK1_MODEREADY_MASK 0x80 +#define IRQ_FSK1_RXREADY_MASK 0x40 +#define IRQ_FSK1_TXREADY_MASK 0x20 +#define IRQ_FSK1_PLLLOCK_MASK 0x10 +#define IRQ_FSK1_RSSI_MASK 0x08 +#define IRQ_FSK1_TIMEOUT_MASK 0x04 +#define IRQ_FSK1_PREAMBLEDETECT_MASK 0x02 +#define IRQ_FSK1_SYNCADDRESSMATCH_MASK 0x01 +#define IRQ_FSK2_FIFOFULL_MASK 0x80 +#define IRQ_FSK2_FIFOEMPTY_MASK 0x40 +#define IRQ_FSK2_FIFOLEVEL_MASK 0x20 +#define IRQ_FSK2_FIFOOVERRUN_MASK 0x10 +#define IRQ_FSK2_PACKETSENT_MASK 0x08 +#define IRQ_FSK2_PAYLOADREADY_MASK 0x04 +#define IRQ_FSK2_CRCOK_MASK 0x02 +#define IRQ_FSK2_LOWBAT_MASK 0x01 + +// ---------------------------------------- +// DIO function mappings D0D1D2D3 +#define MAP_DIO0_LORA_RXDONE 0x00 // 00------ +#define MAP_DIO0_LORA_TXDONE 0x40 // 01------ +#define MAP_DIO1_LORA_RXTOUT 0x00 // --00---- +#define MAP_DIO1_LORA_NOP 0x30 // --11---- +#define MAP_DIO2_LORA_NOP 0xC0 // ----11-- + +#define MAP_DIO0_FSK_READY 0x00 // 00------ (packet sent / payload ready) +#define MAP_DIO1_FSK_NOP 0x30 // --11---- +#define MAP_DIO2_FSK_TXNOP 0x04 // ----01-- +#define MAP_DIO2_FSK_TIMEOUT 0x08 // ----10-- + + +// FSK IMAGECAL defines +#define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F +#define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 +#define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default + +#define RF_IMAGECAL_IMAGECAL_MASK 0xBF +#define RF_IMAGECAL_IMAGECAL_START 0x40 + +#define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 +#define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default + + +// RADIO STATE +// (initialized by radio_init(), used by radio_rand1()) +static u1_t randbuf[16]; + + +#ifdef CFG_sx1276_radio +#define LNA_RX_GAIN (0x20|0x1) +#elif CFG_sx1272_radio +#define LNA_RX_GAIN (0x20|0x03) +#else +#error Missing CFG_sx1272_radio/CFG_sx1276_radio +#endif + + +static void writeReg (u1_t addr, u1_t data ) { + hal_pin_nss(0); + hal_spi(addr | 0x80); + hal_spi(data); + hal_pin_nss(1); +} + +static u1_t readReg (u1_t addr) { + hal_pin_nss(0); + hal_spi(addr & 0x7F); + u1_t val = hal_spi(0x00); + hal_pin_nss(1); + return val; +} + +static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) { + hal_pin_nss(0); + hal_spi(addr | 0x80); + for (u1_t i=0; i>16)); + writeReg(RegFrfMid, (u1_t)(frf>> 8)); + writeReg(RegFrfLsb, (u1_t)(frf>> 0)); +} + + + +static void configPower () { +#ifdef CFG_sx1276_radio + // no boost used for now + s1_t pw = (s1_t)LMIC.txpow; + if(pw >= 17) { + pw = 15; + } else if(pw < 2) { + pw = 2; + } + // check board type for BOOST pin + writeReg(RegPaConfig, (u1_t)(0x80|(pw&0xf))); + writeReg(RegPaDac, readReg(RegPaDac)|0x4); + +#elif CFG_sx1272_radio + // set PA config (2-17 dBm using PA_BOOST) + s1_t pw = (s1_t)LMIC.txpow; + if(pw > 17) { + pw = 17; + } else if(pw < 2) { + pw = 2; + } + writeReg(RegPaConfig, (u1_t)(0x80|(pw-2))); +#else +#error Missing CFG_sx1272_radio/CFG_sx1276_radio +#endif /* CFG_sx1272_radio */ +} + +static void txfsk () { + // select FSK modem (from sleep mode) + writeReg(RegOpMode, 0x10); // FSK, BT=0.5 + ASSERT(readReg(RegOpMode) == 0x10); + // enter standby mode (required for FIFO loading)) + opmode(OPMODE_STANDBY); + // set bitrate + writeReg(FSKRegBitrateMsb, 0x02); // 50kbps + writeReg(FSKRegBitrateLsb, 0x80); + // set frequency deviation + writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz + writeReg(FSKRegFdevLsb, 0x99); + // frame and packet handler settings + writeReg(FSKRegPreambleMsb, 0x00); + writeReg(FSKRegPreambleLsb, 0x05); + writeReg(FSKRegSyncConfig, 0x12); + writeReg(FSKRegPacketConfig1, 0xD0); + writeReg(FSKRegPacketConfig2, 0x40); + writeReg(FSKRegSyncValue1, 0xC1); + writeReg(FSKRegSyncValue2, 0x94); + writeReg(FSKRegSyncValue3, 0xC1); + // configure frequency + configChannel(); + // configure output power + configPower(); + + // set the IRQ mapping DIO0=PacketSent DIO1=NOP DIO2=NOP + writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TXNOP); + + // initialize the payload size and address pointers + writeReg(FSKRegPayloadLength, LMIC.dataLen+1); // (insert length byte into payload)) + + // download length byte and buffer to the radio FIFO + writeReg(RegFifo, LMIC.dataLen); + writeBuf(RegFifo, LMIC.frame, LMIC.dataLen); + + // enable antenna switch for TX + hal_pin_rxtx(1); + + // now we actually start the transmission + opmode(OPMODE_TX); +} + +static void txlora () { + // select LoRa modem (from sleep mode) + //writeReg(RegOpMode, OPMODE_LORA); + opmodeLora(); + ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0); + + // enter standby mode (required for FIFO loading)) + opmode(OPMODE_STANDBY); + // configure LoRa modem (cfg1, cfg2) + configLoraModem(); + // configure frequency + configChannel(); + // configure output power + writeReg(RegPaRamp, (readReg(RegPaRamp) & 0xF0) | 0x08); // set PA ramp-up time 50 uSec + configPower(); + // set sync word + writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE); + + // set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP + writeReg(RegDioMapping1, MAP_DIO0_LORA_TXDONE|MAP_DIO1_LORA_NOP|MAP_DIO2_LORA_NOP); + // clear all radio IRQ flags + writeReg(LORARegIrqFlags, 0xFF); + // mask all IRQs but TxDone + writeReg(LORARegIrqFlagsMask, ~IRQ_LORA_TXDONE_MASK); + + // initialize the payload size and address pointers + writeReg(LORARegFifoTxBaseAddr, 0x00); + writeReg(LORARegFifoAddrPtr, 0x00); + writeReg(LORARegPayloadLength, LMIC.dataLen); + + // download buffer to the radio FIFO + writeBuf(RegFifo, LMIC.frame, LMIC.dataLen); + + // enable antenna switch for TX + hal_pin_rxtx(1); + + // now we actually start the transmission + opmode(OPMODE_TX); + +#if LMIC_DEBUG_LEVEL > 0 + u1_t sf = getSf(LMIC.rps) + 6; // 1 == SF7 + u1_t bw = getBw(LMIC.rps); + u1_t cr = getCr(LMIC.rps); + lmic_printf("%lu: TXMODE, freq=%lu, len=%d, SF=%d, BW=%d, CR=4/%d, IH=%d\n", + os_getTime(), LMIC.freq, LMIC.dataLen, sf, + bw == BW125 ? 125 : (bw == BW250 ? 250 : 500), + cr == CR_4_5 ? 5 : (cr == CR_4_6 ? 6 : (cr == CR_4_7 ? 7 : 8)), + getIh(LMIC.rps) + ); +#endif +} + +// start transmitter (buf=LMIC.frame, len=LMIC.dataLen) +static void starttx () { + ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP ); + if(getSf(LMIC.rps) == FSK) { // FSK modem + txfsk(); + } else { // LoRa modem + txlora(); + } + // the radio will go back to STANDBY mode as soon as the TX is finished + // the corresponding IRQ will inform us about completion. +} + +enum { RXMODE_SINGLE, RXMODE_SCAN, RXMODE_RSSI }; + +static CONST_TABLE(u1_t, rxlorairqmask)[] = { + [RXMODE_SINGLE] = IRQ_LORA_RXDONE_MASK|IRQ_LORA_RXTOUT_MASK, + [RXMODE_SCAN] = IRQ_LORA_RXDONE_MASK, + [RXMODE_RSSI] = 0x00, +}; + +// start LoRa receiver (time=LMIC.rxtime, timeout=LMIC.rxsyms, result=LMIC.frame[LMIC.dataLen]) +static void rxlora (u1_t rxmode) { + // select LoRa modem (from sleep mode) + opmodeLora(); + ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0); + // enter standby mode (warm up)) + opmode(OPMODE_STANDBY); + // don't use MAC settings at startup + if(rxmode == RXMODE_RSSI) { // use fixed settings for rssi scan + writeReg(LORARegModemConfig1, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1); + writeReg(LORARegModemConfig2, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2); + } else { // single or continuous rx mode + // configure LoRa modem (cfg1, cfg2) + configLoraModem(); + // configure frequency + configChannel(); + } + // set LNA gain + writeReg(RegLna, LNA_RX_GAIN); + // set max payload size + writeReg(LORARegPayloadMaxLength, 64); +#if !defined(DISABLE_INVERT_IQ_ON_RX) + // use inverted I/Q signal (prevent mote-to-mote communication) + writeReg(LORARegInvertIQ, readReg(LORARegInvertIQ)|(1<<6)); +#endif + // set symbol timeout (for single rx) + writeReg(LORARegSymbTimeoutLsb, LMIC.rxsyms); + // set sync word + writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE); + + // configure DIO mapping DIO0=RxDone DIO1=RxTout DIO2=NOP + writeReg(RegDioMapping1, MAP_DIO0_LORA_RXDONE|MAP_DIO1_LORA_RXTOUT|MAP_DIO2_LORA_NOP); + // clear all radio IRQ flags + writeReg(LORARegIrqFlags, 0xFF); + // enable required radio IRQs + writeReg(LORARegIrqFlagsMask, ~TABLE_GET_U1(rxlorairqmask, rxmode)); + + // enable antenna switch for RX + hal_pin_rxtx(0); + + // now instruct the radio to receive + if (rxmode == RXMODE_SINGLE) { // single rx + hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time + opmode(OPMODE_RX_SINGLE); + } else { // continous rx (scan or rssi) + opmode(OPMODE_RX); + } + +#if LMIC_DEBUG_LEVEL > 0 + if (rxmode == RXMODE_RSSI) { + lmic_printf("RXMODE_RSSI\n"); + } else { + u1_t sf = getSf(LMIC.rps) + 6; // 1 == SF7 + u1_t bw = getBw(LMIC.rps); + u1_t cr = getCr(LMIC.rps); + lmic_printf("%lu: %s, freq=%lu, SF=%d, BW=%d, CR=4/%d, IH=%d\n", + os_getTime(), + rxmode == RXMODE_SINGLE ? "RXMODE_SINGLE" : (rxmode == RXMODE_SCAN ? "RXMODE_SCAN" : "UNKNOWN_RX"), + LMIC.freq, sf, + bw == BW125 ? 125 : (bw == BW250 ? 250 : 500), + cr == CR_4_5 ? 5 : (cr == CR_4_6 ? 6 : (cr == CR_4_7 ? 7 : 8)), + getIh(LMIC.rps) + ); + } +#endif +} + +static void rxfsk (u1_t rxmode) { + // only single rx (no continuous scanning, no noise sampling) + ASSERT( rxmode == RXMODE_SINGLE ); + // select FSK modem (from sleep mode) + //writeReg(RegOpMode, 0x00); // (not LoRa) + opmodeFSK(); + ASSERT((readReg(RegOpMode) & OPMODE_LORA) == 0); + // enter standby mode (warm up)) + opmode(OPMODE_STANDBY); + // configure frequency + configChannel(); + // set LNA gain + //writeReg(RegLna, 0x20|0x03); // max gain, boost enable + writeReg(RegLna, LNA_RX_GAIN); + // configure receiver + writeReg(FSKRegRxConfig, 0x1E); // AFC auto, AGC, trigger on preamble?!? + // set receiver bandwidth + writeReg(FSKRegRxBw, 0x0B); // 50kHz SSb + // set AFC bandwidth + writeReg(FSKRegAfcBw, 0x12); // 83.3kHz SSB + // set preamble detection + writeReg(FSKRegPreambleDetect, 0xAA); // enable, 2 bytes, 10 chip errors + // set sync config + writeReg(FSKRegSyncConfig, 0x12); // no auto restart, preamble 0xAA, enable, fill FIFO, 3 bytes sync + // set packet config + writeReg(FSKRegPacketConfig1, 0xD8); // var-length, whitening, crc, no auto-clear, no adr filter + writeReg(FSKRegPacketConfig2, 0x40); // packet mode + // set sync value + writeReg(FSKRegSyncValue1, 0xC1); + writeReg(FSKRegSyncValue2, 0x94); + writeReg(FSKRegSyncValue3, 0xC1); + // set preamble timeout + writeReg(FSKRegRxTimeout2, 0xFF);//(LMIC.rxsyms+1)/2); + // set bitrate + writeReg(FSKRegBitrateMsb, 0x02); // 50kbps + writeReg(FSKRegBitrateLsb, 0x80); + // set frequency deviation + writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz + writeReg(FSKRegFdevLsb, 0x99); + + // configure DIO mapping DIO0=PayloadReady DIO1=NOP DIO2=TimeOut + writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TIMEOUT); + + // enable antenna switch for RX + hal_pin_rxtx(0); + + // now instruct the radio to receive + hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time + opmode(OPMODE_RX); // no single rx mode available in FSK +} + +static void startrx (u1_t rxmode) { + ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP ); + if(getSf(LMIC.rps) == FSK) { // FSK modem + rxfsk(rxmode); + } else { // LoRa modem + rxlora(rxmode); + } + // the radio will go back to STANDBY mode as soon as the RX is finished + // or timed out, and the corresponding IRQ will inform us about completion. +} + +// get random seed from wideband noise rssi +void radio_init () { + hal_disableIRQs(); + + // manually reset radio +#ifdef CFG_sx1276_radio + hal_pin_rst(0); // drive RST pin low +#else + hal_pin_rst(1); // drive RST pin high +#endif + hal_waitUntil(os_getTime()+ms2osticks(1)); // wait >100us + hal_pin_rst(2); // configure RST pin floating! + hal_waitUntil(os_getTime()+ms2osticks(5)); // wait 5ms + + opmode(OPMODE_SLEEP); + + // some sanity checks, e.g., read version number + u1_t v = readReg(RegVersion); +#ifdef CFG_sx1276_radio + ASSERT(v == 0x12 ); +#elif CFG_sx1272_radio + ASSERT(v == 0x22); +#else +#error Missing CFG_sx1272_radio/CFG_sx1276_radio +#endif + // seed 15-byte randomness via noise rssi + rxlora(RXMODE_RSSI); + while( (readReg(RegOpMode) & OPMODE_MASK) != OPMODE_RX ); // continuous rx + for(int i=1; i<16; i++) { + for(int j=0; j<8; j++) { + u1_t b; // wait for two non-identical subsequent least-significant bits + while( (b = readReg(LORARegRssiWideband) & 0x01) == (readReg(LORARegRssiWideband) & 0x01) ); + randbuf[i] = (randbuf[i] << 1) | b; + } + } + randbuf[0] = 16; // set initial index + +#ifdef CFG_sx1276mb1_board + // chain calibration + writeReg(RegPaConfig, 0); + + // Launch Rx chain calibration for LF band + writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START); + while((readReg(FSKRegImageCal)&RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING){ ; } + + // Sets a Frequency in HF band + u4_t frf = 868000000; + writeReg(RegFrfMsb, (u1_t)(frf>>16)); + writeReg(RegFrfMid, (u1_t)(frf>> 8)); + writeReg(RegFrfLsb, (u1_t)(frf>> 0)); + + // Launch Rx chain calibration for HF band + writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START); + while((readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING) { ; } +#endif /* CFG_sx1276mb1_board */ + + opmode(OPMODE_SLEEP); + + hal_enableIRQs(); +} + +// return next random byte derived from seed buffer +// (buf[0] holds index of next byte to be returned) +u1_t radio_rand1 () { + u1_t i = randbuf[0]; + ASSERT( i != 0 ); + if( i==16 ) { + os_aes(AES_ENC, randbuf, 16); // encrypt seed with any key + i = 0; + } + u1_t v = randbuf[i++]; + randbuf[0] = i; + return v; +} + +u1_t radio_rssi () { + hal_disableIRQs(); + u1_t r = readReg(LORARegRssiValue); + hal_enableIRQs(); + return r; +} + +static CONST_TABLE(u2_t, LORA_RXDONE_FIXUP)[] = { + [FSK] = us2osticks(0), // ( 0 ticks) + [SF7] = us2osticks(0), // ( 0 ticks) + [SF8] = us2osticks(1648), // ( 54 ticks) + [SF9] = us2osticks(3265), // ( 107 ticks) + [SF10] = us2osticks(7049), // ( 231 ticks) + [SF11] = us2osticks(13641), // ( 447 ticks) + [SF12] = us2osticks(31189), // (1022 ticks) +}; + +// called by hal ext IRQ handler +// (radio goes to stanby mode after tx/rx operations) +void radio_irq_handler (u1_t dio) { + ostime_t now = os_getTime(); + if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem + u1_t flags = readReg(LORARegIrqFlags); +#if LMIC_DEBUG_LEVEL > 1 + lmic_printf("%lu: irq: dio: 0x%x flags: 0x%x\n", now, dio, flags); +#endif + if( flags & IRQ_LORA_TXDONE_MASK ) { + // save exact tx time + LMIC.txend = now - us2osticks(43); // TXDONE FIXUP + } else if( flags & IRQ_LORA_RXDONE_MASK ) { + // save exact rx time + if(getBw(LMIC.rps) == BW125) { + now -= TABLE_GET_U2(LORA_RXDONE_FIXUP, getSf(LMIC.rps)); + } + LMIC.rxtime = now; + // read the PDU and inform the MAC that we received something + LMIC.dataLen = (readReg(LORARegModemConfig1) & SX1272_MC1_IMPLICIT_HEADER_MODE_ON) ? + readReg(LORARegPayloadLength) : readReg(LORARegRxNbBytes); + // set FIFO read address pointer + writeReg(LORARegFifoAddrPtr, readReg(LORARegFifoRxCurrentAddr)); + // now read the FIFO + readBuf(RegFifo, LMIC.frame, LMIC.dataLen); + // read rx quality parameters + LMIC.snr = readReg(LORARegPktSnrValue); // SNR [dB] * 4 + LMIC.rssi = readReg(LORARegPktRssiValue) - 125 + 64; // RSSI [dBm] (-196...+63) + } else if( flags & IRQ_LORA_RXTOUT_MASK ) { + // indicate timeout + LMIC.dataLen = 0; + } + // mask all radio IRQs + writeReg(LORARegIrqFlagsMask, 0xFF); + // clear radio IRQ flags + writeReg(LORARegIrqFlags, 0xFF); + } else { // FSK modem + u1_t flags1 = readReg(FSKRegIrqFlags1); + u1_t flags2 = readReg(FSKRegIrqFlags2); + if( flags2 & IRQ_FSK2_PACKETSENT_MASK ) { + // save exact tx time + LMIC.txend = now; + } else if( flags2 & IRQ_FSK2_PAYLOADREADY_MASK ) { + // save exact rx time + LMIC.rxtime = now; + // read the PDU and inform the MAC that we received something + LMIC.dataLen = readReg(FSKRegPayloadLength); + // now read the FIFO + readBuf(RegFifo, LMIC.frame, LMIC.dataLen); + // read rx quality parameters + LMIC.snr = 0; // determine snr + LMIC.rssi = 0; // determine rssi + } else if( flags1 & IRQ_FSK1_TIMEOUT_MASK ) { + // indicate timeout + LMIC.dataLen = 0; + } else { + ASSERT(0); + } + } + // go from stanby to sleep + opmode(OPMODE_SLEEP); + // run os job (use preset func ptr) + os_setCallback(&LMIC.osjob, LMIC.osjob.func); +} + +void os_radio (u1_t mode) { + hal_disableIRQs(); + switch (mode) { + case RADIO_RST: + // put radio to sleep + opmode(OPMODE_SLEEP); + break; + + case RADIO_TX: + // transmit frame now + starttx(); // buf=LMIC.frame, len=LMIC.dataLen + break; + + case RADIO_RX: + // receive frame now (exactly at rxtime) + startrx(RXMODE_SINGLE); // buf=LMIC.frame, time=LMIC.rxtime, timeout=LMIC.rxsyms + break; + + case RADIO_RXON: + // start scanning for beacon now + startrx(RXMODE_SCAN); // buf=LMIC.frame + break; + } + hal_enableIRQs(); +} diff --git a/libraries/Lora_Serialization/Brewfile b/libraries/Lora_Serialization/Brewfile new file mode 100644 index 0000000..4229f70 --- /dev/null +++ b/libraries/Lora_Serialization/Brewfile @@ -0,0 +1 @@ +brew 'lcov' diff --git a/libraries/Lora_Serialization/LICENSE b/libraries/Lora_Serialization/LICENSE new file mode 100644 index 0000000..2ed91e0 --- /dev/null +++ b/libraries/Lora_Serialization/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Joscha Feth + +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. diff --git a/libraries/Lora_Serialization/README.md b/libraries/Lora_Serialization/README.md new file mode 100644 index 0000000..861b0c6 --- /dev/null +++ b/libraries/Lora_Serialization/README.md @@ -0,0 +1,307 @@ +# LoRaWAN serialization/deserialization library for The Things Network + +[![Build Status](https://travis-ci.org/thesolarnomad/lora-serialization.svg?branch=master)](https://travis-ci.org/thesolarnomad/lora-serialization) +[![Coverage Status](https://coveralls.io/repos/github/thesolarnomad/lora-serialization/badge.svg?branch=master)](https://coveralls.io/github/thesolarnomad/lora-serialization?branch=master) +[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) + +This fully unit-tested library allows you to encode your data on the Arduino side and decode it on the [TTN](https://console.thethingsnetwork.org/) side. It provides both a C-based encoder and a JavaScript-based decoder. + +Since version 2.2.0 there is also an encoder for the TTN side. + +## In short + +### Encoding on Arduino, decoding in TTN +Arduino side: +```cpp +#include "LoraMessage.h" + +LoraMessage message; + +message + .addUnixtime(1467632413) + .addLatLng(-33.905052, 151.26641); + +lora_send_bytes(message.getBytes(), message.getLength()); +delete message; +``` +TTN side: +```javascript +// include src/decoder.js +var json = decode(bytes, [unixtime, latLng], ['time', 'coords']); +// json == {time: unixtime, coords: [latitude, longitude]} +``` + +### Encoding in TTN +TTN side: +```javascript +// include src/encoder.js +var bytes = encode([timestamp, [latitude, longitude]], [unixtime, latLng]); +// bytes is of type Buffer +``` + + +#### With the convenience class + +```javascript +// include src/encoder.js +// include src/LoraMessage.js +var bytes = new LoraMessage(encoder) + .addUnixtime(1467632413) + .addLatLng(-33.905052, 151.26641) + .addBitmap(true, true, false, true) + .getBytes(); +// bytes = +``` + +and then decoding as usual: + +```js +var result = decoder.decode( + bytes, + [decoder.unixtime, decoder.latLng, decoder.bitmap], + ['time', 'coords', 'heaters'] +); +// result = +// { time: 1467632413, +// coords: [ -33.905052, 151.26641 ], +// heaters: +// { a: true, +// b: true, +// c: false, +// d: true, +// e: false, +// f: false, +// g: false, +// h: false } } +``` + +## General Usage + +### Unix time (4 bytes) +Serializes/deserializes a unix time (seconds) + +```cpp +#include "LoraEncoder.h" + +byte buffer[4]; +LoraEncoder encoder(buffer); +encoder.writeUnixtime(1467632413); +// buffer == {0x1d, 0x4b, 0x7a, 0x57} +``` +and then in the TTN frontend, use the following method: + +```javascript +unixtime(bytes.slice(x, x + 4)) // 1467632413 +``` + +### GPS coordinates (8 bytes) +Serializes/deserializes coordinates (latitude/longitude) with a precision of 6 decimals. + +```cpp +#include "LoraEncoder.h" + +byte buffer[8]; +LoraEncoder encoder(buffer); +encoder.writeLatLng(-33.905052, 151.26641); +// buffer == {0x64, 0xa6, 0xfa, 0xfd, 0x6a, 0x24, 0x04, 0x09} +``` +and then in the TTN frontend, use the following method: + +```javascript +latLng(bytes.slice(x, x + 8)) // [-33.905052, 151.26641] +``` + +### Unsigned 8bit Integer (1 byte) +Serializes/deserializes an unsigned 8bit integer. + +```cpp +#include "LoraEncoder.h" + +byte buffer[1]; +LoraEncoder encoder(buffer); +uint8_t i = 10; +encoder.writeUint8(i); +// buffer == {0x0A} +``` +and then in the TTN frontend, use the following method: + +```javascript +uint8(bytes.slice(x, x + 1)) // 10 +``` + +### Unsigned 16bit Integer (2 bytes) +Serializes/deserializes an unsigned 16bit integer. + +```cpp +#include "LoraEncoder.h" + +byte buffer[2]; +LoraEncoder encoder(buffer); +uint16_t i = 23453; +encoder.writeUint16(i); +// buffer == {0x9d, 0x5b} +``` +and then in the TTN frontend, use the following method: + +```javascript +uint16(bytes.slice(x, x + 2)) // 23453 +``` + +### Temperature (2 bytes) +Serializes/deserializes a temperature reading between -327.68 and +327.67 (inclusive) with a precision of 2 decimals. + +```cpp +#include "LoraEncoder.h" + +byte buffer[2]; +LoraEncoder encoder(buffer); +encoder.writeTemperature(-123.45); +// buffer == {0xcf, 0xc7} +``` +and then in the TTN frontend, use the following method: + +```javascript +temperature(bytes.slice(x, x + 2)) // -123.45 +``` + +### Humidity (2 bytes) +Serializes/deserializes a humidity reading between 0 and 100 (inclusive) with a precision of 2 decimals. + +```cpp +#include "LoraEncoder.h" + +byte buffer[2]; +LoraEncoder encoder(buffer); +encoder.writeHumidity(99.99); +// buffer == {0x0f, 0x27} +``` +and then in the TTN frontend, use the following method: + +```javascript +humidity(bytes.slice(x, x + 2)) // 99.99 +``` + +### Bitmap (1 byte) +Serializes/deserializes a bitmap containing between 0 and 8 different flags. + +```cpp +#include "LoraEncoder.h" + +byte buffer[1]; +LoraEncoder encoder(buffer); +encoder.writeBitmap(true, false, false, false, false, false, false, false); +// buffer == {0x80} +``` +and then in the TTN frontend, use the following method: + +```javascript +bitmap(bytes.slice(x, x + 1)) // { a: true, b: false, c: false, d: false, e: false, f: false, g: false, h: false } +``` + +## Composition + +### On the Arduino side +The decoder allows you to write more than one value to a byte array: +```cpp +#include "LoraEncoder.h" + +byte buffer[19]; +LoraEncoder encoder(buffer); + +encoder.writeUnixtime(1467632413); +encoder.writeLatLng(-33.905052, 151.26641); +encoder.writeUint8(10); +encoder.writeUint16(23453); +encoder.writeTemperature(80.12); +encoder.writeHumidity(99.99); +encoder.writeBitmap(true, false, false, false, false, false, false, false); +/* buffer == { + 0x1d, 0x4b, 0x7a, 0x57, // Unixtime + 0x64, 0xa6, 0xfa, 0xfd, 0x6a, 0x24, 0x04, 0x09, // latitude,longitude + 0x0A, // Uint8 + 0x9d, 0x5b, // Uint16 + 0x1f, 0x4c, // temperature + 0x0f, 0x27, // humidity + 0x80 // bitmap +} +*/ +``` + +#### Convenience class `LoraMessage` +There is a convenience class that represents a LoraMessage that you can add readings to: +```cpp +#include "LoraMessage.h" + +LoraMessage message; + +message + .addUnixtime(1467632413) + .addLatLng(-33.905052, 151.26641) + .addUint8(10) + .addUint16(23453) + .addTemperature(80.12) + .addHumidity(99.99) + .addBitmap(false, false, false, false, false, false, true, false); + +send(message.getBytes(), message.getLength()); +/* +getBytes() == { + 0x1d, 0x4b, 0x7a, 0x57, // Unixtime + 0x64, 0xa6, 0xfa, 0xfd, 0x6a, 0x24, 0x04, 0x09, // latitude,longitude + 0x0A, // Uint8 + 0x9d, 0x5b, // Uint16 + 0x1f, 0x4c, // temperature + 0x0f, 0x27, // humidity + 0xfd // Bitmap +} +and +getLength() == 20 +*/ +``` + +### Composition in the TTN decoder frontend with the `decode` method + +The `decode` method allows you to specify a mask for the incoming byte buffer (that was generated by this library) and apply decoding functions accordingly. + +```javascript +decode(byte Array, mask Array [,mapping Array]) +``` + +#### Example +Paste everything from `src/decoder.js` into the decoder method and use like this: + +```javascript +function (bytes) { + // code from src/decoder.js here + return decode(bytes, [latLng, unixtime], ['coords', 'time']); +} +``` +This maps the incoming byte buffer of 12 bytes to a sequence of one `latLng` (8 bytes) and one `unixtime` (4 bytes) sequence and maps the first one to a key `coords` and the second to a key `time`. + +You can use: `64 A6 FA FD 6A 24 04 09 1D 4B 7A 57` for testing, and it will result in: + +```json +{ + "coords": [ + -33.905052, + 151.26641 + ], + "time": 1467632413 +} +``` +##### Example decoder in the TTN console +Set up your decoder in the console: +![TTN console decoder example](https://cloud.githubusercontent.com/assets/188038/23703580/c136cc90-0454-11e7-9570-ae137136d7b5.png) + +##### Example converter in the TTN console +The decode method already does most of the necessary transformations, so in most cases you can just pass the data through: +![TTN console converter example](https://cloud.githubusercontent.com/assets/188038/23703587/c99021c0-0454-11e7-8670-9f77472a111d.png) + +## Development + +* Install the dependencies via `yarn` +* Run the unit tests (C) via `yarn run test:c` +* Run the unit tests (JavaScript) via `yarn test` +* Check the coverage (JavaScript) via `yarn coverage` (see `coverage/lcov-report`) + +The CI will kick off once you create a pull request automatically. diff --git a/libraries/Lora_Serialization/example/.eslintrc b/libraries/Lora_Serialization/example/.eslintrc new file mode 100644 index 0000000..9de2e37 --- /dev/null +++ b/libraries/Lora_Serialization/example/.eslintrc @@ -0,0 +1,17 @@ +{ + "extends": "../.eslintrc.js", + "rules": { + "no-unused-vars": 0 + }, + "globals": { + "encode": false, + "decode": false, + "LoraMessage": false, + "unixtime": false, + "latLng": false, + "uint16": false, + "uint8": false, + "temperature": false, + "humidity": false, + } +} diff --git a/libraries/Lora_Serialization/example/main_encoder.ino b/libraries/Lora_Serialization/example/main_encoder.ino new file mode 100644 index 0000000..3753d51 --- /dev/null +++ b/libraries/Lora_Serialization/example/main_encoder.ino @@ -0,0 +1,15 @@ +#include + +byte mydata[12]; + +void setup() { + LoraEncoder encoder(mydata); + encoder.writeUnixtime(1468075322); + encoder.writeLatLng(-33.905024, 151.26648); + + do_send(&sendjob); +} + +void loop(void) { + os_runloop_once(); +} diff --git a/libraries/Lora_Serialization/example/main_encoder_LoraMessage.ino b/libraries/Lora_Serialization/example/main_encoder_LoraMessage.ino new file mode 100644 index 0000000..98e5b5d --- /dev/null +++ b/libraries/Lora_Serialization/example/main_encoder_LoraMessage.ino @@ -0,0 +1,13 @@ +#include + +void setup() { + LoraMessage message; + message.addUnixtime(1468075322); + message.addLatLng(-33.905024, 151.26648); + + do_send(message.getLength(), message.getBytes()); +} + +void loop(void) { + os_runloop_once(); +} diff --git a/libraries/Lora_Serialization/example/ttn_decoder.js b/libraries/Lora_Serialization/example/ttn_decoder.js new file mode 100644 index 0000000..d296d65 --- /dev/null +++ b/libraries/Lora_Serialization/example/ttn_decoder.js @@ -0,0 +1,11 @@ +function ttn_decoder(bytes) { + // bytes is of type Buffer + + // IMPORTANT: paste code from src/decoder.js here + + return decode( + bytes, + [ unixtime, latLng ], + [ 'timestamp', 'coords' ] + ); +} diff --git a/libraries/Lora_Serialization/example/ttn_encoder.js b/libraries/Lora_Serialization/example/ttn_encoder.js new file mode 100644 index 0000000..7361d96 --- /dev/null +++ b/libraries/Lora_Serialization/example/ttn_encoder.js @@ -0,0 +1,8 @@ +function ttn_encoder() { + // IMPORTANT: paste code from src/encoder.js here + + return encode( + [ Date.now() / 1000, [-33.905052, 151.26641] ], + [ unixtime, latLng ] + ); +} diff --git a/libraries/Lora_Serialization/example/ttn_encoder_LoraMessage.js b/libraries/Lora_Serialization/example/ttn_encoder_LoraMessage.js new file mode 100644 index 0000000..31d8610 --- /dev/null +++ b/libraries/Lora_Serialization/example/ttn_encoder_LoraMessage.js @@ -0,0 +1,8 @@ +function ttn_encoder() { + // IMPORTANT: paste code from src/encoder.js here + // IMPORTANT: paste code from src/LoraMessage.js here + + return new LoraMessage() + .addUnixtime(Date.now() / 1000) + .addLatLng(-33.905052, 151.26641); +} diff --git a/libraries/Lora_Serialization/library.properties b/libraries/Lora_Serialization/library.properties new file mode 100644 index 0000000..459c5b0 --- /dev/null +++ b/libraries/Lora_Serialization/library.properties @@ -0,0 +1,9 @@ +name=LoRa Serialization +version=3.0.0 +author=Joscha Feth +maintainer=Joscha Feth +sentence=Library for serialization of data on the Arduino side and deserialization in the TTN +paragraph= +category=Data Processing +url=https://github.com/thesolarnomad/lora-serialization +architectures=* diff --git a/libraries/Lora_Serialization/package.json b/libraries/Lora_Serialization/package.json new file mode 100644 index 0000000..6b48416 --- /dev/null +++ b/libraries/Lora_Serialization/package.json @@ -0,0 +1,54 @@ +{ + "name": "lora-serialization", + "version": "0.0.0-development", + "description": "LoraWAN serialization/deserialization library for The Things Network", + "main": "src/index.js", + "directories": { + "test": "test" + }, + "repository": { + "type": "git", + "url": "https://github.com/thesolarnomad/lora-serialization" + }, + "scripts": { + "coverage": "nyc report --reporter=lcov", + "coveralls": "lcov-result-merger 'coverage/*.info' | coveralls", + "lint": "eslint .", + "test": "nyc ava", + "test:watch": "ava --watch", + "test:c": "./.ci/run_c_tests.sh", + "semantic-release": "semantic-release pre && npm publish && semantic-release post" + }, + "keywords": [ + "lora", + "lorawan", + "ttn", + "thethingsnetwork", + "arduino", + "serialization", + "deserialization", + "cpp" + ], + "author": "Joscha Feth ", + "license": "MIT", + "devDependencies": { + "ava": "^0.18.2", + "coveralls": "^2.11.16", + "cz-conventional-changelog": "^2.0.0", + "eslint": "^3.0.1", + "lcov-result-merger": "^1.2.0", + "nyc": "^10.1.2", + "semantic-release": "^6.3.6" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + }, + "ava": { + "files": [ + "test/**/*.js", + "!test/base.js" + ] + } +} diff --git a/libraries/Lora_Serialization/src/LoraEncoder.cpp b/libraries/Lora_Serialization/src/LoraEncoder.cpp new file mode 100644 index 0000000..f8f4909 --- /dev/null +++ b/libraries/Lora_Serialization/src/LoraEncoder.cpp @@ -0,0 +1,99 @@ +/* + LoraEncoder.cpp - Base class for the Lora serialization library + + The MIT License (MIT) + + Copyright (c) 2016 Joscha Feth + + 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. +*/ + +#if ARDUINO >= 100 + #include "Arduino.h" +#endif +#include "LoraEncoder.h" + +LoraEncoder::LoraEncoder(byte *buffer) { + _buffer = buffer; +} + +void LoraEncoder::_intToBytes(byte *buf, int32_t i, uint8_t byteSize) { + for(uint8_t x = 0; x < byteSize; x++) { + buf[x] = (byte) (i >> (x*8)); + } +} + +void LoraEncoder::writeUnixtime(uint32_t unixtime) { + _intToBytes(_buffer, unixtime, 4); + _buffer += 4; +} + +void LoraEncoder::writeLatLng(double latitude, double longitude) { + int32_t lat = latitude * 1e6; + int32_t lng = longitude * 1e6; + + _intToBytes(_buffer, lat, 4); + _intToBytes(_buffer + 4, lng, 4); + _buffer += 8; +} + +void LoraEncoder::writeUint16(uint16_t i) { + _intToBytes(_buffer, i, 2); + _buffer += 2; +} + +void LoraEncoder::writeUint8(uint8_t i) { + _intToBytes(_buffer, i, 1); + _buffer += 1; +} + +void LoraEncoder::writeHumidity(float humidity) { + int16_t h = (int16_t) (humidity * 100); + _intToBytes(_buffer, h, 2); + _buffer += 2; +} + +/** +* Uses a 16bit two's complement with two decimals, so the range is +* -327.68 to +327.67 degrees +*/ +void LoraEncoder::writeTemperature(float temperature) { + int16_t t = (int16_t) (temperature * 100); + if (temperature < 0) { + t = ~-t; + t = t + 1; + } + _buffer[0] = (byte) ((t >> 8) & 0xFF); + _buffer[1] = (byte) t & 0xFF; + _buffer += 2; +} + +void LoraEncoder::writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f, bool g, bool h) { + uint8_t bitmap = 0; + // LSB first + bitmap |= (a & 1) << 7; + bitmap |= (b & 1) << 6; + bitmap |= (c & 1) << 5; + bitmap |= (d & 1) << 4; + bitmap |= (e & 1) << 3; + bitmap |= (f & 1) << 2; + bitmap |= (g & 1) << 1; + bitmap |= (h & 1) << 0; + writeUint8(bitmap); +} diff --git a/libraries/Lora_Serialization/src/LoraEncoder.h b/libraries/Lora_Serialization/src/LoraEncoder.h new file mode 100644 index 0000000..2e2d23a --- /dev/null +++ b/libraries/Lora_Serialization/src/LoraEncoder.h @@ -0,0 +1,52 @@ +/* + LoraEncoder.h - Main h file for the Lora serialization library + + The MIT License (MIT) + + Copyright (c) 2016 Joscha Feth + + 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 _LORA_ENCODER_H_ +#define _LORA_ENCODER_H_ + +#if ARDUINO >= 100 + #include "Arduino.h" +#else + #include + typedef uint8_t byte; +#endif + +class LoraEncoder { + public: + LoraEncoder(byte *buffer); + void writeUnixtime(uint32_t unixtime); + void writeLatLng(double latitude, double longitude); + void writeUint16(uint16_t i); + void writeTemperature(float temperature); + void writeUint8(uint8_t i); + void writeHumidity(float humidity); + void writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f, bool g, bool h); + private: + byte* _buffer; + void _intToBytes(byte *buf, int32_t i, uint8_t byteSize); +}; + +#endif diff --git a/libraries/Lora_Serialization/src/LoraMessage.cpp b/libraries/Lora_Serialization/src/LoraMessage.cpp new file mode 100644 index 0000000..31cd9ff --- /dev/null +++ b/libraries/Lora_Serialization/src/LoraMessage.cpp @@ -0,0 +1,72 @@ +#if ARDUINO >= 100 + #include "Arduino.h" +#endif +#include +#include "LoraMessage.h" +#include "LoraEncoder.h" + +LoraMessage::LoraMessage() { + _currentSize = 0; + _buffer = (byte*) malloc(_currentSize); +} + +LoraMessage::~LoraMessage() { + free(_buffer); +} + +LoraEncoder LoraMessage::_reallocBuffer(int delta) { + void* temp = realloc(_buffer, (_currentSize + delta) * sizeof(byte)); + if (temp == NULL) { + free(_buffer); + printf("bad memory allocation!"); + while(true); + } else { + _buffer = (byte*) temp; + } + LoraEncoder encoder(_buffer + _currentSize); + _currentSize += delta; + return encoder; +} + +LoraMessage& LoraMessage::addUnixtime(uint32_t unixtime) { + _reallocBuffer(4).writeUnixtime(unixtime); + return *this; +} + +LoraMessage& LoraMessage::addLatLng(double latitude, double longitude) { + _reallocBuffer(8).writeLatLng(latitude, longitude); + return *this; +} + +LoraMessage& LoraMessage::addUint16(uint16_t i) { + _reallocBuffer(2).writeUint16(i); + return *this; +} + +LoraMessage& LoraMessage::addTemperature(float temperature) { + _reallocBuffer(2).writeTemperature(temperature); + return *this; +} + +LoraMessage& LoraMessage::addUint8(uint8_t i) { + _reallocBuffer(1).writeUint8(i); + return *this; +} + +LoraMessage& LoraMessage::addHumidity(float humidity) { + _reallocBuffer(2).writeHumidity(humidity); + return *this; +} + +LoraMessage& LoraMessage::addBitmap(bool a, bool b, bool c, bool d, bool e, bool f, bool g, bool h) { + _reallocBuffer(1).writeBitmap(a, b, c, d, e, f, g, h); + return *this; +} + +int LoraMessage::getLength() { + return _currentSize; +} + +byte* LoraMessage::getBytes() { + return _buffer; +} diff --git a/libraries/Lora_Serialization/src/LoraMessage.h b/libraries/Lora_Serialization/src/LoraMessage.h new file mode 100644 index 0000000..b3deb42 --- /dev/null +++ b/libraries/Lora_Serialization/src/LoraMessage.h @@ -0,0 +1,32 @@ +#ifndef _LORA_MESSAGE_H_ +#define _LORA_MESSAGE_H_ + +#if ARDUINO >= 100 + #include "Arduino.h" +#else + #include + typedef uint8_t byte; +#endif + +#include "LoraEncoder.h" + +class LoraMessage { + public: + LoraMessage(); + ~LoraMessage(); + LoraMessage& addUnixtime(uint32_t unixtime); + LoraMessage& addLatLng(double latitude, double longitude); + LoraMessage& addUint16(uint16_t i); + LoraMessage& addTemperature(float temperature); + LoraMessage& addUint8(uint8_t i); + LoraMessage& addHumidity(float humidity); + LoraMessage& addBitmap(bool a, bool b, bool c, bool d, bool e, bool f, bool g, bool h); + byte* getBytes(); + int getLength(); + private: + LoraEncoder _reallocBuffer(int delta); + byte* _buffer; + int _currentSize; +}; + +#endif diff --git a/libraries/Lora_Serialization/src/LoraMessage.js b/libraries/Lora_Serialization/src/LoraMessage.js new file mode 100644 index 0000000..a576e14 --- /dev/null +++ b/libraries/Lora_Serialization/src/LoraMessage.js @@ -0,0 +1,70 @@ +(function(root) { + function LoraMessage(encoder) { + this.dataTuples = []; + this.encoder = encoder || root; + } + + LoraMessage.prototype.addTuple = function(data, fnName) { + this.dataTuples.push({ + data: data, + fn: this.encoder[fnName] + }); + }; + + + LoraMessage.prototype.addUnixtime = function(unixtime) { + this.addTuple([unixtime], 'unixtime'); + return this; + }; + + LoraMessage.prototype.addLatLng = function(latitude, longitude) { + this.addTuple([latitude, longitude], 'latLng'); + return this; + }; + + LoraMessage.prototype.addUint16 = function(uint16) { + this.addTuple([uint16], 'uint16'); + return this; + }; + + LoraMessage.prototype.addTemperature = function(temperature) { + this.addTuple([temperature], 'temperature'); + return this; + }; + + LoraMessage.prototype.addUint8 = function(uint8) { + this.addTuple([uint8], 'uint8'); + return this; + }; + + LoraMessage.prototype.addHumidity = function(humidity) { + this.addTuple([humidity], 'humidity'); + return this; + }; + + LoraMessage.prototype.addBitmap = function(a, b, c, d, e, f, g, h) { + this.addTuple([a, b, c, d, e, f, g, h], 'bitmap'); + return this; + }; + + LoraMessage.prototype.getBytes = function() { + var buffer = new Buffer(this.getLength()); + var offset = 0; + this.dataTuples.forEach(function(tuple) { + var current = tuple.fn.apply(null, tuple.data); + current.copy(buffer, offset); + offset += tuple.fn.BYTES; + }); + return buffer; + }; + + LoraMessage.prototype.getLength = function() { + return this.dataTuples.reduce(function(previous, tuple) { + return previous + tuple.fn.BYTES; + }, 0); + }; + + if (typeof module === 'object' && typeof module.exports !== 'undefined') { + module.exports = LoraMessage; + } +})(this); diff --git a/libraries/Lora_Serialization/src/decoder.js b/libraries/Lora_Serialization/src/decoder.js new file mode 100644 index 0000000..52d3b42 --- /dev/null +++ b/libraries/Lora_Serialization/src/decoder.js @@ -0,0 +1,127 @@ +var bytesToInt = function(bytes) { + var i = 0; + for (var x = 0; x < bytes.length; x++) { + i |= +(bytes[x] << (x * 8)); + } + return i; +}; + +var unixtime = function(bytes) { + if (bytes.length !== unixtime.BYTES) { + throw new Error('Unix time must have exactly 4 bytes'); + } + return bytesToInt(bytes); +}; +unixtime.BYTES = 4; + +var uint8 = function(bytes) { + if (bytes.length !== uint8.BYTES) { + throw new Error('int must have exactly 1 byte'); + } + return bytesToInt(bytes); +}; +uint8.BYTES = 1; + +var uint16 = function(bytes) { + if (bytes.length !== uint16.BYTES) { + throw new Error('int must have exactly 2 bytes'); + } + return bytesToInt(bytes); +}; +uint16.BYTES = 2; + +var latLng = function(bytes) { + if (bytes.length !== latLng.BYTES) { + throw new Error('Lat/Long must have exactly 8 bytes'); + } + + var lat = bytesToInt(bytes.slice(0, latLng.BYTES / 2)); + var lng = bytesToInt(bytes.slice(latLng.BYTES / 2, latLng.BYTES)); + + return [lat / 1e6, lng / 1e6]; +}; +latLng.BYTES = 8; + +var temperature = function(bytes) { + if (bytes.length !== temperature.BYTES) { + throw new Error('Temperature must have exactly 2 bytes'); + } + var isNegative = bytes[0] & 0x80; + var b = ('00000000' + Number(bytes[0]).toString(2)).slice(-8) + + ('00000000' + Number(bytes[1]).toString(2)).slice(-8); + if (isNegative) { + var arr = b.split('').map(function(x) { return !Number(x); }); + for (var i = arr.length - 1; i > 0; i--) { + arr[i] = !arr[i]; + if (arr[i]) { + break; + } + } + b = arr.map(Number).join(''); + } + var t = parseInt(b, 2); + if (isNegative) { + t = -t; + } + return t / 1e2; +}; +temperature.BYTES = 2; + +var humidity = function(bytes) { + if (bytes.length !== humidity.BYTES) { + throw new Error('Humidity must have exactly 2 bytes'); + } + + var h = bytesToInt(bytes); + return h / 1e2; +}; +humidity.BYTES = 2; + +var bitmap = function(byte) { + if (byte.length !== bitmap.BYTES) { + throw new Error('Bitmap must have exactly 1 byte'); + } + var i = bytesToInt(byte); + var bm = ('00000000' + Number(i).toString(2)).substr(-8).split('').map(Number).map(Boolean); + return ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] + .reduce(function(obj, pos, index) { + obj[pos] = bm[index]; + return obj; + }, {}); +}; +bitmap.BYTES = 1; + +var decode = function(bytes, mask, names) { + + var maskLength = mask.reduce(function(prev, cur) { + return prev + cur.BYTES; + }, 0); + if (bytes.length < maskLength) { + throw new Error('Mask length is ' + maskLength + ' whereas input is ' + bytes.length); + } + + names = names || []; + var offset = 0; + return mask + .map(function(decodeFn) { + var current = bytes.slice(offset, offset += decodeFn.BYTES); + return decodeFn(current); + }) + .reduce(function(prev, cur, idx) { + prev[names[idx] || idx] = cur; + return prev; + }, {}); +}; + +if (typeof module === 'object' && typeof module.exports !== 'undefined') { + module.exports = { + unixtime: unixtime, + uint8: uint8, + uint16: uint16, + temperature: temperature, + humidity: humidity, + latLng: latLng, + bitmap: bitmap, + decode: decode + }; +} diff --git a/libraries/Lora_Serialization/src/encoder.js b/libraries/Lora_Serialization/src/encoder.js new file mode 100644 index 0000000..894a929 --- /dev/null +++ b/libraries/Lora_Serialization/src/encoder.js @@ -0,0 +1,126 @@ +var intToBytes = function(i, byteSize) { + var buf = new Buffer(byteSize); + for (var x = 0; x < byteSize; x++) { + buf[x] = i >> (x * 8); + } + return buf; +}; + +var unixtime = function(i) { + if (isNaN(i) || i < 0) { + throw new Error('Unix time must be positive'); + } + return intToBytes(i, unixtime.BYTES); +}; +unixtime.BYTES = 4; + +var uint8 = function(i) { + if (isNaN(i) || i < 0 || i > 255) { + throw new Error('int be in range 0..255'); + } + return intToBytes(i, uint8.BYTES); +}; +uint8.BYTES = 1; + +var uint16 = function(i) { + if (isNaN(i) || i < 0 || i > 65535) { + throw new Error('int be in range 0..65535'); + } + return intToBytes(i, uint16.BYTES); +}; +uint16.BYTES = 2; + +var latLng = function(latitude, longitude) { + if (isNaN(latitude) || latitude < -90 || latitude > 90) { + throw new Error('Latitude must be between -90° and 90°'); + } + if (isNaN(longitude) || longitude < -180 || longitude > 180) { + throw new Error('Longitude must be between -180° and 180°'); + } + + return Buffer.concat([ + intToBytes(~~(latitude * 1e6), latLng.BYTES / 2), + intToBytes(~~(longitude * 1e6), latLng.BYTES / 2) + ]); +}; +latLng.BYTES = 8; + +var temperature = function(i) { + + if (isNaN(i) || i < -327.68 || i > 327.67) { + throw new Error('Temperature must be in range -327.68..327.67'); + } + var t = ~~(Math.abs(i) * 1e2); + var b = ('0000000000000000' + Number(t >>> 0).toString(2)).slice(-16); + if (i < 0) { + var arr = b.split('').map(function(x) { return !Number(x); }); + for (var o = arr.length - 1; o > 0; o--) { + arr[o] = !arr[o]; + if (arr[o]) { + break; + } + } + b = arr.map(Number).join(''); + } + return new Buffer([ + parseInt(b.slice(-16, -8), 2), + parseInt(b.slice(-8), 2) + ]); +}; +temperature.BYTES = 2; + +var humidity = function(i) { + if (isNaN(i) || i < 0 || i > 100) { + throw new Error('Humidity must be in range 0..100'); + } + + return intToBytes(i * 1e2, humidity.BYTES); +}; +humidity.BYTES = 2; + +var bitmap = function(a, b, c, d, e, f, g, h) { // eslint-disable-line no-unused-vars + var base = []; + for(var i = 0; i < 8; i++) { + var bit = arguments[i]; + if (typeof bit === 'undefined') { + base[i] = false; + } else if (typeof bit !== 'boolean') { + throw new TypeError('Arguments must be of type boolean'); + } else { + base[i] = bit; + } + } + var bm = parseInt(base.map(Number).join(''), 2); + return intToBytes(bm, bitmap.BYTES); +}; +bitmap.BYTES = 1; + +var encode = function(values, mask) { + if (!Array.isArray(values)) { + throw new TypeError('Values must be an array'); + } + if (!Array.isArray(mask)) { + throw new TypeError('Mask must be an array'); + } + if (values.length > mask.length) { + throw new Error('Mask length is ' + mask.length + ' whereas input is ' + values.length); + } + + return Buffer.concat(values + .map(function(args, i) { + return mask[i].apply(null, Array.isArray(args) ? args : [args]); + })); +}; + +if (typeof module === 'object' && typeof module.exports !== 'undefined') { + module.exports = { + unixtime: unixtime, + uint8: uint8, + uint16: uint16, + temperature: temperature, + humidity: humidity, + latLng: latLng, + bitmap: bitmap, + encode: encode + }; +} diff --git a/libraries/Lora_Serialization/src/index.js b/libraries/Lora_Serialization/src/index.js new file mode 100644 index 0000000..3369193 --- /dev/null +++ b/libraries/Lora_Serialization/src/index.js @@ -0,0 +1,9 @@ +var encoder = require('./encoder'); +var decoder = require('./decoder'); +var LoraMessage = require('./LoraMessage'); + +module.exports = { + encoder: encoder, + decoder: decoder, + LoraMessage: LoraMessage, +}; diff --git a/libraries/Lora_Serialization/test/.eslintrc.js b/libraries/Lora_Serialization/test/.eslintrc.js new file mode 100644 index 0000000..6ce0e4b --- /dev/null +++ b/libraries/Lora_Serialization/test/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + "extends": "../.eslintrc.js", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": 'module', + } +} diff --git a/libraries/Lora_Serialization/test/LoraMessage.js b/libraries/Lora_Serialization/test/LoraMessage.js new file mode 100644 index 0000000..4fa4767 --- /dev/null +++ b/libraries/Lora_Serialization/test/LoraMessage.js @@ -0,0 +1,37 @@ +import test from 'ava'; +import { encoder, LoraMessage } from '../src'; +import base from './base'; + +test('should be possible to construct a simple message', t => { + const m = new LoraMessage(encoder); + m.addUnixtime(base.unixtime); + t.is(m.getLength(), 4); + t.deepEqual(m.getBytes(), base.unixtimeBytes); + t.pass(); +}); + +test('should be possible to chain message parts', t => { + const loraMessage = new LoraMessage(encoder); + t.deepEqual( + loraMessage + .addLatLng.apply(loraMessage, base.latLng) + .addUnixtime(base.unixtime) + .addUint16(base.uint16) + .addTemperature(base.temp) + .addUint8(base.uint8) + .addHumidity(base.humidity) + .addBitmap.apply(loraMessage, base.bitmapArgs) + .getBytes() + , + Buffer.concat([ + base.latLngBytes, + base.unixtimeBytes, + base.uint16Bytes, + base.tempBytes, + base.uint8Bytes, + base.humidityBytes, + base.bitmapBytes, + ]) + ); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/Makefile b/libraries/Lora_Serialization/test/Makefile new file mode 100644 index 0000000..057983c --- /dev/null +++ b/libraries/Lora_Serialization/test/Makefile @@ -0,0 +1,18 @@ +CC = g++ + +# -g adds debugging information to the executable file +# -Wall turns on most, but not all, compiler warnings +CFLAGS = -g -Wall --coverage + +TARGET = main + +all: $(TARGET) + +$(TARGET): $(TARGET).cpp + $(CC) $(CFLAGS) -o $(TARGET) $(TARGET).cpp + +test: + ./main + +clean: + $(RM) $(TARGET) $(TARGET).gcda $(TARGET).gcno diff --git a/libraries/Lora_Serialization/test/base.js b/libraries/Lora_Serialization/test/base.js new file mode 100644 index 0000000..f85cb63 --- /dev/null +++ b/libraries/Lora_Serialization/test/base.js @@ -0,0 +1,39 @@ +module.exports = { + unixtimeBytes: new Buffer([0x1d, 0x4b, 0x7a, 0x57]), + unixtime: 1467632413, + uint8Bytes: new Buffer([0xFF]), + uint8: 255, + uint16Bytes: new Buffer([0x9d, 0x5b]), + uint16: 23453, + tempBytes: new Buffer([0x1f, 0x4c]), + temp: 80.12, + negativeTempBytes: new Buffer([0xcf, 0xc7]), + negativeTemp: -123.45, + humidityBytes: new Buffer([0x0f, 0x27]), + humidity: 99.99, + latLngBytes: new Buffer([0x64, 0xa6, 0xfa, 0xfd, 0x6a, 0x24, 0x04, 0x09]), + latLng: [-33.905052, 151.26641], + bitmapArgs: [true, true, true, true, true, true, false, true], + bitmap: { + a: true, + b: true, + c: true, + d: true, + e: true, + f: true, + g: false, + h: true + }, + bitmapBytes: new Buffer([253]), + bitmap2: { + a: false, + b: true, + c: false, + d: false, + e: false, + f: false, + g: false, + h: false + }, + bitmap2Bytes: new Buffer([64]), +}; diff --git a/libraries/Lora_Serialization/test/decoder/bitmap.js b/libraries/Lora_Serialization/test/decoder/bitmap.js new file mode 100644 index 0000000..8f6c02d --- /dev/null +++ b/libraries/Lora_Serialization/test/decoder/bitmap.js @@ -0,0 +1,20 @@ +import test from 'ava'; +import { decoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the buffer is omitted', t => { + t.throws(() => decoder.bitmap(), /undefined/); + t.pass(); +}); +test('should yell at you if the buffer size is incorrect', t => { + t.throws(() => decoder.bitmap(new Buffer([1, 2])), /must have/); + t.pass(); +}); +test('should be possible to decode a bitmap', t => { + t.deepEqual(decoder.bitmap(base.bitmapBytes), base.bitmap); + t.pass(); +}); +test('should be possible to decode a bitmap with leading false', t => { + t.deepEqual(decoder.bitmap(base.bitmap2Bytes), base.bitmap2); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/decoder/decode.js b/libraries/Lora_Serialization/test/decoder/decode.js new file mode 100644 index 0000000..ccdcebd --- /dev/null +++ b/libraries/Lora_Serialization/test/decoder/decode.js @@ -0,0 +1,52 @@ +import test from 'ava'; +import { decoder } from '../../src'; +import base from '../base'; + +test('should be able to compose decoder functions', t => { + t.deepEqual( + decoder.decode( + Buffer.concat([ + base.latLngBytes, + base.unixtimeBytes, + base.uint16Bytes, + base.tempBytes, + base.uint8Bytes, + base.humidityBytes, + base.bitmapBytes, + ]), [ + decoder.latLng, + decoder.unixtime, + decoder.uint16, + decoder.temperature, + decoder.uint8, + decoder.humidity, + decoder.bitmap, + ] + ), + { + 0: base.latLng, + 1: base.unixtime, + 2: base.uint16, + 3: base.temp, + 4: base.uint8, + 5: base.humidity, + 6: base.bitmap, + } + ); + t.pass(); +}); + +test('should yell at you if mask is longer than input', t => { + t.throws(() => decoder.decode(new Buffer(7), [decoder.latLng]), /Mask/i); + t.pass(); +}); + +test('should be able to take names', t => { + t.deepEqual( + decoder.decode(base.unixtimeBytes, [decoder.unixtime], ['time']), + { + time: base.unixtime + } + ); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/decoder/humidity.js b/libraries/Lora_Serialization/test/decoder/humidity.js new file mode 100644 index 0000000..a7bd00f --- /dev/null +++ b/libraries/Lora_Serialization/test/decoder/humidity.js @@ -0,0 +1,18 @@ +import test from 'ava'; +import { decoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the buffer is omitted', t => { + t.throws(() => decoder.humidity(), /undefined/); + t.pass(); +}); + +test('should yell at you if the buffer size is incorrect', t => { + t.throws(() => decoder.humidity(new Buffer([1])), /must have/); + t.pass(); +}); + +test('should be possible to decode a humidity', t => { + t.is(decoder.humidity(base.humidityBytes), base.humidity); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/decoder/latLng.js b/libraries/Lora_Serialization/test/decoder/latLng.js new file mode 100644 index 0000000..cd202ad --- /dev/null +++ b/libraries/Lora_Serialization/test/decoder/latLng.js @@ -0,0 +1,18 @@ +import test from 'ava'; +import { decoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the buffer is omitted', t => { + t.throws(() => decoder.latLng(), /undefined/); + t.pass(); +}); + +test('should yell at you if the buffer size is incorrect', t => { + t.throws(() => decoder.latLng(new Buffer([1, 2, 3, 4, 5, 6, 7, 8, 9])), /must have/); + t.pass(); +}); + +test('should be possible to decode a coordinate', t => { + t.deepEqual(decoder.latLng(base.latLngBytes), base.latLng); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/decoder/temperature.js b/libraries/Lora_Serialization/test/decoder/temperature.js new file mode 100644 index 0000000..da6e448 --- /dev/null +++ b/libraries/Lora_Serialization/test/decoder/temperature.js @@ -0,0 +1,23 @@ +import test from 'ava'; +import { decoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the buffer is omitted', t => { + t.throws(() => decoder.temperature(), /undefined/); + t.pass(); +}); + +test('should yell at you if the buffer size is incorrect', t => { + t.throws(() => decoder.temperature(new Buffer([1])), /must have/); + t.pass(); +}); + +test('should be possible to decode a temperature', t => { + t.is(decoder.temperature(base.tempBytes), base.temp); + t.pass(); +}); + +test('should be possible to decode a negative temperature', t => { + t.is(decoder.temperature(base.negativeTempBytes), base.negativeTemp); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/decoder/uint16.js b/libraries/Lora_Serialization/test/decoder/uint16.js new file mode 100644 index 0000000..1915a33 --- /dev/null +++ b/libraries/Lora_Serialization/test/decoder/uint16.js @@ -0,0 +1,18 @@ +import test from 'ava'; +import { decoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the buffer is omitted', t => { + t.throws(() => decoder.uint16(), /undefined/); + t.pass(); +}); + +test('should yell at you if the buffer size is incorrect', t => { + t.throws(() => decoder.uint16(new Buffer([1])), /must have/); + t.pass(); +}); + +test('should be possible to decode an int', t => { + t.is(decoder.uint16(base.uint16Bytes), base.uint16); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/decoder/uint8.js b/libraries/Lora_Serialization/test/decoder/uint8.js new file mode 100644 index 0000000..cbe8366 --- /dev/null +++ b/libraries/Lora_Serialization/test/decoder/uint8.js @@ -0,0 +1,18 @@ +import test from 'ava'; +import { decoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the buffer is omitted', t => { + t.throws(() => decoder.uint8(), /undefined/); + t.pass(); +}); + +test('should yell at you if the buffer size is incorrect', t => { + t.throws(() => decoder.uint8(new Buffer([1, 2])), /must have/); + t.pass(); +}); + +test('should be possible to decode an int', t => { + t.is(decoder.uint8(base.uint8Bytes), base.uint8); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/decoder/unixtime.js b/libraries/Lora_Serialization/test/decoder/unixtime.js new file mode 100644 index 0000000..1163d56 --- /dev/null +++ b/libraries/Lora_Serialization/test/decoder/unixtime.js @@ -0,0 +1,18 @@ +import test from 'ava'; +import { decoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the buffer is omitted', t => { + t.throws(() => decoder.unixtime(), /undefined/); + t.pass(); +}); + +test('should yell at you if the buffer size is incorrect', t => { + t.throws(() => decoder.unixtime(new Buffer([1, 2])), /must have/); + t.pass(); +}); + +test('should be possible to decode a unixtime', t => { + t.is(decoder.unixtime(base.unixtimeBytes), base.unixtime); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/encoder/bitmap.js b/libraries/Lora_Serialization/test/encoder/bitmap.js new file mode 100644 index 0000000..cf175d0 --- /dev/null +++ b/libraries/Lora_Serialization/test/encoder/bitmap.js @@ -0,0 +1,19 @@ +import test from 'ava'; +import { encoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the bitmap is incorrect', t => { + t.throws(() => encoder.bitmap(1), TypeError); + t.throws(() => encoder.bitmap('a'), TypeError); + t.pass(); +}); + +test('should be possible to encode a bitmap', t => { + t.deepEqual(encoder.bitmap.apply(encoder, base.bitmapArgs), base.bitmapBytes); + t.pass(); +}); + +test('should be possible to encode a short bitmap', t => { + t.deepEqual(encoder.bitmap(true), new Buffer([0x80])); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/encoder/encode.js b/libraries/Lora_Serialization/test/encoder/encode.js new file mode 100644 index 0000000..08cd20f --- /dev/null +++ b/libraries/Lora_Serialization/test/encoder/encode.js @@ -0,0 +1,48 @@ +import test from 'ava'; +import { encoder } from '../../src'; +import base from '../base'; + +test('should yell at you if input is incorrect', t => { + t.throws(() => encoder.encode(), /values/i); + t.throws(() => encoder.encode([]), /mask/i); + t.pass(); +}); + +test('should yell at you if input is longer than mask', t => { + t.throws(() => encoder.encode([1,2,3], [encoder.latLng]), /Mask/i); + t.pass(); +}); + +test('should be able to compose encoder functions', t => { + t.deepEqual(encoder + .encode( + [ + base.latLng, + base.unixtime, + base.uint16, + base.temp, + base.uint8, + base.humidity, + base.bitmapArgs, + ], + [ + encoder.latLng, + encoder.unixtime, + encoder.uint16, + encoder.temperature, + encoder.uint8, + encoder.humidity, + encoder.bitmap, + ]), + Buffer.concat([ + base.latLngBytes, + base.unixtimeBytes, + base.uint16Bytes, + base.tempBytes, + base.uint8Bytes, + base.humidityBytes, + base.bitmapBytes, + ]) + ); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/encoder/humidity.js b/libraries/Lora_Serialization/test/encoder/humidity.js new file mode 100644 index 0000000..88a8674 --- /dev/null +++ b/libraries/Lora_Serialization/test/encoder/humidity.js @@ -0,0 +1,17 @@ +import test from 'ava'; +import { encoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the humidity is omitted', t => { + t.throws(() => encoder.humidity()); + t.pass(); +}); +test('should yell at you if the humidity is incorrect', t => { + t.throws(() => encoder.humidity(-0.01), /range/); + t.throws(() => encoder.humidity(100.01), /range/); + t.pass(); +}); +test('should be possible to encode a humidity', t => { + t.deepEqual(encoder.humidity(base.humidity), base.humidityBytes); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/encoder/latLng.js b/libraries/Lora_Serialization/test/encoder/latLng.js new file mode 100644 index 0000000..248db70 --- /dev/null +++ b/libraries/Lora_Serialization/test/encoder/latLng.js @@ -0,0 +1,22 @@ +import test from 'ava'; +import { encoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the coordinates are omitted', t => { + t.throws(() => encoder.latLng(), /latitude/i); + t.throws(() => encoder.latLng(0), /longitude/i); + t.pass(); +}); + +test('should yell at you if the coordinates are incorrect', t => { + t.throws(() => encoder.latLng(-90.000001, 0), /latitude/i); + t.throws(() => encoder.latLng(90.000001, 0), /latitude/i); + t.throws(() => encoder.latLng(0, -180.000001), /longitude/i); + t.throws(() => encoder.latLng(0, 180.000001), /longitude/i); + t.pass(); +}); + +test('should be possible to decode a coordinate', t => { + t.deepEqual(encoder.latLng(...base.latLng), base.latLngBytes); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/encoder/temperature.js b/libraries/Lora_Serialization/test/encoder/temperature.js new file mode 100644 index 0000000..e3bb604 --- /dev/null +++ b/libraries/Lora_Serialization/test/encoder/temperature.js @@ -0,0 +1,24 @@ +import test from 'ava'; +import { encoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the temperature is omitted', t => { + t.throws(() => encoder.temperature()); + t.pass(); +}); + +test('should yell at you if the temperature is incorrect', t => { + t.throws(() => encoder.temperature(-327.69), /range/); + t.throws(() => encoder.temperature(327.68), /range/); + t.pass(); +}); + +test('should be possible to encode a temperature', t => { + t.deepEqual(encoder.temperature(base.temp), base.tempBytes); + t.pass(); +}); + +test('should be possible to encode a negative temperature', t => { + t.deepEqual(encoder.temperature(base.negativeTemp), base.negativeTempBytes); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/encoder/uint16.js b/libraries/Lora_Serialization/test/encoder/uint16.js new file mode 100644 index 0000000..526e369 --- /dev/null +++ b/libraries/Lora_Serialization/test/encoder/uint16.js @@ -0,0 +1,19 @@ +import test from 'ava'; +import { encoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the uint is omitted', t => { + t.throws(() => encoder.uint16()); + t.pass(); +}); + +test('should yell at you if the uint size is incorrect', t => { + t.throws(() => encoder.uint16(-1), /range/); + t.throws(() => encoder.uint16(65536), /range/); + t.pass(); +}); + +test('should be possible to encode an int', t => { + t.deepEqual(encoder.uint16(base.uint16), base.uint16Bytes); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/encoder/uint8.js b/libraries/Lora_Serialization/test/encoder/uint8.js new file mode 100644 index 0000000..3f064f3 --- /dev/null +++ b/libraries/Lora_Serialization/test/encoder/uint8.js @@ -0,0 +1,19 @@ +import test from 'ava'; +import { encoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the uint is omitted', t => { + t.throws(() => encoder.uint8()); + t.pass(); +}); + +test('should yell at you if the uint is incorrect', t => { + t.throws(() => encoder.uint8(-1), /range/); + t.throws(() => encoder.uint8(256), /range/); + t.pass(); +}); + +test('should be possible to encode an int', t => { + t.deepEqual(encoder.uint8(base.uint8), base.uint8Bytes); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/encoder/unixtime.js b/libraries/Lora_Serialization/test/encoder/unixtime.js new file mode 100644 index 0000000..591465c --- /dev/null +++ b/libraries/Lora_Serialization/test/encoder/unixtime.js @@ -0,0 +1,18 @@ +import test from 'ava'; +import { encoder } from '../../src'; +import base from '../base'; + +test('should yell at you if the unixtime is omitted', t => { + t.throws(() => encoder.unixtime()); + t.pass(); +}); + +test('should yell at you if the unixtime is incorrect', t => { + t.throws(() => encoder.unixtime(-1), /positive/); + t.pass(); +}); + +test('should be possible to encode a unixtime', t => { + t.deepEqual(encoder.unixtime(base.unixtime), base.unixtimeBytes); + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/helpers.cpp b/libraries/Lora_Serialization/test/helpers.cpp new file mode 100644 index 0000000..9f6fb55 --- /dev/null +++ b/libraries/Lora_Serialization/test/helpers.cpp @@ -0,0 +1,12 @@ +void printByteArrayToHex(byte *arr) { + for(int i = 0; i < sizeof(arr); i++) { + printf("%02x", arr[i]); + } + printf("\n"); +} + +void compare_array(byte *arr1, byte *arr2, int start, int len) { + for(int i = start; i < start + len; i++) { + REQUIRE(arr1[i] == arr2[i]); + } +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/.gitattributes b/libraries/Lora_Serialization/test/lib/Catch/.gitattributes new file mode 100644 index 0000000..a2d66d3 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/.gitattributes @@ -0,0 +1,11 @@ +# This sets the default behaviour, overriding core.autocrlf +* text=auto + +# All source files should have unix line-endings in the repository, +# but convert to native line-endings on checkout +*.cpp text +*.h text +*.hpp text + +# Windows specific files should retain windows line-endings +*.sln text eol=crlf \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/.github/issue_template.md b/libraries/Lora_Serialization/test/lib/Catch/.github/issue_template.md new file mode 100644 index 0000000..051b5e5 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/.github/issue_template.md @@ -0,0 +1,29 @@ +## Description + + + +### Steps to reproduce + + + +### Extra information + +* Catch version: **v42.42.42** +* Operating System: **Joe's discount operating system** +* Compiler+version: **Hidden Dragon v1.2.3** diff --git a/libraries/Lora_Serialization/test/lib/Catch/.github/pull_request_template.md b/libraries/Lora_Serialization/test/lib/Catch/.github/pull_request_template.md new file mode 100644 index 0000000..95e3ccd --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/.github/pull_request_template.md @@ -0,0 +1,25 @@ + + + +## Description + + +## GitHub Issues + diff --git a/libraries/Lora_Serialization/test/lib/Catch/.gitignore b/libraries/Lora_Serialization/test/lib/Catch/.gitignore new file mode 100644 index 0000000..c7c3fc8 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/.gitignore @@ -0,0 +1,29 @@ +*.build +*.pbxuser +*.mode1v3 +*.ncb +*.suo +Debug +Release +*.user +*.xcuserstate +.DS_Store +xcuserdata +CatchSelfTest.xcscheme +Breakpoints.xcbkptlist +projects/VS2010/TestCatch/_UpgradeReport_Files/ +projects/VS2010/TestCatch/TestCatch/TestCatch.vcxproj.filters +projects/VisualStudio/TestCatch/UpgradeLog.XML +projects/CMake/.idea +projects/CMake/cmake-build-debug +UpgradeLog.XML +Resources/DWARF +projects/Generated +*.pyc +DerivedData +*.xccheckout +Build +.idea +cmake-build-debug +cmake-build-release +.vs \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/.travis.yml b/libraries/Lora_Serialization/test/lib/Catch/.travis.yml new file mode 100644 index 0000000..c44a8cd --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/.travis.yml @@ -0,0 +1,232 @@ +language: cpp +sudo: false + +matrix: + include: + + # 1/ Linux Clang Builds + - os: linux + compiler: clang + addons: &clang34 + apt: + sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test'] + packages: ['clang'] + env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: clang + addons: *clang34 + env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0 + + - os: linux + compiler: clang + addons: &clang35 + apt: + sources: ['llvm-toolchain-precise-3.5', 'ubuntu-toolchain-r-test'] + packages: ['clang-3.5'] + env: COMPILER='clang++-3.5' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: clang + addons: *clang35 + env: COMPILER='clang++-3.5' BUILD_TYPE='Debug' CPP11=0 + + + - os: linux + compiler: clang + addons: &clang36 + apt: + sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test'] + packages: ['clang-3.6'] + env: COMPILER='clang++-3.6' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: clang + addons: *clang36 + env: COMPILER='clang++-3.6' BUILD_TYPE='Debug' CPP11=0 + + + - os: linux + compiler: clang + addons: &clang37 + apt: + sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test'] + packages: ['clang-3.7'] + env: COMPILER='clang++-3.7' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: clang + addons: *clang37 + env: COMPILER='clang++-3.7' BUILD_TYPE='Debug' CPP11=0 + + + - os: linux + compiler: clang + addons: &clang38 + apt: + sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test'] + packages: ['clang-3.8'] + env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: clang + addons: *clang38 + env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP11=0 + + + # 2/ Linux GCC Builds + - os: linux + compiler: gcc + addons: &gcc44 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-4.4'] + env: COMPILER='g++-4.4' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: gcc + addons: *gcc44 + env: COMPILER='g++-4.4' BUILD_TYPE='Debug' CPP11=0 + + + - os: linux + compiler: gcc + addons: &gcc47 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-4.7'] + env: COMPILER='g++-4.7' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: gcc + addons: *gcc47 + env: COMPILER='g++-4.7' BUILD_TYPE='Debug' CPP11=0 + + + - os: linux + compiler: gcc + addons: &gcc48 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-4.8'] + env: COMPILER='g++-4.8' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: gcc + addons: *gcc48 + env: COMPILER='g++-4.8' BUILD_TYPE='Debug' CPP11=0 + + + - os: linux + compiler: gcc + addons: &gcc49 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-4.9'] + env: COMPILER='g++-4.9' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: gcc + addons: *gcc49 + env: COMPILER='g++-4.9' BUILD_TYPE='Debug' CPP11=0 + + + - os: linux + compiler: gcc + addons: &gcc5 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-5'] + env: COMPILER='g++-5' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: gcc + addons: *gcc5 + env: COMPILER='g++-5' BUILD_TYPE='Debug' CPP11=0 + + + - os: linux + compiler: gcc + addons: &gcc6 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-6'] + env: COMPILER='g++-6' BUILD_TYPE='Release' CPP11=0 + + - os: linux + compiler: gcc + addons: *gcc6 + env: COMPILER='g++-6' BUILD_TYPE='Debug' CPP11=0 + + # 3a/ Linux C++11 GCC builds + - os: linux + compiler: gcc + addons: &gcc48 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-4.8'] + env: COMPILER='g++-4.8' BUILD_TYPE='Release' CPP11=1 + + - os: linux + compiler: gcc + addons: *gcc48 + env: COMPILER='g++-4.8' BUILD_TYPE='Debug' CPP11=1 + + # 3b/ Linux C++11 Clang builds + - os: linux + compiler: clang + addons: &clang38 + apt: + sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test'] + packages: ['clang-3.8'] + env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP11=1 + + - os: linux + compiler: clang + addons: *clang38 + env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP11=1 + + + # 4/ OSX Clang Builds + - os: osx + osx_image: xcode7.3 + compiler: clang + env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0 + + - os: osx + osx_image: xcode7.3 + compiler: clang + env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0 + + - os: osx + osx_image: xcode8 + compiler: clang + env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0 + + - os: osx + osx_image: xcode8 + compiler: clang + env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0 + + +install: + - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps" + - mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR} + - | + if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then + CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz" + mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake + export PATH=${DEPS_DIR}/cmake/bin:${PATH} + elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then + which cmake || brew install cmake + fi + +before_script: + - export CXX=${COMPILER} + - cd ${TRAVIS_BUILD_DIR} + - cmake -H. -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -Wdev -DUSE_CPP11=${CPP11} + - cd Build + +script: + - make -j 2 + - ctest -V -j 2 diff --git a/libraries/Lora_Serialization/test/lib/Catch/CMakeLists.txt b/libraries/Lora_Serialization/test/lib/Catch/CMakeLists.txt new file mode 100644 index 0000000..db43d41 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/CMakeLists.txt @@ -0,0 +1,271 @@ +cmake_minimum_required(VERSION 3.0) + +project(CatchSelfTest) + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +# define some folders +set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest) +set(BENCHMARK_DIR ${CATCH_DIR}/projects/Benchmark) +set(HEADER_DIR ${CATCH_DIR}/include) + +if(USE_CPP11) + ## We can't turn this on by default, since it breaks on travis + message(STATUS "Enabling C++11") + set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") +elseif(USE_CPP14) + message(STATUS "Enabling C++14") + set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}") +endif() + +#checks that the given hard-coded list contains all headers + sources in the given folder +function(CheckFileList LIST_VAR FOLDER) + set(MESSAGE " should be added to the variable ${LIST_VAR}") + set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n") + file(GLOB GLOBBED_LIST "${FOLDER}/*.cpp" + "${FOLDER}/*.hpp" + "${FOLDER}/*.h") + list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}}) + foreach(EXTRA_ITEM ${GLOBBED_LIST}) + string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}") + message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}") + endforeach() +endfunction() + +function(CheckFileListRec LIST_VAR FOLDER) + set(MESSAGE " should be added to the variable ${LIST_VAR}") + set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n") + file(GLOB_RECURSE GLOBBED_LIST "${FOLDER}/*.cpp" + "${FOLDER}/*.hpp" + "${FOLDER}/*.h") + list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}}) + foreach(EXTRA_ITEM ${GLOBBED_LIST}) + string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}") + message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}") + endforeach() +endfunction() + +# define the sources of the self test +# Please keep these ordered alphabetically +set(TEST_SOURCES + ${SELF_TEST_DIR}/ApproxTests.cpp + ${SELF_TEST_DIR}/BDDTests.cpp + ${SELF_TEST_DIR}/ClassTests.cpp + ${SELF_TEST_DIR}/CmdLineTests.cpp + ${SELF_TEST_DIR}/CompilationTests.cpp + ${SELF_TEST_DIR}/ConditionTests.cpp + ${SELF_TEST_DIR}/EnumToString.cpp + ${SELF_TEST_DIR}/ExceptionTests.cpp + ${SELF_TEST_DIR}/GeneratorTests.cpp + ${SELF_TEST_DIR}/MessageTests.cpp + ${SELF_TEST_DIR}/MiscTests.cpp + ${SELF_TEST_DIR}/PartTrackerTests.cpp + ${SELF_TEST_DIR}/TagAliasTests.cpp + ${SELF_TEST_DIR}/TestMain.cpp + ${SELF_TEST_DIR}/ToStringGeneralTests.cpp + ${SELF_TEST_DIR}/ToStringPair.cpp + ${SELF_TEST_DIR}/ToStringTuple.cpp + ${SELF_TEST_DIR}/ToStringVector.cpp + ${SELF_TEST_DIR}/ToStringWhich.cpp + ${SELF_TEST_DIR}/TrickyTests.cpp + ${SELF_TEST_DIR}/VariadicMacrosTests.cpp + ${SELF_TEST_DIR}/MatchersTests.cpp + ) +CheckFileList(TEST_SOURCES ${SELF_TEST_DIR}) + +# A set of impl files that just #include a single header +# Please keep these ordered alphabetically +set(IMPL_SOURCES + ${SELF_TEST_DIR}/SurrogateCpps/catch_common.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_debugger.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_capture.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_config.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_exception.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_generators.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_registry_hub.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_reporter.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_runner.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_testcase.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_message.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_option.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_ptr.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_stream.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_streambuf.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp + ${SELF_TEST_DIR}/SurrogateCpps/catch_test_case_tracker.cpp + ) +CheckFileList(IMPL_SOURCES ${SELF_TEST_DIR}/SurrogateCpps) + + +# Please keep these ordered alphabetically +set(TOP_LEVEL_HEADERS + ${HEADER_DIR}/catch.hpp + ${HEADER_DIR}/catch_session.hpp + ${HEADER_DIR}/catch_with_main.hpp + ) +CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR}) + +# Please keep these ordered alphabetically +set(EXTERNAL_HEADERS + ${HEADER_DIR}/external/clara.h + ${HEADER_DIR}/external/tbc_text_format.h + ) +CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external) + + +# Please keep these ordered alphabetically +set(INTERNAL_HEADERS + ${HEADER_DIR}/internal/catch_approx.hpp + ${HEADER_DIR}/internal/catch_assertionresult.h + ${HEADER_DIR}/internal/catch_assertionresult.hpp + ${HEADER_DIR}/internal/catch_capture.hpp + ${HEADER_DIR}/internal/catch_clara.h + ${HEADER_DIR}/internal/catch_commandline.hpp + ${HEADER_DIR}/internal/catch_common.h + ${HEADER_DIR}/internal/catch_common.hpp + ${HEADER_DIR}/internal/catch_compiler_capabilities.h + ${HEADER_DIR}/internal/catch_config.hpp + ${HEADER_DIR}/internal/catch_console_colour.hpp + ${HEADER_DIR}/internal/catch_console_colour_impl.hpp + ${HEADER_DIR}/internal/catch_context.h + ${HEADER_DIR}/internal/catch_context_impl.hpp + ${HEADER_DIR}/internal/catch_debugger.h + ${HEADER_DIR}/internal/catch_debugger.hpp + ${HEADER_DIR}/internal/catch_default_main.hpp + ${HEADER_DIR}/internal/catch_evaluate.hpp + ${HEADER_DIR}/internal/catch_exception_translator_registry.hpp + ${HEADER_DIR}/internal/catch_expression_lhs.hpp + ${HEADER_DIR}/internal/catch_fatal_condition.hpp + ${HEADER_DIR}/internal/catch_generators.hpp + ${HEADER_DIR}/internal/catch_generators_impl.hpp + ${HEADER_DIR}/internal/catch_impl.hpp + ${HEADER_DIR}/internal/catch_interfaces_capture.h + ${HEADER_DIR}/internal/catch_interfaces_config.h + ${HEADER_DIR}/internal/catch_interfaces_exception.h + ${HEADER_DIR}/internal/catch_interfaces_generators.h + ${HEADER_DIR}/internal/catch_interfaces_registry_hub.h + ${HEADER_DIR}/internal/catch_interfaces_reporter.h + ${HEADER_DIR}/internal/catch_interfaces_runner.h + ${HEADER_DIR}/internal/catch_interfaces_tag_alias_registry.h + ${HEADER_DIR}/internal/catch_interfaces_testcase.h + ${HEADER_DIR}/internal/catch_legacy_reporter_adapter.h + ${HEADER_DIR}/internal/catch_legacy_reporter_adapter.hpp + ${HEADER_DIR}/internal/catch_list.hpp + ${HEADER_DIR}/internal/catch_matchers.hpp + ${HEADER_DIR}/internal/catch_matchers_string.h + ${HEADER_DIR}/internal/catch_matchers_string.hpp + ${HEADER_DIR}/internal/catch_matchers_vector.h + ${HEADER_DIR}/internal/catch_message.h + ${HEADER_DIR}/internal/catch_message.hpp + ${HEADER_DIR}/internal/catch_notimplemented_exception.h + ${HEADER_DIR}/internal/catch_notimplemented_exception.hpp + ${HEADER_DIR}/internal/catch_objc.hpp + ${HEADER_DIR}/internal/catch_objc_arc.hpp + ${HEADER_DIR}/internal/catch_option.hpp + ${HEADER_DIR}/internal/catch_platform.h + ${HEADER_DIR}/internal/catch_ptr.hpp + ${HEADER_DIR}/internal/catch_reenable_warnings.h + ${HEADER_DIR}/internal/catch_registry_hub.hpp + ${HEADER_DIR}/internal/catch_reporter_registrars.hpp + ${HEADER_DIR}/internal/catch_reporter_registry.hpp + ${HEADER_DIR}/internal/catch_result_builder.h + ${HEADER_DIR}/internal/catch_result_builder.hpp + ${HEADER_DIR}/internal/catch_result_type.h + ${HEADER_DIR}/internal/catch_run_context.hpp + ${HEADER_DIR}/internal/catch_section.h + ${HEADER_DIR}/internal/catch_section.hpp + ${HEADER_DIR}/internal/catch_section_info.h + ${HEADER_DIR}/internal/catch_section_info.hpp + ${HEADER_DIR}/internal/catch_stream.h + ${HEADER_DIR}/internal/catch_stream.hpp + ${HEADER_DIR}/internal/catch_streambuf.h + ${HEADER_DIR}/internal/catch_suppress_warnings.h + ${HEADER_DIR}/internal/catch_tag_alias.h + ${HEADER_DIR}/internal/catch_tag_alias_registry.h + ${HEADER_DIR}/internal/catch_tag_alias_registry.hpp + ${HEADER_DIR}/internal/catch_test_case_info.h + ${HEADER_DIR}/internal/catch_test_case_info.hpp + ${HEADER_DIR}/internal/catch_test_case_registry_impl.hpp + ${HEADER_DIR}/internal/catch_test_case_tracker.hpp + ${HEADER_DIR}/internal/catch_test_registry.hpp + ${HEADER_DIR}/internal/catch_test_spec.hpp + ${HEADER_DIR}/internal/catch_test_spec_parser.hpp + ${HEADER_DIR}/internal/catch_text.h + ${HEADER_DIR}/internal/catch_timer.h + ${HEADER_DIR}/internal/catch_timer.hpp + ${HEADER_DIR}/internal/catch_tostring.h + ${HEADER_DIR}/internal/catch_tostring.hpp + ${HEADER_DIR}/internal/catch_totals.hpp + ${HEADER_DIR}/internal/catch_type_traits.hpp + ${HEADER_DIR}/internal/catch_version.h + ${HEADER_DIR}/internal/catch_version.hpp + ${HEADER_DIR}/internal/catch_wildcard_pattern.hpp + ${HEADER_DIR}/internal/catch_windows_h_proxy.h + ${HEADER_DIR}/internal/catch_xmlwriter.hpp + ) +CheckFileList(INTERNAL_HEADERS ${HEADER_DIR}/internal) + +# Please keep these ordered alphabetically +set(REPORTER_HEADERS + ${HEADER_DIR}/reporters/catch_reporter_automake.hpp + ${HEADER_DIR}/reporters/catch_reporter_bases.hpp + ${HEADER_DIR}/reporters/catch_reporter_compact.hpp + ${HEADER_DIR}/reporters/catch_reporter_console.hpp + ${HEADER_DIR}/reporters/catch_reporter_junit.hpp + ${HEADER_DIR}/reporters/catch_reporter_multi.hpp + ${HEADER_DIR}/reporters/catch_reporter_tap.hpp + ${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp + ${HEADER_DIR}/reporters/catch_reporter_xml.hpp + ) +CheckFileList(REPORTER_HEADERS ${HEADER_DIR}/reporters) + +# Specify the headers, too, so CLion recognises them as project files +set(HEADERS + ${TOP_LEVEL_HEADERS} + ${EXTERNAL_HEADERS} + ${INTERNAL_HEADERS} + ${REPORTER_HEADERS} + ) + + +set(BENCH_SOURCES + ${BENCHMARK_DIR}/BenchMain.cpp + ${BENCHMARK_DIR}/StringificationBench.cpp + ) +CheckFileList(BENCH_SOURCES ${BENCHMARK_DIR}) + +# Provide some groupings for IDEs +SOURCE_GROUP("Tests" FILES ${TEST_SOURCES}) +SOURCE_GROUP("Surrogates" FILES ${IMPL_SOURCES}) +SOURCE_GROUP("Benchmarks" FILES ${BENCH_SOURCES}) + +# configure the executable +include_directories(${HEADER_DIR}) +add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS}) +add_executable(Benchmark ${BENCH_SOURCES} ${HEADERS}) + +# Add desired warnings +if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" ) + target_compile_options( SelfTest PRIVATE -Wall -Wextra ) + target_compile_options( Benchmark PRIVATE -Wall -Wextra ) +endif() +if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" ) + target_compile_options( SelfTest PRIVATE /W4 ) + target_compile_options( Benchmark PRIVATE /W4 ) +endif() + + +# configure unit tests via CTest +enable_testing() +add_test(NAME RunTests COMMAND SelfTest) + +add_test(NAME ListTests COMMAND SelfTest --list-tests) +set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test cases") + +add_test(NAME ListTags COMMAND SelfTest --list-tags) +set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags") + +install(DIRECTORY "single_include/" DESTINATION "include/catch/") diff --git a/libraries/Lora_Serialization/test/lib/Catch/LICENSE_1_0.txt b/libraries/Lora_Serialization/test/lib/Catch/LICENSE_1_0.txt new file mode 100644 index 0000000..36b7cd9 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/libraries/Lora_Serialization/test/lib/Catch/README.md b/libraries/Lora_Serialization/test/lib/Catch/README.md new file mode 100644 index 0000000..5d68e22 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/README.md @@ -0,0 +1,23 @@ +![catch logo](catch-logo-small.png) + +[![Github Releases](https://img.shields.io/github/release/philsquared/catch.svg)](https://github.com/philsquared/catch/releases) +[![Build Status](https://travis-ci.org/philsquared/Catch.svg?branch=master)](https://travis-ci.org/philsquared/Catch) +[![Build status](https://ci.appveyor.com/api/projects/status/hrtk60hv6tw6fght/branch/master?svg=true)](https://ci.appveyor.com/project/philsquared/catch/branch/master) + +The latest, single header, version can be downloaded directly using this link + +## What's the Catch? + +Catch stands for C++ Automated Test Cases in Headers and is a multi-paradigm automated test framework for C++ and Objective-C (and, maybe, C). It is implemented entirely in a set of header files, but is packaged up as a single header for extra convenience. + +## How to use it +This documentation comprises these three parts: + +* [Why do we need yet another C++ Test Framework?](docs/why-catch.md) +* [Tutorial](docs/tutorial.md) - getting started +* [Reference section](docs/Readme.md) - all the details + +## More +* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/philsquared/Catch/issues) +* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum) +* See [who else is using Catch](docs/opensource-users.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/appveyor.yml b/libraries/Lora_Serialization/test/lib/Catch/appveyor.yml new file mode 100644 index 0000000..6576baf --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/appveyor.yml @@ -0,0 +1,45 @@ +# version string format -- This will be overwritten later anyway +version: "{build}" + +# Disable the dead branch for v2 development +branches: + except: + - develop-v2 + +os: + - Visual Studio 2013 + - Visual Studio 2015 + +init: + - git config --global core.autocrlf input + # Set build version to git commit-hash + - ps: Update-AppveyorBuild -Version "$($env:APPVEYOR_REPO_BRANCH) - $($env:APPVEYOR_REPO_COMMIT)" + +# fetch repository as zip archive +shallow_clone: true + +# Win32 and x64 are CMake-compatible solution platform names. +# This allows us to pass %PLATFORM% to CMake -A. +platform: + - Win32 + - x64 + +# build Configurations, i.e. Debug, Release, etc. +configuration: + - Debug + - Release + +#Cmake will autodetect the compiler, but we set the arch +before_build: + - echo Running cmake... + - cmake -H. -BBuild -A%PLATFORM% + +# build with MSBuild +build: + project: Build\CatchSelfTest.sln # path to Visual Studio solution or project + parallel: true # enable MSBuild parallel builds + verbosity: normal # MSBuild verbosity level {quiet|minimal|normal|detailed} + +test_script: + - cd Build + - ctest -V -j 2 -C %CONFIGURATION% diff --git a/libraries/Lora_Serialization/test/lib/Catch/catch-hand-icon.png b/libraries/Lora_Serialization/test/lib/Catch/catch-hand-icon.png new file mode 100644 index 0000000..a110d7d Binary files /dev/null and b/libraries/Lora_Serialization/test/lib/Catch/catch-hand-icon.png differ diff --git a/libraries/Lora_Serialization/test/lib/Catch/catch-icon-tiny.png b/libraries/Lora_Serialization/test/lib/Catch/catch-icon-tiny.png new file mode 100644 index 0000000..a037041 Binary files /dev/null and b/libraries/Lora_Serialization/test/lib/Catch/catch-icon-tiny.png differ diff --git a/libraries/Lora_Serialization/test/lib/Catch/catch-logo-small.png b/libraries/Lora_Serialization/test/lib/Catch/catch-logo-small.png new file mode 100644 index 0000000..dd9b5e7 Binary files /dev/null and b/libraries/Lora_Serialization/test/lib/Catch/catch-logo-small.png differ diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/Readme.md b/libraries/Lora_Serialization/test/lib/Catch/docs/Readme.md new file mode 100644 index 0000000..1d84c66 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/Readme.md @@ -0,0 +1,23 @@ +These are the currently documented areas of the framework. There is more to come. + +Before looking at this material be sure to read the [tutorial](tutorial.md) + +* [Assertion macros](assertions.md) +* [Matchers](matchers.md) +* [Logging macros](logging.md) +* [Test cases and sections](test-cases-and-sections.md) +* [Test fixtures](test-fixtures.md) +* [Command line](command-line.md) +* [Build systems](build-systems.md) +* [Supplying your own main()](own-main.md) +* [Configuration](configuration.md) +* [String Conversions](tostring.md) +* [Why are my tests slow to compile?](slow-compiles.md) +* [Known limitations](limitations.md) + +Other + +* [Why Catch?](why-catch.md) +* [Open Source Projects using Catch](opensource-users.md) +* [Contributing](contributing.md) +* [Release Notes](release-notes.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/assertions.md b/libraries/Lora_Serialization/test/lib/Catch/docs/assertions.md new file mode 100644 index 0000000..ff79f0e --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/assertions.md @@ -0,0 +1,136 @@ +# Assertion Macros + +Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc). + +Catch is different. Because it decomposes natural C-style conditional expressions most of these forms are reduced to one or two that you will use all the time. That said there are a rich set of auxilliary macros as well. We'll describe all of these here. + +Most of these macros come in two forms: + +## Natural Expressions + +The ```REQUIRE``` family of macros tests an expression and aborts the test case if it fails. +The ```CHECK``` family are equivalent but execution continues in the same test case even if the assertion fails. This is useful if you have a series of essentially orthogonal assertions and it is useful to see all the results rather than stopping at the first failure. + +* **REQUIRE(** _expression_ **)** and +* **CHECK(** _expression_ **)** + +Evaluates the expression and records the result. If an exception is thrown it is caught, reported, and counted as a failure. These are the macros you will use most of the time + +Examples: +``` +CHECK( str == "string value" ); +CHECK( thisReturnsTrue() ); +REQUIRE( i == 42 ); +``` + +* **REQUIRE_FALSE(** _expression_ **)** and +* **CHECK_FALSE(** _expression_ **)** + +Evaluates the expression and records the _logical NOT_ of the result. If an exception is thrown it is caught, reported, and counted as a failure. +(these forms exist as a workaround for the fact that ! prefixed expressions cannot be decomposed). + +Example: +``` +REQUIRE_FALSE( thisReturnsFalse() ); +``` + +Do note that "overly complex" expressions cannot be decomposed and thus will not compile. This is done partly for practical reasons (to keep the underlying expression template machinery to minimum) and partly for philosophical reasons (assertions should be simple and deterministic). + +Examples: +* `CHECK(a == 1 && b == 2);` +This expression is too complex because of the `&&` operator. If you want to check that 2 or more properties hold, you can either put the expression into parenthesis, which stops decomposition from working, or you need to decompose the expression into two assertions: `CHECK( a == 1 ); CHECK( b == 2);` +* `CHECK( a == 2 || b == 1 );` +This expression is too complex because of the `||` operator. If you want to check that one of several properties hold, you can put the expression into parenthesis (unlike with `&&`, expression decomposition into several `CHECK`s is not possible). + + +### Floating point comparisons + +When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations. + +Catch provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called ```Approx```. ```Approx``` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example: + +``` +REQUIRE( performComputation() == Approx( 2.1 ) ); +``` + +This way `Approx` is constructed with reasonable defaults, covering most simple cases of rounding errors. If these are insufficient, each `Approx` instance has 3 tuning knobs, that can be used to customize it for your computation. + +* __epsilon__ - epsilon serves to set the percentage by which a result can be erroneous, before it is rejected. By default set to `std::numeric_limits::epsilon()*100`. +* __margin__ - margin serves to set the the absolute value by which a result can be erroneous before it is rejected. By default set to `0.0`. +* __scale__ - scale serves to adjust the base for comparison used by epsilon, can be used when By default set to `1.0`. + +#### epsilon example +```cpp +Approx target = Approx(100).epsilon(0.01); +100.0 == target; // Obviously true +200.0 == target; // Obviously still false +100.5 == target; // True, because we set target to allow up to 1% error +``` + +#### margin example +_Margin check is used only if the relative (epsilon and scale based) check fails._ +```cpp +Approx target = Approx(100).margin(5); +100.0 == target; // Obviously true +200.0 == target; // Obviously still false +104.0 == target; // True, because we set target to allow absolute error up to 5 +``` + +#### scale +Scale can be useful if the computation leading to the result worked on different scale, than is used by the results (and thus expected errors are on a different scale than would be expected based on the results alone). + + +## Exceptions + +* **REQUIRE_NOTHROW(** _expression_ **)** and +* **CHECK_NOTHROW(** _expression_ **)** + +Expects that no exception is thrown during evaluation of the expression. + +* **REQUIRE_THROWS(** _expression_ **)** and +* **CHECK_THROWS(** _expression_ **)** + +Expects that an exception (of any type) is be thrown during evaluation of the expression. + +* **REQUIRE_THROWS_AS(** _expression_, _exception type_ **)** and +* **CHECK_THROWS_AS(** _expression_, _exception type_ **)** + +Expects that an exception of the _specified type_ is thrown during evaluation of the expression. + +* **REQUIRE_THROWS_WITH(** _expression_, _string or string matcher_ **)** and +* **CHECK_THROWS_WITH(** _expression_, _string or string matcher_ **)** + +Expects that an exception is thrown that, when converted to a string, matches the _string_ or _string matcher_ provided (see next section for Matchers). + +e.g. +```cpp +REQUIRE_THROWS_WITH( openThePodBayDoors(), Contains( "afraid" ) && Contains( "can't do that" ) ); +REQUIRE_THROWS_WITH( dismantleHal(), "My mind is going" ); +``` + + +Please note that the `THROW` family of assertions expects to be passed a single expression, not a statement or series of statements. If you want to check a more complicated sequence of operations, you can use a C++11 lambda function. + +```cpp +REQUIRE_NOTHROW([&](){ + int i = 1; + int j = 2; + auto k = i + j; + if (k == 3) { + throw 1; + } +}()); +``` + +## Matcher expressions + +To support Matchers a slightly different form is used. Matchers have [their own documentation](matchers.md). + +* **REQUIRE_THAT(** _lhs_, _matcher expression_ **)** and +* **CHECK_THAT(** _lhs_, _matcher expression_ **)** + +Matchers can be composed using `&&`, `||` and `!` operators. + +--- + +[Home](Readme.md) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/build-systems.md b/libraries/Lora_Serialization/test/lib/Catch/docs/build-systems.md new file mode 100644 index 0000000..69e7e5f --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/build-systems.md @@ -0,0 +1,95 @@ +# Integration with build systems + +Build Systems may refer to low-level tools, like CMake, or larger systems that run on servers, like Jenkins or TeamCity. This page will talk about both. + +# Continuous Integration systems + +Probably the most important aspect to using Catch with a build server is the use of different reporters. Catch comes bundled with three reporters that should cover the majority of build servers out there - although adding more for better integration with some is always a possibility (currently we also offer TeamCity, TAP and Automake reporters). + +Two of these reporters are built in (XML and JUnit) and the third (TeamCity) is included as a separate header. It's possible that the other two may be split out in the future too - as that would make the core of Catch smaller for those that don't need them. + +## XML Reporter +```-r xml``` + +The XML Reporter writes in an XML format that is specific to Catch. + +The advantage of this format is that it corresponds well to the way Catch works (especially the more unusual features, such as nested sections) and is a fully streaming format - that is it writes output as it goes, without having to store up all its results before it can start writing. + +The disadvantage is that, being specific to Catch, no existing build servers understand the format natively. It can be used as input to an XSLT transformation that could covert it to, say, HTML - although this loses the streaming advantage, of course. + +## JUnit Reporter +```-r junit``` + +The JUnit Reporter writes in an XML format that mimics the JUnit ANT schema. + +The advantage of this format is that the JUnit Ant schema is widely understood by most build servers and so can usually be consumed with no additional work. + +The disadvantage is that this schema was designed to correspond to how JUnit works - and there is a significant mismatch with how Catch works. Additionally the format is not streamable (because opening elements hold counts of failed and passing tests as attributes) - so the whole test run must complete before it can be written. + +## Other reporters +Other reporters are not part of the single-header distribution and need to be downloaded and included separately. All reporters are stored in `include/reporters` directory in the git repository, and are named `catch_reporter_*.hpp`. For example, to use the TeamCity reporter you need to download `include/reporters/catch_reporter_teamcity.hpp` and include it after Catch itself. + +``` +#define CATCH_CONFIG_MAIN +#include "catch.hpp" +#include "catch_reporter_teamcity.hpp" +``` + +### TeamCity Reporter +```-r teamcity``` + +The TeamCity Reporter writes TeamCity service messages to stdout. In order to be able to use this reporter an additional header must also be included. + +Being specific to TeamCity this is the best reporter to use with it - but it is completely unsuitable for any other purpose. It is a streaming format (it writes as it goes) - although test results don't appear in the TeamCity interface until the completion of a suite (usually the whole test run). + +### Automake Reporter +```-r automake``` + +The Automake Reporter writes out the [meta tags](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html#Log-files-generation-and-test-results-recording) expected by automake via `make check`. + +### TAP (Test Anything Protocol) Reporter +```-r tap``` + +Because of the incremental nature of Catch's test suites and ability to run specific tests, our implementation of TAP reporter writes out the number of tests in a suite last. + +# Low-level tools + +## CMake + +You can use the following CMake script to automatically fetch Catch from github and configure it as an external project: + +```CMake +cmake_minimum_required(VERSION 2.8.8) +project(catch_builder CXX) +include(ExternalProject) +find_package(Git REQUIRED) + +ExternalProject_Add( + catch + PREFIX ${CMAKE_BINARY_DIR}/catch + GIT_REPOSITORY https://github.com/philsquared/Catch.git + TIMEOUT 10 + UPDATE_COMMAND ${GIT_EXECUTABLE} pull + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + ) + +# Expose required variable (CATCH_INCLUDE_DIR) to parent scope +ExternalProject_Get_Property(catch source_dir) +set(CATCH_INCLUDE_DIR ${source_dir}/single_include CACHE INTERNAL "Path to include folder for Catch") +``` + +If you put it in, e.g., `${PROJECT_SRC_DIR}/${EXT_PROJECTS_DIR}/catch/`, you can use it in your project by adding the following to your root CMake file: + +```CMake +# Includes Catch in the project: +add_subdirectory(${EXT_PROJECTS_DIR}/catch) +include_directories(${CATCH_INCLUDE_DIR} ${COMMON_INCLUDES}) +enable_testing(true) # Enables unit-testing. +``` + +--- + +[Home](Readme.md) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/command-line.md b/libraries/Lora_Serialization/test/lib/Catch/docs/command-line.md new file mode 100644 index 0000000..5afb309 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/command-line.md @@ -0,0 +1,277 @@ +Catch works quite nicely without any command line options at all - but for those times when you want greater control the following options are available. +Click one of the followings links to take you straight to that option - or scroll on to browse the available options. + + ` ...`
+ ` -h, -?, --help`
+ ` -l, --list-tests`
+ ` -t, --list-tags`
+ ` -s, --success`
+ ` -b, --break`
+ ` -e, --nothrow`
+ ` -i, --invisibles`
+ ` -o, --out`
+ ` -r, --reporter`
+ ` -n, --name`
+ ` -a, --abort`
+ ` -x, --abortx`
+ ` -w, --warn`
+ ` -d, --durations`
+ ` -f, --input-file`
+ ` -c, --section`
+ ` -#, --filenames-as-tags`
+ + +
+ + ` --list-test-names-only`
+ ` --list-reporters`
+ ` --order`
+ ` --rng-seed`
+ +
+ + + + +## Specifying which tests to run + +
<test-spec> ...
+ +Test cases, wildcarded test cases, tags and tag expressions are all passed directly as arguments. Tags are distinguished by being enclosed in square brackets. + +If no test specs are supplied then all test cases, except "hidden" tests, are run. +A test is hidden by giving it any tag starting with (or just) a period (```.```) - or, in the deprecated case, tagged ```[hide]``` or given name starting with `'./'`. To specify hidden tests from the command line ```[.]``` or ```[hide]``` can be used *regardless of how they were declared*. + +Specs must be enclosed in quotes if they contain spaces. If they do not contain spaces the quotes are optional. + +Wildcards consist of the `*` character at the beginning and/or end of test case names and can substitute for any number of any characters (including none). + +Test specs are case insensitive. + +If a spec is prefixed with `exclude:` or the `~` character then the pattern matches an exclusion. This means that tests matching the pattern are excluded from the set - even if a prior inclusion spec included them. Subsequent inclusion specs will take precendence, however. +Inclusions and exclusions are evaluated in left-to-right order. + +Test case examples: + +
thisTestOnly            Matches the test case called, 'thisTestOnly'
+"this test only"        Matches the test case called, 'this test only'
+these*                  Matches all cases starting with 'these'
+exclude:notThis         Matches all tests except, 'notThis'
+~notThis                Matches all tests except, 'notThis'
+~*private*              Matches all tests except those that contain 'private'
+a* ~ab* abc             Matches all tests that start with 'a', except those that
+                        start with 'ab', except 'abc', which is included
+
+ +Names within square brackets are interpreted as tags. +A series of tags form an AND expression wheras a comma-separated sequence forms an OR expression. e.g.: + +
[one][two],[three]
+This matches all tests tagged `[one]` and `[two]`, as well as all tests tagged `[three]` + +Test names containing special characters, such as `,` or `[` can specify them on the command line using `\`. +`\` also escapes itself. + + +## Choosing a reporter to use + +
-r, --reporter <reporter>
+ +A reporter is an object that formats and structures the output of running tests, and potentially summarises the results. By default a console reporter is used that writes, IDE friendly, textual output. Catch comes bundled with some alternative reporters, but more can be added in client code.
+The bundled reporters are: + +
-r console
+-r compact
+-r xml
+-r junit
+
+ +The JUnit reporter is an xml format that follows the structure of the JUnit XML Report ANT task, as consumed by a number of third-party tools, including Continuous Integration servers such as Hudson. If not otherwise needed, the standard XML reporter is preferred as this is a streaming reporter, whereas the Junit reporter needs to hold all its results until the end so it can write the overall results into attributes of the root node. + + +## Breaking into the debugger +
-b, --break
+ +In some IDEs (currently XCode and Visual Studio) it is possible for Catch to break into the debugger on a test failure. This can be very helpful during debug sessions - especially when there is more than one path through a particular test. + + +## Showing results for successful tests +
-s, --success
+ +Usually you only want to see reporting for failed tests. Sometimes it's useful to see *all* the output (especially when you don't trust that that test you just added worked first time!). +To see successful, as well as failing, test results just pass this option. Note that each reporter may treat this option differently. The Junit reporter, for example, logs all results regardless. + + +## Aborting after a certain number of failures +
-a, --abort
+-x, --abortx [<failure threshold>]
+
+ +If a ```REQUIRE``` assertion fails the test case aborts, but subsequent test cases are still run. +If a ```CHECK``` assertion fails even the current test case is not aborted. + +Sometimes this results in a flood of failure messages and you'd rather just see the first few. Specifying ```-a``` or ```--abort``` on its own will abort the whole test run on the first failed assertion of any kind. Use ```-x``` or ```--abortx``` followed by a number to abort after that number of assertion failures. + + +## Listing available tests, tags or reporters +
-l, --list-tests
+-t, --list-tags
+--list-reporters
+
+ +```-l``` or ```--list-tests``` will list all registered tests, along with any tags. +If one or more test-specs have been supplied too then only the matching tests will be listed. + +```-t``` or ```--list-tags``` lists all available tags, along with the number of test cases they match. Again, supplying test specs limits the tags that match. + +```--list-reporters``` lists the available reporters. + + +## Sending output to a file +
-o, --out <filename>
+
+ +Use this option to send all output to a file. By default output is sent to stdout (note that uses of stdout and stderr *from within test cases* are redirected and included in the report - so even stderr will effectively end up on stdout). + + +## Naming a test run +
-n, --name <name for test run>
+ +If a name is supplied it will be used by the reporter to provide an overall name for the test run. This can be useful if you are sending to a file, for example, and need to distinguish different test runs - either from different Catch executables or runs of the same executable with different options. If not supplied the name is defaulted to the name of the executable. + + +## Eliding assertions expected to throw +
-e, --nothrow
+ +Skips all assertions that test that an exception is thrown, e.g. ```REQUIRE_THROWS```. + +These can be a nuisance in certain debugging environments that may break when exceptions are thrown (while this is usually optional for handled exceptions, it can be useful to have enabled if you are trying to track down something unexpected). + +Sometimes exceptions are expected outside of one of the assertions that tests for them (perhaps thrown and caught within the code-under-test). The whole test case can be skipped when using ```-e``` by marking it with the ```[!throws]``` tag. + +When running with this option any throw checking assertions are skipped so as not to contribute additional noise. Be careful if this affects the behaviour of subsequent tests. + + +## Make whitespace visible +
-i, --invisibles
+ +If a string comparison fails due to differences in whitespace - especially leading or trailing whitespace - it can be hard to see what's going on. +This option transforms tabs and newline characters into ```\t``` and ```\n``` respectively when printing. + + +## Warnings +
-w, --warn <warning name>
+ +Enables reporting of warnings (only one, at time of this writing). If a warning is issued it fails the test. + +The ony available warning, presently, is ```NoAssertions```. This warning fails a test case, or (leaf) section if no assertions (```REQUIRE```/ ```CHECK``` etc) are encountered. + + +## Reporting timings +
-d, --durations <yes/no>
+ +When set to ```yes``` Catch will report the duration of each test case, in milliseconds. Note that it does this regardless of whether a test case passes or fails. Note, also, the certain reporters (e.g. Junit) always report test case durations regardless of this option being set or not. + + +## Load test names to run from a file +
-f, --input-file <filename>
+ +Provide the name of a file that contains a list of test case names - one per line. Blank lines are skipped and anything after the comment character, ```#```, is ignored. + +A useful way to generate an initial instance of this file is to use the list-test-names-only option. This can then be manually curated to specify a specific subset of tests - or in a specific order. + + +## Just test names +
--list-test-names-only
+ +This option lists all available tests in a non-indented form, one on each line. This makes it ideal for saving to a file and feeding back into the ```-f``` or ```--input-file``` option. + + + +## Specify the order test cases are run +
--order <decl|lex|rand>
+ +Test cases are ordered one of three ways: + + +### decl +Declaration order. The order the tests were originally declared in. Note that ordering between files is not guaranteed and is implementation dependent. + +### lex +Lexicographically sorted. Tests are sorted, alpha-numerically, by name. + +### rand +Randomly sorted. Test names are sorted using ```std::random_shuffle()```. By default the random number generator is seeded with 0 - and so the order is repeatable. To control the random seed see rng-seed. + + +## Specify a seed for the Random Number Generator +
--rng-seed <'time'|number>
+ +Sets a seed for the random number generator using ```std::srand()```. +If a number is provided this is used directly as the seed so the random pattern is repeatable. +Alternatively if the keyword ```time``` is provided then the result of calling ```std::time(0)``` is used and so the pattern becomes unpredictable. + +In either case the actual value for the seed is printed as part of Catch's output so if an issue is discovered that is sensitive to test ordering the ordering can be reproduced - even if it was originally seeded from ```std::time(0)```. + + +## Usage +
-h, -?, --help
+ +Prints the command line arguments to stdout + + + +## Specify the section to run +
-c, --section <section name>
+ +To limit execution to a specific section within a test case, use this option one or more times. +To narrow to sub-sections use multiple instances, where each subsequent instance specifies a deeper nesting level. + +E.g. if you have: + +
+TEST_CASE( "Test" ) {
+  SECTION( "sa" ) {
+    SECTION( "sb" ) {
+      /*...*/
+    }
+    SECTION( "sc" ) {
+      /*...*/
+    }
+  }
+  SECTION( "sd" ) {
+    /*...*/
+  }
+}
+
+ +Then you can run `sb` with: +
./MyExe Test -c sa -c sb
+ +Or run just `sd` with: +
./MyExe Test -c sd
+ +To run all of `sa`, including `sb` and `sc` use: +
./MyExe Test -c sa
+ +There are some limitations of this feature to be aware of: +- Code outside of sections being skipped will still be executed - e.g. any set-up code in the TEST_CASE before the +start of the first section.
+- At time of writing, wildcards are not supported in section names. +- If you specify a section without narrowing to a test case first then all test cases will be executed +(but only matching sections within them). + + + +## Filenames as tags +
-#, --filenames-as-tags
+ +When this option is used then every test is given an additional tag which is formed of the unqualified +filename it is found in, with any extension stripped, prefixed with the `#` character. + +So, for example, tests within the file `~\Dev\MyProject\Ferrets.cpp` would be tagged `[#Ferrets]`. + + +--- + +[Home](Readme.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/commercial-users.md b/libraries/Lora_Serialization/test/lib/Catch/docs/commercial-users.md new file mode 100644 index 0000000..53b0e70 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/commercial-users.md @@ -0,0 +1,12 @@ +# Commercial users of Catch + +As well as [Open Source](opensource-users.md) users Catch is widely used within proprietary code bases too. Many companies like to keep this +information internal, and that's fine, but if you're more open it would be great if we could list the names of as +many organisations as possible that use Catch somewhere in their codebase. Enterprise environments often tend to be +far more conservative in their tool adoption - and being aware that other companies are using Catch can ease the +path in. + +So if you are aware of Catch usage in your organisation, and are fairly confident there is no issue with sharing this +fact then please let us know - either directly, via a PR or [issue](https://github.com/philsquared/Catch/issues), or on the [forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum). + + - Bloomberg diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/configuration.md b/libraries/Lora_Serialization/test/lib/Catch/docs/configuration.md new file mode 100644 index 0000000..99b7ff2 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/configuration.md @@ -0,0 +1,100 @@ +Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```). + +Nonetheless there are still some occasions where finer control is needed. For these occasions Catch exposes a set of macros for configuring how it is built. + +# main()/ implementation + + CATCH_CONFIG_MAIN // Designates this as implementation file and defines main() + CATCH_CONFIG_RUNNER // Designates this as implementation file + +Although Catch is header only it still, internally, maintains a distinction between interface headers and headers that contain implementation. Only one source file in your test project should compile the implementation headers and this is controlled through the use of one of these macros - one of these identifiers should be defined before including Catch in *exactly one implementation file in your project*. + +# Prefixing Catch macros + + CATCH_CONFIG_PREFIX_ALL + +To keep test code clean and uncluttered Catch uses short macro names (e.g. ```TEST_CASE``` and ```REQUIRE```). Occasionally these may conflict with identifiers from platform headers or the system under test. In this case the above identifier can be defined. This will cause all the Catch user macros to be prefixed with ```CATCH_``` (e.g. ```CATCH_TEST_CASE``` and ```CATCH_REQUIRE```). + + +# Terminal colour + + CATCH_CONFIG_COLOUR_NONE // completely disables all text colouring + CATCH_CONFIG_COLOUR_WINDOWS // forces the Win32 console API to be used + CATCH_CONFIG_COLOUR_ANSI // forces ANSI colour codes to be used + +Yes, I am English, so I will continue to spell "colour" with a 'u'. + +When sending output to the terminal, if it detects that it can, Catch will use colourised text. On Windows the Win32 API, ```SetConsoleTextAttribute```, is used. On POSIX systems ANSI colour escape codes are inserted into the stream. + +For finer control you can define one of the above identifiers (these are mutually exclusive - but that is not checked so may behave unexpectedly if you mix them): + +Note that when ANSI colour codes are used "unistd.h" must be includable - along with a definition of ```isatty()``` + +Typically you should place the ```#define``` before #including "catch.hpp" in your main source file - but if you prefer you can define it for your whole project by whatever your IDE or build system provides for you to do so. + +# Console width + + CATCH_CONFIG_CONSOLE_WIDTH = x // where x is a number + +Catch formats output intended for the console to fit within a fixed number of characters. This is especially important as indentation is used extensively and uncontrolled line wraps break this. +By default a console width of 80 is assumed but this can be controlled by defining the above identifier to be a different value. + +# stdout + + CATCH_CONFIG_NOSTDOUT + +Catch does not use ```std::cout``` and ```std::cerr``` directly but gets them from ```Catch::cout()``` and ```Catch::cerr()``` respectively. If the above identifier is defined these functions are left unimplemented and you must implement them yourself. Their signatures are: + + std::ostream& cout(); + std::ostream& cerr(); + +This can be useful on certain platforms that do not provide ```std::cout``` and ```std::cerr```, such as certain embedded systems. + +# C++ conformance toggles + + CATCH_CONFIG_CPP11_NULLPTR // nullptr is supported? + CATCH_CONFIG_CPP11_NOEXCEPT // noexcept is supported? + CATCH_CONFIG_CPP11_GENERATED_METHODS // delete and default keywords for methods + CATCH_CONFIG_CPP11_IS_ENUM // std::is_enum is supported? + CATCH_CONFIG_CPP11_TUPLE // std::tuple is supported + CATCH_CONFIG_VARIADIC_MACROS // Usually pre-C++11 compiler extensions are sufficient + CATCH_CONFIG_CPP11_LONG_LONG // generates overloads for the long long type + CATCH_CONFIG_CPP11_OVERRIDE // CATCH_OVERRIDE expands to override (for virtual function implementations) + CATCH_CONFIG_CPP11_UNIQUE_PTR // Use std::unique_ptr instead of std::auto_ptr + CATCH_CONFIG_CPP11_SHUFFLE // Use std::shuffle instead of std::random_shuffle + CATCH_CONFIG_CPP11_TYPE_TRAITS // Use std::enable_if and + +Catch has some basic compiler detection that will attempt to select the appropriate mix of these macros. However being incomplete - and often without access to the respective compilers - this detection tends to be conservative. +So overriding control is given to the user. If a compiler supports a feature (and Catch does not already detect it) then one or more of these may be defined to enable it (or suppress it, in some cases). If you do do this please raise an issue, specifying your compiler version (ideally with an idea of how to detect it) and stating that it has such support. +You may also suppress any of these features by using the `_NO_` form, e.g. `CATCH_CONFIG_CPP11_NO_NULLPTR`. + +All C++11 support can be disabled with `CATCH_CONFIG_NO_CPP11` + +# Other toggles + + CATCH_CONFIG_COUNTER // Use __COUNTER__ to generate unique names for test cases + CATCH_CONFIG_WINDOWS_SEH // Enable SEH handling on Windows + CATCH_CONFIG_FAST_COMPILE // Sacrifices some (extremely minor) features for compilation speed + CATCH_CONFIG_POSIX_SIGNALS // Enable handling POSIX signals + CATCH_CONFIG_WINDOWS_CRTDBG // Enable leak checking using Windows's CRT Debug Heap + +Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support. + +At this moment, `CATCH_CONFIG_FAST_COMPILE` changes only the behaviour of the `-b` (`--break`) flag, making it break into debugger in a stack frame *below* the actual test, unlike the default behaviour, where the break into debugger occurs in the same stack frame as the actual test. `CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined, in all translation units that are linked into single test binary, or the behaviour of setting `-b` flag will be unpredictable. + +`CATCH_CONFIG_POSIX_SIGNALS` is on by default, except when Catch is compiled under `Cygwin`, where it is disabled by default (but can be force-enabled by defining `CATCH_CONFIG_POSIX_SIGNALS`). + +`CATCH_CONFIG_WINDOWS_CRTDBG` is off by default. If enabled, Windows's CRT is used to check for memory leaks, and displays them after the tests finish running. + +Just as with the C++11 conformance toggles, these toggles can be disabled by using `_NO_` form of the toggle, e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`. + +# Windows header clutter + +On Windows Catch includes `windows.h`. To minimize global namespace clutter in the implementation file, it defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including it. You can control this behaviour via two macros: + + CATCH_CONFIG_NO_NOMINMAX // Stops Catch from using NOMINMAX macro + CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN // Stops Catch from using WIN32_LEAN_AND_MEAN macro + +--- + +[Home](Readme.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/contributing.md b/libraries/Lora_Serialization/test/lib/Catch/docs/contributing.md new file mode 100644 index 0000000..28d0643 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/contributing.md @@ -0,0 +1,41 @@ +# Contributing to Catch + +So you want to contribute something to Catch? That's great! Whether it's a bug fix, a new feature, support for +additional compilers - or just a fix to the documentation - all contributions are very welcome and very much appreciated. +Of course so are bug reports and other comments and questions. + +If you are contributing to the code base there are a few simple guidelines to keep in mind. This also includes notes to +help you find your way around. As this is liable to drift out of date please raise an issue or, better still, a pull +request for this file, if you notice that. + +## Branches + +Ongoing development is currently on _master_. At some point an integration branch will be set-up and PRs should target + that - but for now it's all against master. You may see feature branches come and go from time to time, too. + +## Directory structure + +_Users_ of Catch primarily use the single header version. _Maintainers_ should work with the full source (which is still, +primarily, in headers). This can be found in the `include` folder. There are a set of test files, currently under +`projects/SelfTest`. The test app can be built via CMake from the `CMakeLists.txt` file in the root, or you can generate +project files for Visual Studio, XCode, and others (instructions in the `projects` folder). If you have access to CLion +that can work with the CMake file directly. + +As well as the runtime test files you'll also see a `SurrogateCpps` directory under `projects/SelfTest`. +This contains a set of .cpp files that each `#include` a single header. +While these files are not essential to compilation they help to keep the implementation headers self-contained. +At time of writing this set is not complete but has reasonable coverage. +If you add additional headers please try to remember to add a surrogate cpp for it. + +The other directories are `scripts` which contains a set of python scripts to help in testing Catch as well as +generating the single include, and `docs`, which contains the documentation as a set of markdown files. + +__When submitting a pull request please do not include changes to the single include, or to the version number file +as these are managed by the scripts!__ + + + *this document is still in-progress...* + +--- + +[Home](Readme.md) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/limitations.md b/libraries/Lora_Serialization/test/lib/Catch/docs/limitations.md new file mode 100644 index 0000000..bee4a29 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/limitations.md @@ -0,0 +1,99 @@ +# Known limitations + +Catch has some known limitations, that we are not planning to change. Some of these are caused by our desire to support C++98 compilers, some of these are caused by our desire to keep Catch crossplatform, some exist because their priority is seen as low compared to the development effort they would need and some other yet are compiler/runtime bugs. + +## Features +This section outlines some missing features, what is their status and their possible workarounds. + +### Thread safe assertions +Because threading support in standard C++98 is limited (well, non-existent), assertion macros in Catch are not thread safe. This does not mean that you cannot use threads inside Catch's test, but that only single thread can interact with Catch's assertions and other macros. + +This means that this is ok +```cpp + std::vector threads; + std::atomic cnt{ 0 }; + for (int i = 0; i < 4; ++i) { + threads.emplace_back([&]() { + ++cnt; ++cnt; ++cnt; ++cnt; + }); + } + for (auto& t : threads) { t.join(); } + REQUIRE(cnt == 16); +``` +because only one thread passes the `REQUIRE` macro and this is not +```cpp + std::vector threads; + std::atomic cnt{ 0 }; + for (int i = 0; i < 4; ++i) { + threads.emplace_back([&]() { + ++cnt; ++cnt; ++cnt; ++cnt; + CHECK(cnt == 16); + }); + } + for (auto& t : threads) { t.join(); } + REQUIRE(cnt == 16); +``` + + +_This limitation is highly unlikely to be lifted before Catch 2 is released._ + +### Process isolation in a test +Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available. + +### Running multiple tests in parallel +Catch's test execution is strictly serial. If you find yourself with a test suite that takes too long to run and you want to make it parallel, there are 2 feasible solutions + * You can split your tests into multiple binaries and then run these binaries in parallel. + * You can have Catch list contained test cases and then run the same test binary multiple times in parallel, passing each instance list of test cases it should run. + +Both of these solutions have their problems, but should let you wring parallelism out of your test suite. + +## 3rd party bugs +This section outlines known bugs in 3rd party components (this means compilers, standard libraries, standard runtimes). + +### Visual Studio 2013 -- do-while loop withing range based for fails to compile (C2059) +There is a known bug in Visual Studio 2013 (VC 12), that causes compilation error if range based for is followed by an assertion macro, without enclosing the block in braces. This snippet is sufficient to trigger the error +```cpp +#define CATCH_CONFIG_MAIN +#include "catch.hpp" + +TEST_CASE("Syntax error with VC12") { + for ( auto x : { 1 , 2, 3 } ) + REQUIRE( x < 3.14 ); +} +``` +An easy workaround is possible, use braces: +```cpp +#define CATCH_CONFIG_MAIN +#include "catch.hpp" + +TEST_CASE("No longer a syntax error with VC12") { + for ( auto x : { 1 , 2, 3 } ) { + REQUIRE( x < 3.14 ); + } +} +``` + +### Visual Studio 2003 -- Syntax error caused by improperly expanded `__LINE__` macro +Older version of Visual Studio can have trouble compiling Catch, not expanding the `__LINE__` macro properly when recompiling the test binary. This is caused by Edit and Continue being on. + +A workaround is to turn off Edit and Continue when compiling the test binary. + +### Clang/G++ -- skipping leaf sections after an exception +Some versions of `libc++` and `libstdc++` (or their runtimes) have a bug with `std::uncaught_exception()` getting stuck returning `true` after rethrow, even if there are no active exceptions. One such case is this snippet, which skipped the sections "a" and "b", when compiled against `libcxxrt` from master +```cpp +#define CATCH_CONFIG_MAIN +#include + +TEST_CASE("a") { + CHECK_THROWS(throw 3); +} + +TEST_CASE("b") { + int i = 0; + SECTION("a") { i = 1; } + SECTION("b") { i = 2; } + CHECK(i > 0); +} +``` + +If you are seeing a problem like this, i.e. a weird test paths that trigger only under Clang with `libc++`, or only under very specific version of `libstdc++`, it is very likely you are seeing this. The only known workaround is to use a fixed version of your standard library. diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/logging.md b/libraries/Lora_Serialization/test/lib/Catch/docs/logging.md new file mode 100644 index 0000000..a659b3e --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/logging.md @@ -0,0 +1,52 @@ +# Logging macros + +Additional messages can be logged during a test case. + +## Streaming macros + +All these macros allow heterogenous sequences of values to be streaming using the insertion operator (```<<```) in the same way that std::ostream, std::cout, etc support it. + +E.g.: +```c++ +INFO( "The number is " << i ); +``` + +(Note that there is no initial ```<<``` - instead the insertion sequence is placed in parentheses.) +These macros come in three forms: + +**INFO(** _message expression_ **)** + +The message is logged to a buffer, but only reported with the next assertion that is logged. This allows you to log contextual information in case of failures which is not shown during a successful test run (for the console reporter, without -s). Messages are removed from the buffer at the end of their scope, so may be used, for example, in loops. + +**WARN(** _message expression_ **)** + +The message is always reported but does not fail the test. + +**FAIL(** _message expression_ **)** + +The message is reported and the test case fails. + +## Quickly capture a variable value + +**CAPTURE(** _expression_ **)** + +Sometimes you just want to log the name and value of a variable. While you can easily do this with the INFO macro, above, as a convenience the CAPTURE macro handles the stringising of the variable name for you (actually it works with any expression, not just variables). + +E.g. +```c++ +CAPTURE( theAnswer ); +``` + +This would log something like: + +
"theAnswer := 42"
+ +## Deprecated macros + +**SCOPED_INFO and SCOPED_CAPTURE** + +These macros are now deprecated and are just aliases for INFO and CAPTURE (which were not previously scoped). + +--- + +[Home](Readme.md) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/matchers.md b/libraries/Lora_Serialization/test/lib/Catch/docs/matchers.md new file mode 100644 index 0000000..93f6a27 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/matchers.md @@ -0,0 +1,103 @@ +# Matchers + +Matchers are an alternative way to do assertions which are easily extensible and composable. +This makes them well suited to use with more complex types (such as collections) or your own custom types. +Matchers were first popularised by the [Hamcrest](https://en.wikipedia.org/wiki/Hamcrest) family of frameworks. + +## In use + +Matchers are introduced with the `REQUIRE_THAT` or `CHECK_THAT` macros, which take two arguments. +The first argument is the thing (object or value) under test. The second part is a match _expression_, +which consists of either a single matcher or one or more matchers combined using `&&`, `||` or `!` operators. + +For example, to assert that a string ends with a certain substring: + + ```c++ +std::string str = getStringFromSomewhere(); +REQUIRE_THAT( str, EndsWith( "as a service" ) ); + ``` + +The matcher objects can take multiple arguments, allowing more fine tuning. +The built-in string matchers, for example, take a second argument specifying whether the comparison is +case sensitive or not: + +```c++ +REQUIRE_THAT( str, EndsWith( "as a service", Catch::CaseSensitive::No ) ); + ``` + +And matchers can be combined: + +```c++ +REQUIRE_THAT( str, + EndsWith( "as a service" ) || + (StartsWith( "Big data" ) && !Contains( "web scale" ) ) ); +``` + +## Built in matchers +Currently Catch has some string matchers and some vector matchers. +The string matchers are `StartsWith`, `EndsWith`, `Contains` and `Equals`. Each of them also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive). +The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector. + + +## Custom matchers +It's easy to provide your own matchers to extend Catch or just to work with your own types. + +You need to provide two things: +1. A matcher class, derived from `Catch::MatcherBase` - where `T` is the type being tested. +The constructor takes and stores any arguments needed (e.g. something to compare against) and you must +override two methods: `match()` and `describe()`. +2. A simple builder function. This is what is actually called from the test code and allows overloading. + +Here's an example for asserting that an integer falls within a given range +(note that it is all inline for the sake of keeping the example short): + +```c++ +// The matcher class +class IntRange : public Catch::MatcherBase { + int m_begin, m_end; +public: + IntRange( int begin, int end ) : m_begin( begin ), m_end( end ) {} + + // Performs the test for this matcher + virtual bool match( int const& i ) const override { + return i >= m_begin && i <= m_end; + } + + // Produces a string describing what this matcher does. It should + // include any provided data (the begin/ end in this case) and + // be written as if it were stating a fact (in the output it will be + // preceded by the value under test). + virtual std::string describe() const { + std::ostringstream ss; + ss << "is between " << m_begin << " and " << m_end; + return ss.str(); + } +}; + +// The builder function +inline IntRange IsBetween( int begin, int end ) { + return IntRange( begin, end ); +} + +// ... + +// Usage +TEST_CASE("Integers are within a range") +{ + CHECK_THAT( 3, IsBetween( 1, 10 ) ); + CHECK_THAT( 100, IsBetween( 1, 10 ) ); +} +``` + +Running this test gives the following in the console: + +``` +/**/TestFile.cpp:123: FAILED: + CHECK_THAT( 100, IsBetween( 1, 10 ) ) +with expansion: + 100 is between 1 and 10 +``` + +--- + +[Home](Readme.md) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/opensource-users.md b/libraries/Lora_Serialization/test/lib/Catch/docs/opensource-users.md new file mode 100644 index 0000000..b0a89eb --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/opensource-users.md @@ -0,0 +1,59 @@ +# Open Source projects using Catch + +Catch is great for open source. With it's [liberal license](../LICENSE_1_0.txt) and single-header, dependency-free, distribution +it's easy to just drop the header into your project and start writing tests - what's not to like? + +As a result Catch is now being used in many Open Source projects, including some quite well known ones. +This page is an attempt to track those projects. Obviously it can never be complete. +This effort largely relies on the maintainers of the projects themselves updating this page and submitting a PR +(or, if you prefer contact one of the maintainers of Catch directly, use the +[forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)), or raise an [issue](https://github.com/philsquared/Catch/issues) to let us know). +Of course users of those projects might want to update this page too. That's fine - as long you're confident the project maintainers won't mind. +If you're an Open Source project maintainer and see your project listed here but would rather it wasn't - +just let us know via any of the previously mentioned means - although I'm sure there won't be many who feel that way. + +Listing a project here does not imply endorsement and the plan is to keep these ordered alphabetically to avoid an implication of relative importance. + +## Libraries & Frameworks + +### [Azmq](https://github.com/zeromq/azmq) +Boost Asio style bindings for ZeroMQ + +### [ChakraCore](https://github.com/Microsoft/ChakraCore) +The core part of the Chakra Javascript engine that powers Microsoft Edge + +### [ChaiScript](https://github.com/ChaiScript/ChaiScript) +A, header-only, embedded scripting language designed from the ground up to directly target C++ and take advantage of modern C++ development techniques + +### [Couchbase-lite-core](https://github.com/couchbase/couchbase-lite-core) +The next-generation core storage and query engine for Couchbase Lite/ + +### [JSON for Modern C++](https://github.com/nlohmann/json) +A, single-header, JSON parsing library that takes advantage of what C++ has to offer. + +### [MNMLSTC Core](https://github.com/mnmlstc/core) +a small and easy to use C++11 library that adds a functionality set that will be available in C++14 and later, as well as some useful additions + +### [SOCI](https://github.com/SOCI/soci) +The C++ Database Access Library + +### [Ppconsul](https://github.com/oliora/ppconsul) +A C++ client library for Consul. Consul is a distributed tool for discovering and configuring services in your infrastructure + +### [Reactive-Extensions/ RxCpp](https://github.com/Reactive-Extensions/RxCpp) +A library of algorithms for values-distributed-in-time + +### [Trompeloeil](https://github.com/rollbear/trompeloeil) +A thread safe header only mocking framework for C++14 + +## Applications & Tools + +### [MAME](https://github.com/mamedev/mame) +MAME originally stood for Multiple Arcade Machine Emulator + +### [Standardese](https://github.com/foonathan/standardese) +Standardese aims to be a nextgen Doxygen + +--- + +[Home](Readme.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/own-main.md b/libraries/Lora_Serialization/test/lib/Catch/docs/own-main.md new file mode 100644 index 0000000..67e551f --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/own-main.md @@ -0,0 +1,72 @@ +# Supplying main() yourself + +The easiest way to use Catch is to let it supply ```main()``` for you and handle configuring itself from the command line. + +This is achieved by writing ```#define CATCH_CONFIG_MAIN``` before the ```#include "catch.hpp"``` in *exactly one* source file. + +Sometimes, though, you need to write your own version of main(). You can do this by writing ```#define CATCH_CONFIG_RUNNER``` instead. Now you are free to write ```main()``` as normal and call into Catch yourself manually. + +You now have a lot of flexibility - but here are three recipes to get your started: + +## Let Catch take full control of args and config + +If you just need to have code that executes before and/ or after Catch this is the simplest option. + +```c++ +#define CATCH_CONFIG_RUNNER +#include "catch.hpp" + +int main( int argc, char* argv[] ) +{ + // global setup... + + int result = Catch::Session().run( argc, argv ); + + // global clean-up... + + return ( result < 0xff ? result : 0xff ); +} +``` + +## Amending the config + +If you still want Catch to process the command line, but you want to programatically tweak the config, you can do so in one of two ways: + +```c++ +#define CATCH_CONFIG_RUNNER +#include "catch.hpp" + +int main( int argc, char* argv[] ) +{ + Catch::Session session; // There must be exactly one instance + + // writing to session.configData() here sets defaults + // this is the preferred way to set them + + int returnCode = session.applyCommandLine( argc, argv ); + if( returnCode != 0 ) // Indicates a command line error + return returnCode; + + // writing to session.configData() or session.Config() here + // overrides command line args + // only do this if you know you need to + + int numFailed = session.run(); + // Note that on unices only the lower 8 bits are usually used, clamping + // the return value to 255 prevents false negative when some multiple + // of 256 tests has failed + return ( numFailed < 0xff ? numFailed : 0xff ); +} +``` + +Take a look at the definitions of Config and ConfigData to see what you can do with them. + +To take full control of the config simply omit the call to ```applyCommandLine()```. + +## Adding your own command line options + +Catch embeds a powerful command line parser which you can also use to parse your own options out. This capability is still in active development but will be documented here when it is ready. + +--- + +[Home](Readme.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/release-notes.md b/libraries/Lora_Serialization/test/lib/Catch/docs/release-notes.md new file mode 100644 index 0000000..3820111 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/release-notes.md @@ -0,0 +1,150 @@ +# 1.8.1 + +### Fixes + +Cygwin issue with `gettimeofday` - `#define` was not early enough + +# 1.8.0 + +### New features/ minor changes + +* Matchers have new, simpler (and documented) interface. + * Catch provides string and vector matchers. + * For details see [Matchers documentation](matchers.md). +* Changed console reporter test duration reporting format (#322) + * Old format: `Some simple comparisons between doubles completed in 0.000123s` + * New format: `xxx.123s: Some simple comparisons between doubles` _(There will always be exactly 3 decimal places)_ +* Added opt-in leak detection under MSVC + Windows (#439) + * Enable it by compiling Catch's main with `CATCH_CONFIG_WINDOWS_CRTDBG` +* Introduced new compile-time flag, `CATCH_CONFIG_FAST_COMPILE`, trading features for compilation speed. + * Moves debug breaks out of tests and into implementation, speeding up compilation time + * _More changes are coming_ +* Added [TAP (Test Anything Protocol)](https://testanything.org/) and [Automake](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html#Log-files-generation-and-test-results-recording) reporters. + * These are not present in the default single-include header and need to be downloaded from GitHub separately. + * For details see [documentation about integrating with build systems](build-systems.md). +* XML reporter now reports filename as part of the `Section` and `TestCase` tags. +* `Approx` now supports an optional margin of absolute error + * It has also received [new documentation](). + +### Fixes +* Silenced C4312 ("conversion from int to 'ClassName *") warnings in the evaluate layer. +* Fixed C4512 ("assignment operator could not be generated") warnings under VS2013. +* Cygwin compatibility fixes + * Signal handling is no longer compiled by default. + * Usage of `gettimeofday` inside Catch should no longer cause compilation errors. +* Improved `-Wparentheses` supression for gcc (#674) + * When compiled with gcc 4.8 or newer, the supression is localized to assertions only + * Otherwise it is supressed for the whole TU +* Fixed test spec parser issue (with escapes in multiple names) + +### Other +* Various documentation fixes and improvements + + +# 1.7.2 + +### Fixes and minor improvements +Xml: + +(technically the first two are breaking changes but are also fixes and arguably break few if any people) +* C-escape control characters instead of XML encoding them (which requires XML 1.1) +* Revert XML output to XML 1.0 +* Can provide stylesheet references by extending the XML reporter +* Added description and tags attribites to XML Reporter +* Tags are closed and the stream flushed more eagerly to avoid stdout interpolation + + +Other: +* `REQUIRE_THROWS_AS` now catches exception by `const&` and reports expected type +* In `SECTION`s the file/ line is now of the `SECTION`. not the `TEST_CASE` +* Added std:: qualification to some functions from C stdlib +* Removed use of RTTI (`dynamic_cast`) that had crept back in +* Silenced a few more warnings in different circumstances +* Travis improvements + +# 1.7.1 + +### Fixes: +* Fixed inconsistency in defining `NOMINMAX` and `WIN32_LEAN_AND_MEAN` inside `catch.hpp`. +* Fixed SEH-related compilation error under older MinGW compilers, by making Windows SEH handling opt-in for compilers other than MSVC. + * For specifics, look into the [documentation](docs/configuration.md). +* Fixed compilation error under MinGW caused by improper compiler detection. +* Fixed XML reporter sometimes leaving an empty output file when a test ends with signal/structured exception. +* Fixed XML reporter not reporting captured stdout/stderr. +* Fixed possible infinite recursion in Windows SEH. +* Fixed possible compilation error caused by Catch's operator overloads being ambiguous in regards to user-defined templated operators. + +## 1.7.0 + +### Features/ Changes: +* Catch now runs significantly faster for passing tests + * Microbenchmark focused on Catch's overhead went from ~3.4s to ~0.7s. + * Real world test using [JSON for Modern C++](https://github.com/nlohmann/json)'s test suite went from ~6m 25s to ~4m 14s. +* Catch can now run specific sections within test cases. + * For now the support is only basic (no wildcards or tags), for details see the [documentation](docs/command-line.md). +* Catch now supports SEH on Windows as well as signals on Linux. + * After receiving a signal, Catch reports failing assertion and then passes the signal onto the previous handler. +* Approx can be used to compare values against strong typedefs (available in C++11 mode only). + * Strong typedefs mean types that are explicitly convertible to double. +* CHECK macro no longer stops executing section if an exception happens. +* Certain characters (space, tab, etc) are now pretty printed. + * This means that a `char c = ' '; REQUIRE(c == '\t');` would be printed as `' ' == '\t'`, instead of ` == 9`. + +### Fixes: +* Text formatting no longer attempts to access out-of-bounds characters under certain conditions. +* THROW family of assertions no longer trigger `-Wunused-value` on expressions containing explicit cast. +* Breaking into debugger under OS X works again and no longer required `DEBUG` to be defined. +* Compilation no longer breaks under certain compiler if a lambda is used inside assertion macro. + +### Other: +* Catch's CMakeLists now defines install command. +* Catch's CMakeLists now generates projects with warnings enabled. + + +## 1.6.1 + +### Features/ Changes: +* Catch now supports breaking into debugger on Linux + +### Fixes: +* Generators no longer leak memory (generators are still unsupported in general) +* JUnit reporter now reports UTC timestamps, instead of "tbd" +* `CHECK_THAT` macro is now properly defined as `CATCH_CHECK_THAT` when using `CATCH_` prefixed macros + +### Other: +* Types with overloaded `&&` operator are no longer evaluated twice when used in an assertion macro. +* The use of `__COUNTER__` is supressed when Catch is parsed by CLion + * This change is not active when compiling a binary +* Approval tests can now be run on Windows +* CMake will now warn if a file is present in the `include` folder but not is not enumerated as part of the project +* Catch now defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including `windows.h` + * This can be disabled if needed, see [documentation](docs/configuration.md) for details. + + +## 1.6.0 + +### Cmake/ projects: +* Moved CMakeLists.txt to root, made it friendlier for CLion and generating XCode and VS projects, and removed the manually maintained XCode and VS projects. + +### Features/ Changes: +* Approx now supports `>=` and `<=` +* Can now use `\` to escape chars in test names on command line +* Standardize C++11 feature toggles + +### Fixes: +* Blue shell colour +* Missing argument to `CATCH_CHECK_THROWS` +* Don't encode extended ASCII in XML +* use `std::shuffle` on more compilers (fixes deprecation warning/error) +* Use `__COUNTER__` more consistently (where available) + +### Other: +* Tweaks and changes to scripts - particularly for Approval test - to make them more portable + + +# Older versions +Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history + +--- + +[Home](Readme.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/slow-compiles.md b/libraries/Lora_Serialization/test/lib/Catch/docs/slow-compiles.md new file mode 100644 index 0000000..a12d086 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/slow-compiles.md @@ -0,0 +1,64 @@ +# Why do my tests take so long to compile? + +Several people have reported that test code written with Catch takes much longer to compile than they would expect. Why is that? + +Catch is implemented entirely in headers. There is a little overhead due to this - but not as much as you might think - and you can minimise it simply by organising your test code as follows: + +## Short answer +Exactly one source file must ```#define``` either ```CATCH_CONFIG_MAIN``` or ```CATCH_CONFIG_RUNNER``` before ```#include```-ing Catch. In this file *do not write any test cases*! In most cases that means this file will just contain two lines (the ```#define``` and the ```#include```). + +## Long answer + +Usually C++ code is split between a header file, containing declarations and prototypes, and an implementation file (.cpp) containing the definition, or implementation, code. Each implementation file, along with all the headers that it includes (and which those headers include, etc), is expanded into a single entity called a translation unit - which is then passed to the compiler and compiled down to an object file. + +But functions and methods can also be written inline in header files. The downside to this is that these definitions will then be compiled in *every* translation unit that includes the header. + +Because Catch is implemented *entirely* in headers you might think that the whole of Catch must be compiled into every translation unit that uses it! Actually it's not quite as bad as that. Catch mitigates this situation by effectively maintaining the traditional separation between the implementation code and declarations. Internally the implementation code is protected by ```#ifdef```s and is conditionally compiled into only one translation unit. This translation unit is that one that ```#define```s ```CATCH_CONFIG_MAIN``` or ```CATCH_CONFIG_RUNNER```. Let's call this the main source file. + +As a result the main source file *does* compile the whole of Catch every time! So it makes sense to dedicate this file to *only* ```#define```-ing the identifier and ```#include```-ing Catch (and implementing the runner code, if you're doing that). Keep all your test cases in other files. This way you won't pay the recompilation cost for the whole of Catch + +## Practical example +Assume you have the `Factorial` function from the [tutorial](tutorial.md) in `factorial.cpp` (with forward declaration in `factorial.h`) and want to test it and keep the compile times down when adding new tests. Then you should have 2 files, `tests-main.cpp` and `tests-factorial.cpp`: + +```cpp +// tests-main.cpp +#define CATCH_CONFIG_MAIN +#include "catch.hpp" +``` + +```cpp +// tests-factorial.cpp +#include "catch.hpp" + +#include "factorial.h" + +TEST_CASE( "Factorials are computed", "[factorial]" ) { + REQUIRE( Factorial(1) == 1 ); + REQUIRE( Factorial(2) == 2 ); + REQUIRE( Factorial(3) == 6 ); + REQUIRE( Factorial(10) == 3628800 ); +} +``` + +After compiling `tests-main.cpp` once, it is enough to link it with separately compiled `tests-factorial.cpp`. This means that adding more tests to `tests-factorial.cpp`, will not result in recompiling Catch's main and the resulting compilation times will decrease substantially. + +``` +$ g++ tests-main.cpp -c +$ g++ tests-main.o tests-factorial.cpp -o tests && ./tests -r compact +Passed 1 test case with 4 assertions. +``` + +Now, the next time we change the file `tests-factorial.cpp` (say we add `REQUIRE( Factorial(0) == 1)`), it is enough to recompile the tests instead of recompiling main as well: + +``` +$ g++ tests-main.o tests-factorial.cpp -o tests && ./tests -r compact +tests-factorial.cpp:11: failed: Factorial(0) == 1 for: 0 == 1 +Failed 1 test case, failed 1 assertion. +``` + +## Other possible solutions +You can also opt to sacrifice some features in order to speed-up Catch's compilation times. For details see the [documentation on Catch's compile-time configuration](configuration.md#other-toggles). + +--- + +[Home](Readme.md) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/test-cases-and-sections.md b/libraries/Lora_Serialization/test/lib/Catch/docs/test-cases-and-sections.md new file mode 100644 index 0000000..809935b --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/test-cases-and-sections.md @@ -0,0 +1,88 @@ +# Test cases and sections + +While Catch fully supports the traditional, xUnit, style of class-based fixtures containing test case methods this is not the preferred style. + +Instead Catch provides a powerful mechanism for nesting test case sections within a test case. For a more detailed discussion see the [tutorial](tutorial.md#test-cases-and-sections). + +Test cases and sections are very easy to use in practice: + +* **TEST_CASE(** _test name_ \[, _tags_ \] **)** +* **SECTION(** _section name_ **)** + +_test name_ and _section name_ are free form, quoted, strings. The optional _tags_ argument is a quoted string containing one or more tags enclosed in square brackets. Tags are discussed below. Test names must be unique within the Catch executable. + +For examples see the [Tutorial](tutorial.md) + +## Tags + +Tags allow an arbitrary number of additional strings to be associated with a test case. Test cases can be selected (for running, or just for listing) by tag - or even by an expression that combines several tags. At their most basic level they provide a simple way to group several related tests together. + +As an example - given the following test cases: + + TEST_CASE( "A", "[widget]" ) { /* ... */ } + TEST_CASE( "B", "[widget]" ) { /* ... */ } + TEST_CASE( "C", "[gadget]" ) { /* ... */ } + TEST_CASE( "D", "[widget][gadget]" ) { /* ... */ } + +The tag expression, ```"[widget]"``` selects A, B & D. ```"[gadget]"``` selects C & D. ```"[widget][gadget]"``` selects just D and ```"[widget],[gadget]"``` selects all four test cases. + +For more detail on command line selection see [the command line docs](command-line.md#specifying-which-tests-to-run) + +Tag names are not case sensitive. + +### Special Tags + +All tag names beginning with non-alphanumeric characters are reserved by Catch. Catch defines a number of "special" tags, which have meaning to the test runner itself. These special tags all begin with a symbol character. Following is a list of currently defined special tags and their meanings. + +* `[!hide]` or `[.]` (or, for legacy reasons, `[hide]`) - causes test cases to be skipped from the default list (i.e. when no test cases have been explicitly selected through tag expressions or name wildcards). The hide tag is often combined with another, user, tag (for example `[.][integration]` - so all integration tests are excluded from the default run but can be run by passing `[integration]` on the command line). As a short-cut you can combine these by simply prefixing your user tag with a `.` - e.g. `[.integration]`. Because the hide tag has evolved to have several forms, all forms are added as tags if you use one of them. + +* `[!throws]` - lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be excluded when running with `-e` or `--nothrow`. + +* `[!shouldfail]` - reverse the failing logic of the test: if the test is successful if it fails, and vice-versa. + +* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in the your tests. + +* `[!nonportable]` - Indicates that behaviour may vary between platforms or compilers. + +* `[#]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped) as a tag. e.g. tests in testfile.cpp would all be tagged `[#testfile]`. + +* `[@]` - tag aliases all begin with `@` (see below). + +## Tag aliases + +Between tag expressions and wildcarded test names (as well as combinations of the two) quite complex patterns can be constructed to direct which test cases are run. If a complex pattern is used often it is convenient to be able to create an alias for the expression. this can be done, in code, using the following form: + + CATCH_REGISTER_TAG_ALIAS( , ) + +Aliases must begin with the `@` character. An example of a tag alias is: + + CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" ) + +Now when `[@nhf]` is used on the command line this matches all tests that are tagged `[failing]`, but which are not also hidden. + +## BDD-style test cases + +In addition to Catch's take on the classic style of test cases, Catch supports an alternative syntax that allow tests to be written as "executable specifications" (one of the early goals of [Behaviour Driven Development](http://dannorth.net/introducing-bdd/)). This set of macros map on to ```TEST_CASE```s and ```SECTION```s, with a little internal support to make them smoother to work with. + +* **SCENARIO(** _scenario name_ \[, _tags_ \] **)** + +This macro maps onto ```TEST_CASE``` and works in the same way, except that the test case name will be prefixed by "Scenario: " + +* **GIVEN(** _something_ **)** +* **WHEN(** _something_ **)** +* **THEN(** _something_ **)** + +These macros map onto ```SECTION```s except that the section names are the _something_s prefixed by "given: ", "when: " or "then: " respectively. + +* **AND_WHEN(** _something_ **)** +* **AND_THEN(** _something_ **)** + +Similar to ```WHEN``` and ```THEN``` except that the prefixes start with "and ". These are used to chain ```WHEN```s and ```THEN```s together. + +When any of these macros are used the console reporter recognises them and formats the test case header such that the Givens, Whens and Thens are aligned to aid readability. + +Other than the additional prefixes and the formatting in the console reporter these macros behave exactly as ```TEST_CASE```s and ```SECTION```s. As such there is nothing enforcing the correct sequencing of these macros - that's up to the programmer! + +--- + +[Home](Readme.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/test-fixtures.md b/libraries/Lora_Serialization/test/lib/Catch/docs/test-fixtures.md new file mode 100644 index 0000000..fc546b3 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/test-fixtures.md @@ -0,0 +1,32 @@ +Although Catch allows you to group tests together as sections within a test case, it can still be convenient, sometimes, to group them using a more traditional test fixture. Catch fully supports this too. You define the test fixture as a simple structure: + +```c++ +class UniqueTestsFixture { + private: + static int uniqueID; + protected: + DBConnection conn; + public: + UniqueTestsFixture() : conn(DBConnection::createConnection("myDB")) { + } + protected: + int getID() { + return ++uniqueID; + } + }; + + int UniqueTestsFixture::uniqueID = 0; + + TEST_CASE_METHOD(UniqueTestsFixture, "Create Employee/No Name", "[create]") { + REQUIRE_THROWS(conn.executeSQL("INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "")); + } + TEST_CASE_METHOD(UniqueTestsFixture, "Create Employee/Normal", "[create]") { + REQUIRE(conn.executeSQL("INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "Joe Bloggs")); + } +``` + +The two test cases here will create uniquely-named derived classes of UniqueTestsFixture and thus can access the `getID()` protected method and `conn` member variables. This ensures that both the test cases are able to create a DBConnection using the same method (DRY principle) and that any ID's created are unique such that the order that tests are executed does not matter. + +--- + +[Home](Readme.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/tostring.md b/libraries/Lora_Serialization/test/lib/Catch/docs/tostring.md new file mode 100644 index 0000000..dbb6cb8 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/tostring.md @@ -0,0 +1,70 @@ +# String conversions + +Catch needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes). +Most built-in or std types are supported out of the box but there are three ways that you can tell Catch how to convert your own types (or other, third-party types) into strings. + +## operator << overload for std::ostream + +This is the standard way of providing string conversions in C++ - and the chances are you may already provide this for your own purposes. If you're not familiar with this idiom it involves writing a free function of the form: + +``` +std::ostream& operator << ( std::ostream& os, T const& value ) { + os << convertMyTypeToString( value ); + return os; +} +``` + +(where ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable - it doesn't have to be in another function). + +You should put this function in the same namespace as your type. + +Alternatively you may prefer to write it as a member function: + +``` +std::ostream& T::operator << ( std::ostream& os ) const { + os << convertMyTypeToString( *this ); + return os; +} +``` + +## Catch::toString overload + +If you don't want to provide an ```operator <<``` overload, or you want to convert your type differently for testing purposes, you can provide an overload for ```Catch::toString()``` for your type. + +``` +namespace Catch { + std::string toString( T const& value ) { + return convertMyTypeToString( value ); + } +} +``` + +Again ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable. Note that the function must be in the Catch namespace, which itself must be in the global namespace. + +## Catch::StringMaker specialisation + +There are some cases where overloading toString does not work as expected. Specialising StringMaker gives you more precise, and reliable, control - but at the cost of slightly more code and complexity: + +``` +namespace Catch { + template<> struct StringMaker { + static std::string convert( T const& value ) { + return convertMyTypeToString( value ); + } + }; +} +``` + +## Exceptions + +By default all exceptions deriving from `std::exception` will be translated to strings by calling the `what()` method. For exception types that do not derive from `std::exception` - or if `what()` does not return a suitable string - use `CATCH_TRANSLATE_EXCEPTION`. This defines a function that takes your exception type, by reference, and returns a string. It can appear anywhere in the code - it doesn't have to be in the same translation unit. For example: + +``` +CATCH_TRANSLATE_EXCEPTION( MyType& ex ) { + return ex.message(); +} +``` + +--- + +[Home](Readme.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/tutorial.md b/libraries/Lora_Serialization/test/lib/Catch/docs/tutorial.md new file mode 100644 index 0000000..7392459 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/tutorial.md @@ -0,0 +1,249 @@ +# Getting Catch + +The simplest way to get Catch is to download the latest [single header version](https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file. + +The full source for Catch, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there. + + +## Where to put it? + +Catch is header only. All you need to do is drop the file(s) somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](http://www.levelofindirection.com/journal/2011/5/27/unit-testing-in-c-and-objective-c-just-got-ridiculously-easi.html). + +The rest of this tutorial will assume that the Catch single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary. + +# Writing tests + +Let's start with a really simple example. Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now). + +```c++ +unsigned int Factorial( unsigned int number ) { + return number <= 1 ? number : Factorial(number-1)*number; +} +``` + +To keep things simple we'll put everything in a single file (see later for more on how to structure your test files) + +```c++ +#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file +#include "catch.hpp" + +unsigned int Factorial( unsigned int number ) { + return number <= 1 ? number : Factorial(number-1)*number; +} + +TEST_CASE( "Factorials are computed", "[factorial]" ) { + REQUIRE( Factorial(1) == 1 ); + REQUIRE( Factorial(2) == 2 ); + REQUIRE( Factorial(3) == 6 ); + REQUIRE( Factorial(10) == 3628800 ); +} +``` + +This will compile to a complete executable which responds to [command line arguments](command-line.md). If you just run it with no arguments it will execute all test cases (in this case there is just one), report any failures, report a summary of how many tests passed and failed and return the number of failed tests (useful for if you just want a yes/ no answer to: "did it work"). + +If you run this as written it will pass. Everything is good. Right? +Well, there is still a bug here. In fact the first version of this tutorial I posted here genuinely had the bug in! So it's not completely contrived (thanks to Daryle Walker (```@CTMacUser```) for pointing this out). + +What is the bug? Well what is the factorial of zero? +[The factorial of zero is one](http://mathforum.org/library/drmath/view/57128.html) - which is just one of those things you have to know (and remember!). + +Let's add that to the test case: + +```c++ +TEST_CASE( "Factorials are computed", "[factorial]" ) { + REQUIRE( Factorial(0) == 1 ); + REQUIRE( Factorial(1) == 1 ); + REQUIRE( Factorial(2) == 2 ); + REQUIRE( Factorial(3) == 6 ); + REQUIRE( Factorial(10) == 3628800 ); +} +``` + +Now we get a failure - something like: + +``` +Example.cpp:9: FAILED: + REQUIRE( Factorial(0) == 1 ) +with expansion: + 0 == 1 +``` + +Note that we get the actual return value of Factorial(0) printed for us (0) - even though we used a natural expression with the == operator. That let's us immediately see what the problem is. + +Let's change the factorial function to: + +```c++ +unsigned int Factorial( unsigned int number ) { + return number > 1 ? Factorial(number-1)*number : 1; +} +``` + +Now all the tests pass. + +Of course there are still more issues to do deal with. For example we'll hit problems when the return value starts to exceed the range of an unsigned int. With factorials that can happen quite quickly. You might want to add tests for such cases and decide how to handle them. We'll stop short of doing that here. + +## What did we do here? + +Although this was a simple test it's been enough to demonstrate a few things about how Catch is used. Let's take moment to consider those before we move on. + +1. All we did was ```#define``` one identifier and ```#include``` one header and we got everything - even an implementation of ```main()``` that will [respond to command line arguments](command-line.md). You can only use that ```#define``` in one implementation file, for (hopefully) obvious reasons. Once you have more than one file with unit tests in you'll just ```#include "catch.hpp"``` and go. Usually it's a good idea to have a dedicated implementation file that just has ```#define CATCH_CONFIG_MAIN``` and ```#include "catch.hpp"```. You can also provide your own implementation of main and drive Catch yourself (see [Supplying-your-own-main()](own-main.md)). +2. We introduce test cases with the ```TEST_CASE``` macro. This macro takes one or two arguments - a free form test name and, optionally, one or more tags (for more see Test cases and Sections, ). The test name must be unique. You can run sets of tests by specifying a wildcarded test name or a tag expression. See the [command line docs](command-line.md) for more information on running tests. +3. The name and tags arguments are just strings. We haven't had to declare a function or method - or explicitly register the test case anywhere. Behind the scenes a function with a generated name is defined for you, and automatically registered using static registry classes. By abstracting the function name away we can name our tests without the constraints of identifier names. +4. We write our individual test assertions using the ```REQUIRE``` macro. Rather than a separate macro for each type of condition we express the condition naturally using C/C++ syntax. Behind the scenes a simple set of expression templates captures the left-hand-side and right-hand-side of the expression so we can display the values in our test report. As we'll see later there _are_ other assertion macros - but because of this technique the number of them is drastically reduced. + + +## Test cases and sections + +Most test frameworks have a class-based fixture mechanism. That is, test cases map to methods on a class and common setup and teardown can be performed in ```setup()``` and ```teardown()``` methods (or constructor/ destructor in languages, like C++, that support deterministic destruction). + +While Catch fully supports this way of working there are a few problems with the approach. In particular the way your code must be split up, and the blunt granularity of it, may cause problems. You can only have one setup/ teardown pair across a set of methods, but sometimes you want slightly different setup in each method, or you may even want several levels of setup (a concept which we will clarify later on in this tutorial). It was problems like these that led James Newkirk, who led the team that built NUnit, to start again from scratch and build xUnit). + +Catch takes a different approach (to both NUnit and xUnit) that is a more natural fit for C++ and the C family of languages. This is best explained through an example: + +```c++ +TEST_CASE( "vectors can be sized and resized", "[vector]" ) { + + std::vector v( 5 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 5 ); + + SECTION( "resizing bigger changes size and capacity" ) { + v.resize( 10 ); + + REQUIRE( v.size() == 10 ); + REQUIRE( v.capacity() >= 10 ); + } + SECTION( "resizing smaller changes size but not capacity" ) { + v.resize( 0 ); + + REQUIRE( v.size() == 0 ); + REQUIRE( v.capacity() >= 5 ); + } + SECTION( "reserving bigger changes capacity but not size" ) { + v.reserve( 10 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 10 ); + } + SECTION( "reserving smaller does not change size or capacity" ) { + v.reserve( 0 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 5 ); + } +} +``` + +For each ```SECTION``` the ```TEST_CASE``` is executed from the start - so as we enter each section we know that size is 5 and capacity is at least 5. We enforced those requirements with the ```REQUIRE```s at the top level so we can be confident in them. +This works because the ```SECTION``` macro contains an if statement that calls back into Catch to see if the section should be executed. One leaf section is executed on each run through a ```TEST_CASE```. The other sections are skipped. Next time through the next section is executed, and so on until no new sections are encountered. + +So far so good - this is already an improvement on the setup/teardown approach because now we see our setup code inline and use the stack. + +The power of sections really shows, however, when we need to execute a sequence of, checked, operations. Continuing the vector example, we might want to verify that attempting to reserve a capacity smaller than the current capacity of the vector changes nothing. We can do that, naturally, like so: + +```c++ + SECTION( "reserving bigger changes capacity but not size" ) { + v.reserve( 10 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 10 ); + + SECTION( "reserving smaller again does not change capacity" ) { + v.reserve( 7 ); + + REQUIRE( v.capacity() >= 10 ); + } + } +``` + +Sections can be nested to an arbitrary depth (limited only by your stack size). Each leaf section (i.e. a section that contains no nested sections) will be executed exactly once, on a separate path of execution from any other leaf section (so no leaf section can interfere with another). A failure in a parent section will prevent nested sections from running - but then that's the idea. + +## BDD-Style + +If you name your test cases and sections appropriately you can achieve a BDD-style specification structure. This became such a useful way of working that first class support has been added to Catch. Scenarios can be specified using ```SCENARIO```, ```GIVEN```, ```WHEN``` and ```THEN``` macros, which map on to ```TEST_CASE```s and ```SECTION```s, respectively. For more details see [Test cases and sections](test-cases-and-sections.md). + +The vector example can be adjusted to use these macros like so: + +```c++ +SCENARIO( "vectors can be sized and resized", "[vector]" ) { + + GIVEN( "A vector with some items" ) { + std::vector v( 5 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 5 ); + + WHEN( "the size is increased" ) { + v.resize( 10 ); + + THEN( "the size and capacity change" ) { + REQUIRE( v.size() == 10 ); + REQUIRE( v.capacity() >= 10 ); + } + } + WHEN( "the size is reduced" ) { + v.resize( 0 ); + + THEN( "the size changes but not capacity" ) { + REQUIRE( v.size() == 0 ); + REQUIRE( v.capacity() >= 5 ); + } + } + WHEN( "more capacity is reserved" ) { + v.reserve( 10 ); + + THEN( "the capacity changes but not the size" ) { + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 10 ); + } + } + WHEN( "less capacity is reserved" ) { + v.reserve( 0 ); + + THEN( "neither size nor capacity are changed" ) { + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 5 ); + } + } + } +} +``` + +Conveniently, these tests will be reported as follows when run: + +``` +Scenario: vectors can be sized and resized + Given: A vector with some items + When: more capacity is reserved + Then: the capacity changes but not the size +``` + + +## Scaling up + +To keep the tutorial simple we put all our code in a single file. This is fine to get started - and makes jumping into Catch even quicker and easier. As you write more real-world tests, though, this is not really the best approach. + +The requirement is that the following block of code ([or equivalent](own-main.md)): + +```c++ +#define CATCH_CONFIG_MAIN +#include "catch.hpp" +``` + +appears in _exactly one_ source file. Use as many additional cpp files (or whatever you call your implementation files) as you need for your tests, partitioned however makes most sense for your way of working. Each additional file need only ```#include "catch.hpp"``` - do not repeat the ```#define```! + +In fact it is usually a good idea to put the block with the ```#define``` [in its own source file](slow-compiles.md). + +Do not write your tests in header files! + + +## Next steps + +This has been a brief introduction to get you up and running with Catch, and to point out some of the key differences between Catch and other frameworks you may already be familiar with. This will get you going quite far already and you are now in a position to dive in and write some tests. + +Of course there is more to learn - most of which you should be able to page-fault in as you go. Please see the ever-growing [Reference section](Readme.md) for what's available. + +--- + +[Home](Readme.md) diff --git a/libraries/Lora_Serialization/test/lib/Catch/docs/why-catch.md b/libraries/Lora_Serialization/test/lib/Catch/docs/why-catch.md new file mode 100644 index 0000000..b77ca2c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/docs/why-catch.md @@ -0,0 +1,46 @@ +# Why do we need yet another C++ test framework? + +Good question. For C++ there are quite a number of established frameworks, including (but not limited to), [CppUnit](http://sourceforge.net/apps/mediawiki/cppunit/index.php?title=Main_Page), [Google Test](http://code.google.com/p/googletest/), [Boost.Test](http://www.boost.org/doc/libs/1_49_0/libs/test/doc/html/index.html), [Aeryn](https://launchpad.net/aeryn), [Cute](http://r2.ifs.hsr.ch/cute), [Fructose](http://fructose.sourceforge.net/) and [many, many more](http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B). Even for Objective-C there are a few, including OCUnit - which now comes bundled with XCode. + +So what does Catch bring to the party that differentiates it from these? Apart from a Catchy name, of course. + +## Key Features + +* Really easy to get started. Just download catch.hpp, #include it and you're away. +* No external dependencies. As long as you can compile C++98 and have a C++ standard library available. +* Write test cases as, self-registering, functions or methods. +* Divide test cases into sections, each of which is run in isolation (eliminates the need for fixtures!) +* Use BDD-style Given-When-Then sections as well as traditional unit test cases. +* Only one core assertion macro for comparisons. Standard C/C++ operators are used for the comparison - yet the full expression is decomposed and lhs and rhs values are logged. + +## Other core features + +* Tests are named using free-form strings - no more couching names in legal identifiers. +* Tests can be tagged for easily running ad-hoc groups of tests. +* Failures can (optionally) break into the debugger on Windows and Mac. +* Output is through modular reporter objects. Basic textual and XML reporters are included. Custom reporters can easily be added. +* JUnit xml output is supported for integration with third-party tools, such as CI servers. +* A default main() function is provided (in a header), but you can supply your own for complete control (e.g. integration into your own test runner GUI). +* A command line parser is provided and can still be used if you choose to provided your own main() function. +* Catch can test itself. +* Alternative assertion macro(s) report failures but don't abort the test case +* Floating point tolerance comparisons are built in using an expressive Approx() syntax. +* Internal and friendly macros are isolated so name clashes can be managed +* Support for Matchers (early stages) + +## Objective-C-specific features + +* Automatically detects if you are using it from an Objective-C project +* Works with and without ARC with no additional configuration +* Implement test fixtures using Obj-C classes too (like OCUnit) +* Additional built in matchers that work with Obj-C types (e.g. string matchers) + +## Who else is using Catch? + +See the list of [open source projects using Catch](opensource-users.md). + +See the [tutorial](tutorial.md) to get more of a taste of using CATCH in practice + +--- + +[Home](Readme.md) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/catch.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/catch.hpp new file mode 100644 index 0000000..5d009ee --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/catch.hpp @@ -0,0 +1,237 @@ +/* + * Created by Phil on 22/10/2010. + * Copyright 2010 Two Blue Cubes Ltd + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifndef TWOBLUECUBES_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_HPP_INCLUDED + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +#include "internal/catch_suppress_warnings.h" + +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +#endif + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +#include "internal/catch_notimplemented_exception.h" +#include "internal/catch_context.h" +#include "internal/catch_test_registry.hpp" +#include "internal/catch_capture.hpp" +#include "internal/catch_section.h" +#include "internal/catch_generators.hpp" +#include "internal/catch_interfaces_exception.h" +#include "internal/catch_approx.hpp" +#include "internal/catch_matchers_string.h" +#include "internal/catch_matchers_vector.h" +#include "internal/catch_compiler_capabilities.h" +#include "internal/catch_interfaces_tag_alias_registry.h" + +// These files are included here so the single_include script doesn't put them +// in the conditionally compiled sections +#include "internal/catch_test_case_info.h" +#include "internal/catch_interfaces_runner.h" + +#ifdef __OBJC__ +#include "internal/catch_objc.hpp" +#endif + +#ifdef CATCH_IMPL + +// !TBD: Move the leak detector code into a separate header +#ifdef CATCH_CONFIG_WINDOWS_CRTDBG +#include +class LeakDetector { +public: + LeakDetector() { + int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + flag |= _CRTDBG_LEAK_CHECK_DF; + flag |= _CRTDBG_ALLOC_MEM_DF; + _CrtSetDbgFlag(flag); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + // Change this to leaking allocation's number to break there + _CrtSetBreakAlloc(-1); + } +}; +#else +class LeakDetector {}; +#endif + +LeakDetector leakDetector; + +#include "internal/catch_impl.hpp" +#endif + +#ifdef CATCH_CONFIG_MAIN +#include "internal/catch_default_main.hpp" +#endif + + +#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED +# undef CLARA_CONFIG_MAIN +#endif + +////// + +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" ) +#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" ) + +#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" ) +#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" ) +#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" ) +#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" ) + +#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" ) +#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" ) +#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" ) +#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" ) +#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" ) + +#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CATCH_CHECK_THROWS" ) +#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" ) +#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" ) +#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" ) + +#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) +#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) + +#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) +#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg ) +#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) +#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << Catch::toString(msg), "CATCH_CAPTURE" ) +#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << Catch::toString(msg), "CATCH_CAPTURE" ) + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) + #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) + #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) + #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) + #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) + #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) + #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ ) +#else + #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) + #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) + #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) + #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description ) + #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) + #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg ) + #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg ) +#endif +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) + +#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) +#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) + +#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) + +// "BDD-style" convenience wrappers +#ifdef CATCH_CONFIG_VARIADIC_MACROS +#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#else +#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) +#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) +#endif +#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" ) +#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" ) +#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) +#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" ) +#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" ) +#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" ) + +#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" ) +#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" ) +#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" ) +#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" ) + +#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" ) +#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" ) +#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" ) +#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" ) +#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" ) + +#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" ) +#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" ) +#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" ) +#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" ) + +#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) +#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) + +#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) +#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg ) +#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) +#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << Catch::toString(msg), "CAPTURE" ) +#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << Catch::toString(msg), "CAPTURE" ) + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) + #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) + #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) + #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) + #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) + #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ ) + #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ ) +#else + #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) + #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) + #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) + #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description ) + #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) + #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg ) + #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg ) +#endif +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) + +#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) +#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) + +#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) + +#endif + +#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) + +// "BDD-style" convenience wrappers +#ifdef CATCH_CONFIG_VARIADIC_MACROS +#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#else +#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) +#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) +#endif +#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" ) +#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" ) +#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" ) +#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" ) +#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" ) + +using Catch::Detail::Approx; + +#include "internal/catch_reenable_warnings.h" + +#endif // TWOBLUECUBES_CATCH_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/catch_session.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/catch_session.hpp new file mode 100644 index 0000000..a9c3366 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/catch_session.hpp @@ -0,0 +1,219 @@ +/* + * Created by Phil on 31/10/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED + +#include "internal/catch_commandline.hpp" +#include "internal/catch_list.hpp" +#include "internal/catch_run_context.hpp" +#include "internal/catch_test_spec.hpp" +#include "internal/catch_version.h" +#include "internal/catch_text.h" + +#include +#include +#include + +namespace Catch { + + Ptr createReporter( std::string const& reporterName, Ptr const& config ) { + Ptr reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() ); + if( !reporter ) { + std::ostringstream oss; + oss << "No reporter registered with name: '" << reporterName << "'"; + throw std::domain_error( oss.str() ); + } + return reporter; + } + + Ptr makeReporter( Ptr const& config ) { + std::vector reporters = config->getReporterNames(); + if( reporters.empty() ) + reporters.push_back( "console" ); + + Ptr reporter; + for( std::vector::const_iterator it = reporters.begin(), itEnd = reporters.end(); + it != itEnd; + ++it ) + reporter = addReporter( reporter, createReporter( *it, config ) ); + return reporter; + } + Ptr addListeners( Ptr const& config, Ptr reporters ) { + IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners(); + for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end(); + it != itEnd; + ++it ) + reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) ); + return reporters; + } + + + Totals runTests( Ptr const& config ) { + + Ptr iconfig = config.get(); + + Ptr reporter = makeReporter( config ); + reporter = addListeners( iconfig, reporter ); + + RunContext context( iconfig, reporter ); + + Totals totals; + + context.testGroupStarting( config->name(), 1, 1 ); + + TestSpec testSpec = config->testSpec(); + if( !testSpec.hasFilters() ) + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests + + std::vector const& allTestCases = getAllTestCasesSorted( *iconfig ); + for( std::vector::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end(); + it != itEnd; + ++it ) { + if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) ) + totals += context.runTest( *it ); + else + reporter->skipTest( *it ); + } + + context.testGroupEnded( iconfig->name(), totals, 1, 1 ); + return totals; + } + + void applyFilenamesAsTags( IConfig const& config ) { + std::vector const& tests = getAllTestCasesSorted( config ); + for(std::size_t i = 0; i < tests.size(); ++i ) { + TestCase& test = const_cast( tests[i] ); + std::set tags = test.tags; + + std::string filename = test.lineInfo.file; + std::string::size_type lastSlash = filename.find_last_of( "\\/" ); + if( lastSlash != std::string::npos ) + filename = filename.substr( lastSlash+1 ); + + std::string::size_type lastDot = filename.find_last_of( "." ); + if( lastDot != std::string::npos ) + filename = filename.substr( 0, lastDot ); + + tags.insert( "#" + filename ); + setTags( test, tags ); + } + } + + class Session : NonCopyable { + static bool alreadyInstantiated; + + public: + + struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; + + Session() + : m_cli( makeCommandLineParser() ) { + if( alreadyInstantiated ) { + std::string msg = "Only one instance of Catch::Session can ever be used"; + Catch::cerr() << msg << std::endl; + throw std::logic_error( msg ); + } + alreadyInstantiated = true; + } + ~Session() { + Catch::cleanUp(); + } + + void showHelp( std::string const& processName ) { + Catch::cout() << "\nCatch v" << libraryVersion << "\n"; + + m_cli.usage( Catch::cout(), processName ); + Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; + } + + int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { + try { + m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); + m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData ); + if( m_configData.showHelp ) + showHelp( m_configData.processName ); + m_config.reset(); + } + catch( std::exception& ex ) { + { + Colour colourGuard( Colour::Red ); + Catch::cerr() + << "\nError(s) in input:\n" + << Text( ex.what(), TextAttributes().setIndent(2) ) + << "\n\n"; + } + m_cli.usage( Catch::cout(), m_configData.processName ); + return (std::numeric_limits::max)(); + } + return 0; + } + + void useConfigData( ConfigData const& _configData ) { + m_configData = _configData; + m_config.reset(); + } + + int run( int argc, char const* const* const argv ) { + + int returnCode = applyCommandLine( argc, argv ); + if( returnCode == 0 ) + returnCode = run(); + return returnCode; + } + + int run() { + if( m_configData.showHelp ) + return 0; + + try + { + config(); // Force config to be constructed + + seedRng( *m_config ); + + if( m_configData.filenamesAsTags ) + applyFilenamesAsTags( *m_config ); + + // Handle list request + if( Option listed = list( config() ) ) + return static_cast( *listed ); + + return static_cast( runTests( m_config ).assertions.failed ); + } + catch( std::exception& ex ) { + Catch::cerr() << ex.what() << std::endl; + return (std::numeric_limits::max)(); + } + } + + Clara::CommandLine const& cli() const { + return m_cli; + } + std::vector const& unusedTokens() const { + return m_unusedTokens; + } + ConfigData& configData() { + return m_configData; + } + Config& config() { + if( !m_config ) + m_config = new Config( m_configData ); + return *m_config; + } + private: + Clara::CommandLine m_cli; + std::vector m_unusedTokens; + ConfigData m_configData; + Ptr m_config; + }; + + bool Session::alreadyInstantiated = false; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/catch_with_main.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/catch_with_main.hpp new file mode 100644 index 0000000..54aa651 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/catch_with_main.hpp @@ -0,0 +1,14 @@ + /* + * Created by Phil on 01/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED + +#define CATCH_CONFIG_MAIN +#include "catch.hpp" + +#endif // TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/external/clara.h b/libraries/Lora_Serialization/test/lib/Catch/include/external/clara.h new file mode 100644 index 0000000..a999a37 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/external/clara.h @@ -0,0 +1,1051 @@ +/* + * Created by Phil on 25/05/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// Version 0.0.2.4 + +// Only use header guard if we are not using an outer namespace +#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) + +#ifndef STITCH_CLARA_OPEN_NAMESPACE +#define TWOBLUECUBES_CLARA_H_INCLUDED +#define STITCH_CLARA_OPEN_NAMESPACE +#define STITCH_CLARA_CLOSE_NAMESPACE +#else +#define STITCH_CLARA_CLOSE_NAMESPACE } +#endif + + +#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE + +// ----------- #included from tbc_text_format.h ----------- + +/* + * Created by Phil on 18/4/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +// Only use header guard if we are not using an outer namespace +#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) +#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +#define TBC_TEXT_FORMAT_H_INCLUDED +#endif + +#include +#include +#include +#include + +// Use optional outer namespace +#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { +#endif + +namespace Tbc { + +#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH + const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + struct TextAttributes { + TextAttributes() + : initialIndent( std::string::npos ), + indent( 0 ), + width( consoleWidth-1 ), + tabChar( '\t' ) + {} + + TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } + TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } + TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } + TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } + + std::size_t initialIndent; // indent of first line, or npos + std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos + std::size_t width; // maximum width of text, including indent. Longer text will wrap + char tabChar; // If this char is seen the indent is changed to current pos + }; + + class Text { + public: + Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) + : attr( _attr ) + { + std::string wrappableChars = " [({.,/|\\-"; + std::size_t indent = _attr.initialIndent != std::string::npos + ? _attr.initialIndent + : _attr.indent; + std::string remainder = _str; + + while( !remainder.empty() ) { + if( lines.size() >= 1000 ) { + lines.push_back( "... message truncated due to excessive size" ); + return; + } + std::size_t tabPos = std::string::npos; + std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); + std::size_t pos = remainder.find_first_of( '\n' ); + if( pos <= width ) { + width = pos; + } + pos = remainder.find_last_of( _attr.tabChar, width ); + if( pos != std::string::npos ) { + tabPos = pos; + if( remainder[width] == '\n' ) + width--; + remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); + } + + if( width == remainder.size() ) { + spliceLine( indent, remainder, width ); + } + else if( remainder[width] == '\n' ) { + spliceLine( indent, remainder, width ); + if( width <= 1 || remainder.size() != 1 ) + remainder = remainder.substr( 1 ); + indent = _attr.indent; + } + else { + pos = remainder.find_last_of( wrappableChars, width ); + if( pos != std::string::npos && pos > 0 ) { + spliceLine( indent, remainder, pos ); + if( remainder[0] == ' ' ) + remainder = remainder.substr( 1 ); + } + else { + spliceLine( indent, remainder, width-1 ); + lines.back() += "-"; + } + if( lines.size() == 1 ) + indent = _attr.indent; + if( tabPos != std::string::npos ) + indent += tabPos; + } + } + } + + void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { + lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); + _remainder = _remainder.substr( _pos ); + } + + typedef std::vector::const_iterator const_iterator; + + const_iterator begin() const { return lines.begin(); } + const_iterator end() const { return lines.end(); } + std::string const& last() const { return lines.back(); } + std::size_t size() const { return lines.size(); } + std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } + std::string toString() const { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + + inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { + for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); + it != itEnd; ++it ) { + if( it != _text.begin() ) + _stream << "\n"; + _stream << *it; + } + return _stream; + } + + private: + std::string str; + TextAttributes attr; + std::vector lines; + }; + +} // end namespace Tbc + +#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +} // end outer namespace +#endif + +#endif // TBC_TEXT_FORMAT_H_INCLUDED + +// ----------- end of #include from tbc_text_format.h ----------- +// ........... back in clara.h + +#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE + + +// ----------- #included from clara_compilers.h ----------- + +/* + * Created by Phil on 10/02/2016. + * Copyright 2016 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED +#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED + +// Detect a number of compiler features - mostly C++11/14 conformance - by compiler +// The following features are defined: +// +// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported? +// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported? +// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods +// CLARA_CONFIG_CPP11_OVERRIDE : is override supported? +// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) + +// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported? + +// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported? + +// In general each macro has a _NO_ form +// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11 + +#ifdef __clang__ + +#if __has_feature(cxx_nullptr) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +#if __has_feature(cxx_noexcept) +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#endif + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// GCC +#ifdef __GNUC__ + +#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +// - otherwise more recent versions define __cplusplus >= 201103L +// and will get picked up below + +#endif // __GNUC__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +#if (_MSC_VER >= 1600) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#endif + +#endif // _MSC_VER + + +//////////////////////////////////////////////////////////////////////////////// +// C++ language feature support + +// catch all support for C++11 +#if defined(__cplusplus) && __cplusplus >= 201103L + +#define CLARA_CPP11_OR_GREATER + +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#endif + +#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#endif + +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) +#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE +#endif +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) +#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + + +#endif // __cplusplus >= 201103L + +// Now set the actual defines based on the above + anything the user has configured +#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_NULLPTR +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_NOEXCEPT +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_GENERATED_METHODS +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_OVERRIDE +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_UNIQUE_PTR +#endif + + +// noexcept support: +#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT) +#define CLARA_NOEXCEPT noexcept +# define CLARA_NOEXCEPT_IS(x) noexcept(x) +#else +#define CLARA_NOEXCEPT throw() +# define CLARA_NOEXCEPT_IS(x) +#endif + +// nullptr support +#ifdef CLARA_CONFIG_CPP11_NULLPTR +#define CLARA_NULL nullptr +#else +#define CLARA_NULL NULL +#endif + +// override support +#ifdef CLARA_CONFIG_CPP11_OVERRIDE +#define CLARA_OVERRIDE override +#else +#define CLARA_OVERRIDE +#endif + +// unique_ptr support +#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR +# define CLARA_AUTO_PTR( T ) std::unique_ptr +#else +# define CLARA_AUTO_PTR( T ) std::auto_ptr +#endif + +#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED + + +// ----------- end of #include from clara_compilers.h ----------- +// ........... back in clara.h + + +#include +#include +#include + +#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +#define CLARA_PLATFORM_WINDOWS +#endif + + +// Use optional outer namespace +#ifdef STITCH_CLARA_OPEN_NAMESPACE +STITCH_CLARA_OPEN_NAMESPACE +#endif + +namespace Clara { + + struct UnpositionalTag {}; + + extern UnpositionalTag _; + +#ifdef CLARA_CONFIG_MAIN + UnpositionalTag _; +#endif + + namespace Detail { + +#ifdef CLARA_CONSOLE_WIDTH + const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + using namespace Tbc; + + inline bool startsWith( std::string const& str, std::string const& prefix ) { + return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; + } + + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + + template struct IsBool { static const bool value = false; }; + template<> struct IsBool { static const bool value = true; }; + + template + void convertInto( std::string const& _source, T& _dest ) { + std::stringstream ss; + ss << _source; + ss >> _dest; + if( ss.fail() ) + throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); + } + inline void convertInto( std::string const& _source, std::string& _dest ) { + _dest = _source; + } + char toLowerCh(char c) { + return static_cast( ::tolower( c ) ); + } + inline void convertInto( std::string const& _source, bool& _dest ) { + std::string sourceLC = _source; + std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh ); + if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) + _dest = true; + else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) + _dest = false; + else + throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); + } + + + template + struct IArgFunction { + virtual ~IArgFunction() {} +#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS + IArgFunction() = default; + IArgFunction( IArgFunction const& ) = default; +#endif + virtual void set( ConfigT& config, std::string const& value ) const = 0; + virtual bool takesArg() const = 0; + virtual IArgFunction* clone() const = 0; + }; + + template + class BoundArgFunction { + public: + BoundArgFunction() : functionObj( CLARA_NULL ) {} + BoundArgFunction( IArgFunction* _functionObj ) : functionObj( _functionObj ) {} + BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {} + BoundArgFunction& operator = ( BoundArgFunction const& other ) { + IArgFunction* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL; + delete functionObj; + functionObj = newFunctionObj; + return *this; + } + ~BoundArgFunction() { delete functionObj; } + + void set( ConfigT& config, std::string const& value ) const { + functionObj->set( config, value ); + } + bool takesArg() const { return functionObj->takesArg(); } + + bool isSet() const { + return functionObj != CLARA_NULL; + } + private: + IArgFunction* functionObj; + }; + + + template + struct NullBinder : IArgFunction{ + virtual void set( C&, std::string const& ) const {} + virtual bool takesArg() const { return true; } + virtual IArgFunction* clone() const { return new NullBinder( *this ); } + }; + + template + struct BoundDataMember : IArgFunction{ + BoundDataMember( M C::* _member ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + convertInto( stringValue, p.*member ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundDataMember( *this ); } + M C::* member; + }; + template + struct BoundUnaryMethod : IArgFunction{ + BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + typename RemoveConstRef::type value; + convertInto( stringValue, value ); + (p.*member)( value ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundUnaryMethod( *this ); } + void (C::*member)( M ); + }; + template + struct BoundNullaryMethod : IArgFunction{ + BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + bool value; + convertInto( stringValue, value ); + if( value ) + (p.*member)(); + } + virtual bool takesArg() const { return false; } + virtual IArgFunction* clone() const { return new BoundNullaryMethod( *this ); } + void (C::*member)(); + }; + + template + struct BoundUnaryFunction : IArgFunction{ + BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} + virtual void set( C& obj, std::string const& stringValue ) const { + bool value; + convertInto( stringValue, value ); + if( value ) + function( obj ); + } + virtual bool takesArg() const { return false; } + virtual IArgFunction* clone() const { return new BoundUnaryFunction( *this ); } + void (*function)( C& ); + }; + + template + struct BoundBinaryFunction : IArgFunction{ + BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} + virtual void set( C& obj, std::string const& stringValue ) const { + typename RemoveConstRef::type value; + convertInto( stringValue, value ); + function( obj, value ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundBinaryFunction( *this ); } + void (*function)( C&, T ); + }; + + } // namespace Detail + + inline std::vector argsToVector( int argc, char const* const* const argv ) { + std::vector args( static_cast( argc ) ); + for( std::size_t i = 0; i < static_cast( argc ); ++i ) + args[i] = argv[i]; + + return args; + } + + class Parser { + enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional }; + Mode mode; + std::size_t from; + bool inQuotes; + public: + + struct Token { + enum Type { Positional, ShortOpt, LongOpt }; + Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} + Type type; + std::string data; + }; + + Parser() : mode( None ), from( 0 ), inQuotes( false ){} + + void parseIntoTokens( std::vector const& args, std::vector& tokens ) { + const std::string doubleDash = "--"; + for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i ) + parseIntoTokens( args[i], tokens); + } + + void parseIntoTokens( std::string const& arg, std::vector& tokens ) { + for( std::size_t i = 0; i <= arg.size(); ++i ) { + char c = arg[i]; + if( c == '"' ) + inQuotes = !inQuotes; + mode = handleMode( i, c, arg, tokens ); + } + } + Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + switch( mode ) { + case None: return handleNone( i, c ); + case MaybeShortOpt: return handleMaybeShortOpt( i, c ); + case ShortOpt: + case LongOpt: + case SlashOpt: return handleOpt( i, c, arg, tokens ); + case Positional: return handlePositional( i, c, arg, tokens ); + default: throw std::logic_error( "Unknown mode" ); + } + } + + Mode handleNone( std::size_t i, char c ) { + if( inQuotes ) { + from = i; + return Positional; + } + switch( c ) { + case '-': return MaybeShortOpt; +#ifdef CLARA_PLATFORM_WINDOWS + case '/': from = i+1; return SlashOpt; +#endif + default: from = i; return Positional; + } + } + Mode handleMaybeShortOpt( std::size_t i, char c ) { + switch( c ) { + case '-': from = i+1; return LongOpt; + default: from = i; return ShortOpt; + } + } + Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + if( std::string( ":=\0", 3 ).find( c ) == std::string::npos ) + return mode; + + std::string optName = arg.substr( from, i-from ); + if( mode == ShortOpt ) + for( std::size_t j = 0; j < optName.size(); ++j ) + tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) ); + else if( mode == SlashOpt && optName.size() == 1 ) + tokens.push_back( Token( Token::ShortOpt, optName ) ); + else + tokens.push_back( Token( Token::LongOpt, optName ) ); + return None; + } + Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos ) + return mode; + + std::string data = arg.substr( from, i-from ); + tokens.push_back( Token( Token::Positional, data ) ); + return None; + } + }; + + template + struct CommonArgProperties { + CommonArgProperties() {} + CommonArgProperties( Detail::BoundArgFunction const& _boundField ) : boundField( _boundField ) {} + + Detail::BoundArgFunction boundField; + std::string description; + std::string detail; + std::string placeholder; // Only value if boundField takes an arg + + bool takesArg() const { + return !placeholder.empty(); + } + void validate() const { + if( !boundField.isSet() ) + throw std::logic_error( "option not bound" ); + } + }; + struct OptionArgProperties { + std::vector shortNames; + std::string longName; + + bool hasShortName( std::string const& shortName ) const { + return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end(); + } + bool hasLongName( std::string const& _longName ) const { + return _longName == longName; + } + }; + struct PositionalArgProperties { + PositionalArgProperties() : position( -1 ) {} + int position; // -1 means non-positional (floating) + + bool isFixedPositional() const { + return position != -1; + } + }; + + template + class CommandLine { + + struct Arg : CommonArgProperties, OptionArgProperties, PositionalArgProperties { + Arg() {} + Arg( Detail::BoundArgFunction const& _boundField ) : CommonArgProperties( _boundField ) {} + + using CommonArgProperties::placeholder; // !TBD + + std::string dbgName() const { + if( !longName.empty() ) + return "--" + longName; + if( !shortNames.empty() ) + return "-" + shortNames[0]; + return "positional args"; + } + std::string commands() const { + std::ostringstream oss; + bool first = true; + std::vector::const_iterator it = shortNames.begin(), itEnd = shortNames.end(); + for(; it != itEnd; ++it ) { + if( first ) + first = false; + else + oss << ", "; + oss << "-" << *it; + } + if( !longName.empty() ) { + if( !first ) + oss << ", "; + oss << "--" << longName; + } + if( !placeholder.empty() ) + oss << " <" << placeholder << ">"; + return oss.str(); + } + }; + + typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr; + + friend void addOptName( Arg& arg, std::string const& optName ) + { + if( optName.empty() ) + return; + if( Detail::startsWith( optName, "--" ) ) { + if( !arg.longName.empty() ) + throw std::logic_error( "Only one long opt may be specified. '" + + arg.longName + + "' already specified, now attempting to add '" + + optName + "'" ); + arg.longName = optName.substr( 2 ); + } + else if( Detail::startsWith( optName, "-" ) ) + arg.shortNames.push_back( optName.substr( 1 ) ); + else + throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" ); + } + friend void setPositionalArg( Arg& arg, int position ) + { + arg.position = position; + } + + + class ArgBuilder { + public: + ArgBuilder( Arg* arg ) : m_arg( arg ) {} + + // Bind a non-boolean data member (requires placeholder string) + template + void bind( M C::* field, std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundDataMember( field ); + m_arg->placeholder = placeholder; + } + // Bind a boolean data member (no placeholder required) + template + void bind( bool C::* field ) { + m_arg->boundField = new Detail::BoundDataMember( field ); + } + + // Bind a method taking a single, non-boolean argument (requires a placeholder string) + template + void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); + m_arg->placeholder = placeholder; + } + + // Bind a method taking a single, boolean argument (no placeholder string required) + template + void bind( void (C::* unaryMethod)( bool ) ) { + m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); + } + + // Bind a method that takes no arguments (will be called if opt is present) + template + void bind( void (C::* nullaryMethod)() ) { + m_arg->boundField = new Detail::BoundNullaryMethod( nullaryMethod ); + } + + // Bind a free function taking a single argument - the object to operate on (no placeholder string required) + template + void bind( void (* unaryFunction)( C& ) ) { + m_arg->boundField = new Detail::BoundUnaryFunction( unaryFunction ); + } + + // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) + template + void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundBinaryFunction( binaryFunction ); + m_arg->placeholder = placeholder; + } + + ArgBuilder& describe( std::string const& description ) { + m_arg->description = description; + return *this; + } + ArgBuilder& detail( std::string const& detail ) { + m_arg->detail = detail; + return *this; + } + + protected: + Arg* m_arg; + }; + + class OptBuilder : public ArgBuilder { + public: + OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} + OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} + + OptBuilder& operator[]( std::string const& optName ) { + addOptName( *ArgBuilder::m_arg, optName ); + return *this; + } + }; + + public: + + CommandLine() + : m_boundProcessName( new Detail::NullBinder() ), + m_highestSpecifiedArgPosition( 0 ), + m_throwOnUnrecognisedTokens( false ) + {} + CommandLine( CommandLine const& other ) + : m_boundProcessName( other.m_boundProcessName ), + m_options ( other.m_options ), + m_positionalArgs( other.m_positionalArgs ), + m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ), + m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens ) + { + if( other.m_floatingArg.get() ) + m_floatingArg.reset( new Arg( *other.m_floatingArg ) ); + } + + CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) { + m_throwOnUnrecognisedTokens = shouldThrow; + return *this; + } + + + OptBuilder operator[]( std::string const& optName ) { + m_options.push_back( Arg() ); + addOptName( m_options.back(), optName ); + OptBuilder builder( &m_options.back() ); + return builder; + } + + ArgBuilder operator[]( int position ) { + m_positionalArgs.insert( std::make_pair( position, Arg() ) ); + if( position > m_highestSpecifiedArgPosition ) + m_highestSpecifiedArgPosition = position; + setPositionalArg( m_positionalArgs[position], position ); + ArgBuilder builder( &m_positionalArgs[position] ); + return builder; + } + + // Invoke this with the _ instance + ArgBuilder operator[]( UnpositionalTag ) { + if( m_floatingArg.get() ) + throw std::logic_error( "Only one unpositional argument can be added" ); + m_floatingArg.reset( new Arg() ); + ArgBuilder builder( m_floatingArg.get() ); + return builder; + } + + template + void bindProcessName( M C::* field ) { + m_boundProcessName = new Detail::BoundDataMember( field ); + } + template + void bindProcessName( void (C::*_unaryMethod)( M ) ) { + m_boundProcessName = new Detail::BoundUnaryMethod( _unaryMethod ); + } + + void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const { + typename std::vector::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it; + std::size_t maxWidth = 0; + for( it = itBegin; it != itEnd; ++it ) + maxWidth = (std::max)( maxWidth, it->commands().size() ); + + for( it = itBegin; it != itEnd; ++it ) { + Detail::Text usage( it->commands(), Detail::TextAttributes() + .setWidth( maxWidth+indent ) + .setIndent( indent ) ); + Detail::Text desc( it->description, Detail::TextAttributes() + .setWidth( width - maxWidth - 3 ) ); + + for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { + std::string usageCol = i < usage.size() ? usage[i] : ""; + os << usageCol; + + if( i < desc.size() && !desc[i].empty() ) + os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' ) + << desc[i]; + os << "\n"; + } + } + } + std::string optUsage() const { + std::ostringstream oss; + optUsage( oss ); + return oss.str(); + } + + void argSynopsis( std::ostream& os ) const { + for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) { + if( i > 1 ) + os << " "; + typename std::map::const_iterator it = m_positionalArgs.find( i ); + if( it != m_positionalArgs.end() ) + os << "<" << it->second.placeholder << ">"; + else if( m_floatingArg.get() ) + os << "<" << m_floatingArg->placeholder << ">"; + else + throw std::logic_error( "non consecutive positional arguments with no floating args" ); + } + // !TBD No indication of mandatory args + if( m_floatingArg.get() ) { + if( m_highestSpecifiedArgPosition > 1 ) + os << " "; + os << "[<" << m_floatingArg->placeholder << "> ...]"; + } + } + std::string argSynopsis() const { + std::ostringstream oss; + argSynopsis( oss ); + return oss.str(); + } + + void usage( std::ostream& os, std::string const& procName ) const { + validate(); + os << "usage:\n " << procName << " "; + argSynopsis( os ); + if( !m_options.empty() ) { + os << " [options]\n\nwhere options are: \n"; + optUsage( os, 2 ); + } + os << "\n"; + } + std::string usage( std::string const& procName ) const { + std::ostringstream oss; + usage( oss, procName ); + return oss.str(); + } + + ConfigT parse( std::vector const& args ) const { + ConfigT config; + parseInto( args, config ); + return config; + } + + std::vector parseInto( std::vector const& args, ConfigT& config ) const { + std::string processName = args[0]; + std::size_t lastSlash = processName.find_last_of( "/\\" ); + if( lastSlash != std::string::npos ) + processName = processName.substr( lastSlash+1 ); + m_boundProcessName.set( config, processName ); + std::vector tokens; + Parser parser; + parser.parseIntoTokens( args, tokens ); + return populate( tokens, config ); + } + + std::vector populate( std::vector const& tokens, ConfigT& config ) const { + validate(); + std::vector unusedTokens = populateOptions( tokens, config ); + unusedTokens = populateFixedArgs( unusedTokens, config ); + unusedTokens = populateFloatingArgs( unusedTokens, config ); + return unusedTokens; + } + + std::vector populateOptions( std::vector const& tokens, ConfigT& config ) const { + std::vector unusedTokens; + std::vector errors; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); + for(; it != itEnd; ++it ) { + Arg const& arg = *it; + + try { + if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) || + ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) { + if( arg.takesArg() ) { + if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional ) + errors.push_back( "Expected argument to option: " + token.data ); + else + arg.boundField.set( config, tokens[++i].data ); + } + else { + arg.boundField.set( config, "true" ); + } + break; + } + } + catch( std::exception& ex ) { + errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" ); + } + } + if( it == itEnd ) { + if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens ) + unusedTokens.push_back( token ); + else if( errors.empty() && m_throwOnUnrecognisedTokens ) + errors.push_back( "unrecognised option: " + token.data ); + } + } + if( !errors.empty() ) { + std::ostringstream oss; + for( std::vector::const_iterator it = errors.begin(), itEnd = errors.end(); + it != itEnd; + ++it ) { + if( it != errors.begin() ) + oss << "\n"; + oss << *it; + } + throw std::runtime_error( oss.str() ); + } + return unusedTokens; + } + std::vector populateFixedArgs( std::vector const& tokens, ConfigT& config ) const { + std::vector unusedTokens; + int position = 1; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + typename std::map::const_iterator it = m_positionalArgs.find( position ); + if( it != m_positionalArgs.end() ) + it->second.boundField.set( config, token.data ); + else + unusedTokens.push_back( token ); + if( token.type == Parser::Token::Positional ) + position++; + } + return unusedTokens; + } + std::vector populateFloatingArgs( std::vector const& tokens, ConfigT& config ) const { + if( !m_floatingArg.get() ) + return tokens; + std::vector unusedTokens; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + if( token.type == Parser::Token::Positional ) + m_floatingArg->boundField.set( config, token.data ); + else + unusedTokens.push_back( token ); + } + return unusedTokens; + } + + void validate() const + { + if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) + throw std::logic_error( "No options or arguments specified" ); + + for( typename std::vector::const_iterator it = m_options.begin(), + itEnd = m_options.end(); + it != itEnd; ++it ) + it->validate(); + } + + private: + Detail::BoundArgFunction m_boundProcessName; + std::vector m_options; + std::map m_positionalArgs; + ArgAutoPtr m_floatingArg; + int m_highestSpecifiedArgPosition; + bool m_throwOnUnrecognisedTokens; + }; + +} // end namespace Clara + + +STITCH_CLARA_CLOSE_NAMESPACE +#undef STITCH_CLARA_OPEN_NAMESPACE +#undef STITCH_CLARA_CLOSE_NAMESPACE + + +#endif // TWOBLUECUBES_CLARA_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/external/tbc_text_format.h b/libraries/Lora_Serialization/test/lib/Catch/include/external/tbc_text_format.h new file mode 100644 index 0000000..5209d80 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/external/tbc_text_format.h @@ -0,0 +1,168 @@ +/* + * Created by Phil on 18/4/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +// Only use header guard if we are not using an outer namespace +#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED +# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +# endif +# else +# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED +# endif +#endif +#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +#include +#include +#include + +// Use optional outer namespace +#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { +#endif + +namespace Tbc { + +#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH + const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + struct TextAttributes { + TextAttributes() + : initialIndent( std::string::npos ), + indent( 0 ), + width( consoleWidth-1 ) + {} + + TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } + TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } + TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } + + std::size_t initialIndent; // indent of first line, or npos + std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos + std::size_t width; // maximum width of text, including indent. Longer text will wrap + }; + + class Text { + public: + Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) + : attr( _attr ) + { + const std::string wrappableBeforeChars = "[({<\t"; + const std::string wrappableAfterChars = "])}>-,./|\\"; + const std::string wrappableInsteadOfChars = " \n\r"; + std::string indent = _attr.initialIndent != std::string::npos + ? std::string( _attr.initialIndent, ' ' ) + : std::string( _attr.indent, ' ' ); + + typedef std::string::const_iterator iterator; + iterator it = _str.begin(); + const iterator strEnd = _str.end(); + + while( it != strEnd ) { + + if( lines.size() >= 1000 ) { + lines.push_back( "... message truncated due to excessive size" ); + return; + } + + + std::string suffix; + std::size_t width = (std::min)( static_cast( strEnd-it ), _attr.width-static_cast( indent.size() ) ); + iterator itEnd = it+width; + iterator itNext = _str.end(); + + iterator itNewLine = std::find( it, itEnd, '\n' ); + if( itNewLine != itEnd ) + itEnd = itNewLine; + + if( itEnd != strEnd ) { + bool foundWrapPoint = false; + iterator findIt = itEnd; + do { + if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) { + itEnd = findIt+1; + itNext = findIt+1; + foundWrapPoint = true; + } + else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) { + itEnd = findIt; + itNext = findIt; + foundWrapPoint = true; + } + else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) { + itNext = findIt+1; + itEnd = findIt; + foundWrapPoint = true; + } + if( findIt == it ) + break; + else + --findIt; + } + while( !foundWrapPoint ); + + if( !foundWrapPoint ) { + // No good wrap char, so we'll break mid word and add a hyphen + --itEnd; + itNext = itEnd; + suffix = "-"; + } + else { + while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos ) + --itEnd; + } + } + lines.push_back( indent + std::string( it, itEnd ) + suffix ); + + if( indent.size() != _attr.indent ) + indent = std::string( _attr.indent, ' ' ); + it = itNext; + } + } + + + + typedef std::vector::const_iterator const_iterator; + + const_iterator begin() const { return lines.begin(); } + const_iterator end() const { return lines.end(); } + std::string const& last() const { return lines.back(); } + std::size_t size() const { return lines.size(); } + std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } + std::string toString() const { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + + inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { + for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); + it != itEnd; ++it ) { + if( it != _text.begin() ) + _stream << "\n"; + _stream << *it; + } + return _stream; + } + + + private: + std::string str; + TextAttributes attr; + std::vector lines; + }; + +} // end namespace Tbc + +#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +} // end outer namespace +#endif + +#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_approx.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_approx.hpp new file mode 100644 index 0000000..5d6df1d --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_approx.hpp @@ -0,0 +1,180 @@ +/* + * Created by Phil on 28/04/2011. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED + +#include "catch_tostring.h" + +#include +#include + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) +#include +#endif + +namespace Catch { +namespace Detail { + + class Approx { + public: + explicit Approx ( double value ) + : m_epsilon( std::numeric_limits::epsilon()*100 ), + m_margin( 0.0 ), + m_scale( 1.0 ), + m_value( value ) + {} + + Approx( Approx const& other ) + : m_epsilon( other.m_epsilon ), + m_margin( other.m_margin ), + m_scale( other.m_scale ), + m_value( other.m_value ) + {} + + static Approx custom() { + return Approx( 0 ); + } + + Approx operator()( double value ) { + Approx approx( value ); + approx.epsilon( m_epsilon ); + approx.margin( m_margin ); + approx.scale( m_scale ); + return approx; + } + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) + template ::value>::type> + friend bool operator == ( const T& lhs, Approx const& rhs ) { + // Thanks to Richard Harris for his help refining this formula + auto lhs_v = double(lhs); + bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value))); + if (relativeOK) { + return true; + } + return std::fabs(lhs_v - rhs.m_value) < rhs.m_margin; + } + + template ::value>::type> + friend bool operator == ( Approx const& lhs, const T& rhs ) { + return operator==( rhs, lhs ); + } + + template ::value>::type> + friend bool operator != ( T lhs, Approx const& rhs ) { + return !operator==( lhs, rhs ); + } + + template ::value>::type> + friend bool operator != ( Approx const& lhs, T rhs ) { + return !operator==( rhs, lhs ); + } + + template ::value>::type> + friend bool operator <= ( T lhs, Approx const& rhs ) + { + return double(lhs) < rhs.m_value || lhs == rhs; + } + + template ::value>::type> + friend bool operator <= ( Approx const& lhs, T rhs ) + { + return lhs.m_value < double(rhs) || lhs == rhs; + } + + template ::value>::type> + friend bool operator >= ( T lhs, Approx const& rhs ) + { + return double(lhs) > rhs.m_value || lhs == rhs; + } + + template ::value>::type> + friend bool operator >= ( Approx const& lhs, T rhs ) + { + return lhs.m_value > double(rhs) || lhs == rhs; + } +#else + friend bool operator == ( double lhs, Approx const& rhs ) { + // Thanks to Richard Harris for his help refining this formula + bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) ); + if (relativeOK) { + return true; + } + return std::fabs(lhs - rhs.m_value) < rhs.m_margin; + } + + friend bool operator == ( Approx const& lhs, double rhs ) { + return operator==( rhs, lhs ); + } + + friend bool operator != ( double lhs, Approx const& rhs ) { + return !operator==( lhs, rhs ); + } + + friend bool operator != ( Approx const& lhs, double rhs ) { + return !operator==( rhs, lhs ); + } + + friend bool operator <= ( double lhs, Approx const& rhs ) + { + return lhs < rhs.m_value || lhs == rhs; + } + + friend bool operator <= ( Approx const& lhs, double rhs ) + { + return lhs.m_value < rhs || lhs == rhs; + } + + friend bool operator >= ( double lhs, Approx const& rhs ) + { + return lhs > rhs.m_value || lhs == rhs; + } + + friend bool operator >= ( Approx const& lhs, double rhs ) + { + return lhs.m_value > rhs || lhs == rhs; + } +#endif + + Approx& epsilon( double newEpsilon ) { + m_epsilon = newEpsilon; + return *this; + } + + Approx& margin( double newMargin ) { + m_margin = newMargin; + return *this; + } + + Approx& scale( double newScale ) { + m_scale = newScale; + return *this; + } + + std::string toString() const { + std::ostringstream oss; + oss << "Approx( " << Catch::toString( m_value ) << " )"; + return oss.str(); + } + + private: + double m_epsilon; + double m_margin; + double m_scale; + double m_value; + }; +} + +template<> +inline std::string toString( Detail::Approx const& value ) { + return value.toString(); +} + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_assertionresult.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_assertionresult.h new file mode 100644 index 0000000..a193c55 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_assertionresult.h @@ -0,0 +1,127 @@ +/* + * Created by Phil on 28/10/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED +#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED + +#include +#include "catch_result_type.h" + +namespace Catch { + + struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; + + struct DecomposedExpression + { + virtual ~DecomposedExpression() {} + virtual bool isBinaryExpression() const { + return false; + } + virtual void reconstructExpression( std::string& dest ) const = 0; + + // Only simple binary comparisons can be decomposed. + // If more complex check is required then wrap sub-expressions in parentheses. + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& ); + + private: + DecomposedExpression& operator = (DecomposedExpression const&); + }; + + struct AssertionInfo + { + AssertionInfo() {} + AssertionInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + std::string const& _capturedExpression, + ResultDisposition::Flags _resultDisposition ); + + std::string macroName; + SourceLineInfo lineInfo; + std::string capturedExpression; + ResultDisposition::Flags resultDisposition; + }; + + struct AssertionResultData + { + AssertionResultData() : decomposedExpression( CATCH_NULL ) + , resultType( ResultWas::Unknown ) + , negated( false ) + , parenthesized( false ) {} + + void negate( bool parenthesize ) { + negated = !negated; + parenthesized = parenthesize; + if( resultType == ResultWas::Ok ) + resultType = ResultWas::ExpressionFailed; + else if( resultType == ResultWas::ExpressionFailed ) + resultType = ResultWas::Ok; + } + + std::string const& reconstructExpression() const { + if( decomposedExpression != CATCH_NULL ) { + decomposedExpression->reconstructExpression( reconstructedExpression ); + if( parenthesized ) { + reconstructedExpression.insert( 0, 1, '(' ); + reconstructedExpression.append( 1, ')' ); + } + if( negated ) { + reconstructedExpression.insert( 0, 1, '!' ); + } + decomposedExpression = CATCH_NULL; + } + return reconstructedExpression; + } + + mutable DecomposedExpression const* decomposedExpression; + mutable std::string reconstructedExpression; + std::string message; + ResultWas::OfType resultType; + bool negated; + bool parenthesized; + }; + + class AssertionResult { + public: + AssertionResult(); + AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); + ~AssertionResult(); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + AssertionResult( AssertionResult const& ) = default; + AssertionResult( AssertionResult && ) = default; + AssertionResult& operator = ( AssertionResult const& ) = default; + AssertionResult& operator = ( AssertionResult && ) = default; +# endif + + bool isOk() const; + bool succeeded() const; + ResultWas::OfType getResultType() const; + bool hasExpression() const; + bool hasMessage() const; + std::string getExpression() const; + std::string getExpressionInMacro() const; + bool hasExpandedExpression() const; + std::string getExpandedExpression() const; + std::string getMessage() const; + SourceLineInfo getSourceInfo() const; + std::string getTestMacroName() const; + void discardDecomposedExpression() const; + void expandDecomposedExpression() const; + + protected: + AssertionInfo m_info; + AssertionResultData m_resultData; + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_assertionresult.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_assertionresult.hpp new file mode 100644 index 0000000..9b63702 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_assertionresult.hpp @@ -0,0 +1,99 @@ +/* + * Created by Phil on 8/8/12 + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED + +#include "catch_assertionresult.h" + +namespace Catch { + + + AssertionInfo::AssertionInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + std::string const& _capturedExpression, + ResultDisposition::Flags _resultDisposition ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + capturedExpression( _capturedExpression ), + resultDisposition( _resultDisposition ) + {} + + AssertionResult::AssertionResult() {} + + AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) + : m_info( info ), + m_resultData( data ) + {} + + AssertionResult::~AssertionResult() {} + + // Result was a success + bool AssertionResult::succeeded() const { + return Catch::isOk( m_resultData.resultType ); + } + + // Result was a success, or failure is suppressed + bool AssertionResult::isOk() const { + return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); + } + + ResultWas::OfType AssertionResult::getResultType() const { + return m_resultData.resultType; + } + + bool AssertionResult::hasExpression() const { + return !m_info.capturedExpression.empty(); + } + + bool AssertionResult::hasMessage() const { + return !m_resultData.message.empty(); + } + + std::string AssertionResult::getExpression() const { + if( isFalseTest( m_info.resultDisposition ) ) + return '!' + m_info.capturedExpression; + else + return m_info.capturedExpression; + } + std::string AssertionResult::getExpressionInMacro() const { + if( m_info.macroName.empty() ) + return m_info.capturedExpression; + else + return m_info.macroName + "( " + m_info.capturedExpression + " )"; + } + + bool AssertionResult::hasExpandedExpression() const { + return hasExpression() && getExpandedExpression() != getExpression(); + } + + std::string AssertionResult::getExpandedExpression() const { + return m_resultData.reconstructExpression(); + } + + std::string AssertionResult::getMessage() const { + return m_resultData.message; + } + SourceLineInfo AssertionResult::getSourceInfo() const { + return m_info.lineInfo; + } + + std::string AssertionResult::getTestMacroName() const { + return m_info.macroName; + } + + void AssertionResult::discardDecomposedExpression() const { + m_resultData.decomposedExpression = CATCH_NULL; + } + + void AssertionResult::expandDecomposedExpression() const { + m_resultData.reconstructExpression(); + } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_capture.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_capture.hpp new file mode 100644 index 0000000..ef0fcc7 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_capture.hpp @@ -0,0 +1,154 @@ +/* + * Created by Phil on 18/10/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED + +#include "catch_result_builder.h" +#include "catch_message.h" +#include "catch_interfaces_capture.h" +#include "catch_debugger.h" +#include "catch_common.h" +#include "catch_tostring.h" +#include "catch_interfaces_runner.h" +#include "catch_compiler_capabilities.h" +#include "catch_type_traits.hpp" + + +#if defined(CATCH_CONFIG_FAST_COMPILE) +/////////////////////////////////////////////////////////////////////////////// +// We can speedup compilation significantly by breaking into debugger lower in +// the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER +// macro in each assertion +#define INTERNAL_CATCH_REACT( resultBuilder ) \ + resultBuilder.react(); +#else +/////////////////////////////////////////////////////////////////////////////// +// In the event of a failure works out if the debugger needs to be invoked +// and/or an exception thrown and takes appropriate action. +// This needs to be done as a macro so the debugger will stop in the user +// source code rather than in Catch library code +#define INTERNAL_CATCH_REACT( resultBuilder ) \ + if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ + resultBuilder.react(); +#endif + + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ + try { \ + CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + ( __catchResult <= expr ).endExpression(); \ + CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look + // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ + INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ + if( Catch::getResultCapture().getLastResult()->succeeded() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ + INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ + if( !Catch::getResultCapture().getLastResult()->succeeded() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ + try { \ + static_cast(expr); \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \ + if( __catchResult.allowThrows() ) \ + try { \ + static_cast(expr); \ + __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ + } \ + catch( ... ) { \ + __catchResult.captureExpectedException( matcher ); \ + } \ + else \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr ", " #exceptionType, resultDisposition ); \ + if( __catchResult.allowThrows() ) \ + try { \ + static_cast(expr); \ + __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ + } \ + catch( Catch::add_const::type>::type ) { \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + else \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + + +/////////////////////////////////////////////////////////////////////////////// +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ + __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ + __catchResult.captureResult( messageType ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) +#else + #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ + __catchResult << log + ::Catch::StreamEndStop(); \ + __catchResult.captureResult( messageType ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) +#endif + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_INFO( log, macroName ) \ + Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \ + try { \ + __catchResult.captureMatch( arg, matcher, #matcher ); \ + } catch( ... ) { \ + __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +#endif // TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_clara.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_clara.h new file mode 100644 index 0000000..bfe2f4b --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_clara.h @@ -0,0 +1,32 @@ +/* + * Created by Phil on 10/2/2014. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ +#ifndef TWOBLUECUBES_CATCH_CLARA_H_INCLUDED +#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED + +// Use Catch's value for console width (store Clara's off to the side, if present) +#ifdef CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH +#undef CLARA_CONFIG_CONSOLE_WIDTH +#endif +#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH + + +// Declare Clara inside the Catch namespace +#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { +#include "../external/clara.h" +#undef STITCH_CLARA_OPEN_NAMESPACE + + +// Restore Clara's value for console width, if present +#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +#endif // TWOBLUECUBES_CATCH_CLARA_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_commandline.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_commandline.hpp new file mode 100644 index 0000000..742f01a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_commandline.hpp @@ -0,0 +1,215 @@ +/* + * Created by Phil on 02/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED + +#include "catch_config.hpp" +#include "catch_common.h" +#include "catch_clara.h" + +#include +#include + +namespace Catch { + + inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } + inline void abortAfterX( ConfigData& config, int x ) { + if( x < 1 ) + throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" ); + config.abortAfter = x; + } + inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } + inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); } + inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); } + + inline void addWarning( ConfigData& config, std::string const& _warning ) { + if( _warning == "NoAssertions" ) + config.warnings = static_cast( config.warnings | WarnAbout::NoAssertions ); + else + throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' ); + } + inline void setOrder( ConfigData& config, std::string const& order ) { + if( startsWith( "declared", order ) ) + config.runOrder = RunTests::InDeclarationOrder; + else if( startsWith( "lexical", order ) ) + config.runOrder = RunTests::InLexicographicalOrder; + else if( startsWith( "random", order ) ) + config.runOrder = RunTests::InRandomOrder; + else + throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' ); + } + inline void setRngSeed( ConfigData& config, std::string const& seed ) { + if( seed == "time" ) { + config.rngSeed = static_cast( std::time(0) ); + } + else { + std::stringstream ss; + ss << seed; + ss >> config.rngSeed; + if( ss.fail() ) + throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" ); + } + } + inline void setVerbosity( ConfigData& config, int level ) { + // !TBD: accept strings? + config.verbosity = static_cast( level ); + } + inline void setShowDurations( ConfigData& config, bool _showDurations ) { + config.showDurations = _showDurations + ? ShowDurations::Always + : ShowDurations::Never; + } + inline void setUseColour( ConfigData& config, std::string const& value ) { + std::string mode = toLower( value ); + + if( mode == "yes" ) + config.useColour = UseColour::Yes; + else if( mode == "no" ) + config.useColour = UseColour::No; + else if( mode == "auto" ) + config.useColour = UseColour::Auto; + else + throw std::runtime_error( "colour mode must be one of: auto, yes or no" ); + } + inline void forceColour( ConfigData& config ) { + config.useColour = UseColour::Yes; + } + inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { + std::ifstream f( _filename.c_str() ); + if( !f.is_open() ) + throw std::domain_error( "Unable to load input file: " + _filename ); + + std::string line; + while( std::getline( f, line ) ) { + line = trim(line); + if( !line.empty() && !startsWith( line, '#' ) ) { + if( !startsWith( line, '"' ) ) + line = '"' + line + '"'; + addTestOrTags( config, line + ',' ); + } + } + } + + inline Clara::CommandLine makeCommandLineParser() { + + using namespace Clara; + CommandLine cli; + + cli.bindProcessName( &ConfigData::processName ); + + cli["-?"]["-h"]["--help"] + .describe( "display usage information" ) + .bind( &ConfigData::showHelp ); + + cli["-l"]["--list-tests"] + .describe( "list all/matching test cases" ) + .bind( &ConfigData::listTests ); + + cli["-t"]["--list-tags"] + .describe( "list all/matching tags" ) + .bind( &ConfigData::listTags ); + + cli["-s"]["--success"] + .describe( "include successful tests in output" ) + .bind( &ConfigData::showSuccessfulTests ); + + cli["-b"]["--break"] + .describe( "break into debugger on failure" ) + .bind( &ConfigData::shouldDebugBreak ); + + cli["-e"]["--nothrow"] + .describe( "skip exception tests" ) + .bind( &ConfigData::noThrow ); + + cli["-i"]["--invisibles"] + .describe( "show invisibles (tabs, newlines)" ) + .bind( &ConfigData::showInvisibles ); + + cli["-o"]["--out"] + .describe( "output filename" ) + .bind( &ConfigData::outputFilename, "filename" ); + + cli["-r"]["--reporter"] +// .placeholder( "name[:filename]" ) + .describe( "reporter to use (defaults to console)" ) + .bind( &addReporterName, "name" ); + + cli["-n"]["--name"] + .describe( "suite name" ) + .bind( &ConfigData::name, "name" ); + + cli["-a"]["--abort"] + .describe( "abort at first failure" ) + .bind( &abortAfterFirst ); + + cli["-x"]["--abortx"] + .describe( "abort after x failures" ) + .bind( &abortAfterX, "no. failures" ); + + cli["-w"]["--warn"] + .describe( "enable warnings" ) + .bind( &addWarning, "warning name" ); + +// - needs updating if reinstated +// cli.into( &setVerbosity ) +// .describe( "level of verbosity (0=no output)" ) +// .shortOpt( "v") +// .longOpt( "verbosity" ) +// .placeholder( "level" ); + + cli[_] + .describe( "which test or tests to use" ) + .bind( &addTestOrTags, "test name, pattern or tags" ); + + cli["-d"]["--durations"] + .describe( "show test durations" ) + .bind( &setShowDurations, "yes|no" ); + + cli["-f"]["--input-file"] + .describe( "load test names to run from a file" ) + .bind( &loadTestNamesFromFile, "filename" ); + + cli["-#"]["--filenames-as-tags"] + .describe( "adds a tag for the filename" ) + .bind( &ConfigData::filenamesAsTags ); + + cli["-c"]["--section"] + .describe( "specify section to run" ) + .bind( &addSectionToRun, "section name" ); + + // Less common commands which don't have a short form + cli["--list-test-names-only"] + .describe( "list all/matching test cases names only" ) + .bind( &ConfigData::listTestNamesOnly ); + + cli["--list-reporters"] + .describe( "list all reporters" ) + .bind( &ConfigData::listReporters ); + + cli["--order"] + .describe( "test case order (defaults to decl)" ) + .bind( &setOrder, "decl|lex|rand" ); + + cli["--rng-seed"] + .describe( "set a specific seed for random numbers" ) + .bind( &setRngSeed, "'time'|number" ); + + cli["--force-colour"] + .describe( "force colourised output (deprecated)" ) + .bind( &forceColour ); + + cli["--use-colour"] + .describe( "should output be colourised" ) + .bind( &setUseColour, "yes|no" ); + + return cli; + } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_common.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_common.h new file mode 100644 index 0000000..d325a08 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_common.h @@ -0,0 +1,146 @@ +/* + * Created by Phil on 29/10/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_COMMON_H_INCLUDED +#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED + +#include "catch_compiler_capabilities.h" + +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr +#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) + +#include +#include + +namespace Catch { + + struct IConfig; + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { +#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; +#else + NonCopyable( NonCopyable const& info ); + NonCopyable& operator = ( NonCopyable const& ); +#endif + + protected: + NonCopyable() {} + virtual ~NonCopyable(); + }; + + class SafeBool { + public: + typedef void (SafeBool::*type)() const; + + static type makeSafe( bool value ) { + return value ? &SafeBool::trueValue : 0; + } + private: + void trueValue() const {} + }; + + template + inline void deleteAll( ContainerT& container ) { + typename ContainerT::const_iterator it = container.begin(); + typename ContainerT::const_iterator itEnd = container.end(); + for(; it != itEnd; ++it ) + delete *it; + } + template + inline void deleteAllValues( AssociativeContainerT& container ) { + typename AssociativeContainerT::const_iterator it = container.begin(); + typename AssociativeContainerT::const_iterator itEnd = container.end(); + for(; it != itEnd; ++it ) + delete it->second; + } + + bool startsWith( std::string const& s, std::string const& prefix ); + bool startsWith( std::string const& s, char prefix ); + bool endsWith( std::string const& s, std::string const& suffix ); + bool endsWith( std::string const& s, char suffix ); + bool contains( std::string const& s, std::string const& infix ); + void toLowerInPlace( std::string& s ); + std::string toLower( std::string const& s ); + std::string trim( std::string const& str ); + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); + + struct pluralise { + pluralise( std::size_t count, std::string const& label ); + + friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); + + std::size_t m_count; + std::string m_label; + }; + + struct SourceLineInfo { + + SourceLineInfo(); + SourceLineInfo( char const* _file, std::size_t _line ); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + SourceLineInfo(SourceLineInfo const& other) = default; + SourceLineInfo( SourceLineInfo && ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo& operator = ( SourceLineInfo && ) = default; +# endif + bool empty() const; + bool operator == ( SourceLineInfo const& other ) const; + bool operator < ( SourceLineInfo const& other ) const; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // This is just here to avoid compiler warnings with macro constants and boolean literals + inline bool isTrue( bool value ){ return value; } + inline bool alwaysTrue() { return true; } + inline bool alwaysFalse() { return false; } + + void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); + + void seedRng( IConfig const& config ); + unsigned int rngSeed(); + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() { + return std::string(); + } + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) +#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); + +#endif // TWOBLUECUBES_CATCH_COMMON_H_INCLUDED + diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_common.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_common.hpp new file mode 100644 index 0000000..9f94377 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_common.hpp @@ -0,0 +1,119 @@ +/* + * Created by Phil on 27/11/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED + +#include "catch_common.h" + +#include +#include + +namespace Catch { + + bool startsWith( std::string const& s, std::string const& prefix ) { + return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); + } + bool startsWith( std::string const& s, char prefix ) { + return !s.empty() && s[0] == prefix; + } + bool endsWith( std::string const& s, std::string const& suffix ) { + return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); + } + bool endsWith( std::string const& s, char suffix ) { + return !s.empty() && s[s.size()-1] == suffix; + } + bool contains( std::string const& s, std::string const& infix ) { + return s.find( infix ) != std::string::npos; + } + char toLowerCh(char c) { + return static_cast( std::tolower( c ) ); + } + void toLowerInPlace( std::string& s ) { + std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); + } + std::string toLower( std::string const& s ) { + std::string lc = s; + toLowerInPlace( lc ); + return lc; + } + std::string trim( std::string const& str ) { + static char const* whitespaceChars = "\n\r\t "; + std::string::size_type start = str.find_first_not_of( whitespaceChars ); + std::string::size_type end = str.find_last_not_of( whitespaceChars ); + + return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); + } + + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { + bool replaced = false; + std::size_t i = str.find( replaceThis ); + while( i != std::string::npos ) { + replaced = true; + str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); + if( i < str.size()-withThis.size() ) + i = str.find( replaceThis, i+withThis.size() ); + else + i = std::string::npos; + } + return replaced; + } + + pluralise::pluralise( std::size_t count, std::string const& label ) + : m_count( count ), + m_label( label ) + {} + + std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { + os << pluraliser.m_count << ' ' << pluraliser.m_label; + if( pluraliser.m_count != 1 ) + os << 's'; + return os; + } + + SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){} + SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) + : file( _file ), + line( _line ) + {} + bool SourceLineInfo::empty() const { + return file[0] == '\0'; + } + bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const { + return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); + } + bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const { + return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0)); + } + + void seedRng( IConfig const& config ) { + if( config.rngSeed() != 0 ) + std::srand( config.rngSeed() ); + } + unsigned int rngSeed() { + return getCurrentContext().getConfig()->rngSeed(); + } + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { +#ifndef __GNUG__ + os << info.file << '(' << info.line << ')'; +#else + os << info.file << ':' << info.line; +#endif + return os; + } + + void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { + std::ostringstream oss; + oss << locationInfo << ": Internal Catch error: '" << message << '\''; + if( alwaysTrue() ) + throw std::logic_error( oss.str() ); + } +} + +#endif // TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED + diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_compiler_capabilities.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_compiler_capabilities.h new file mode 100644 index 0000000..735d3d4 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_compiler_capabilities.h @@ -0,0 +1,313 @@ +/* + * Created by Phil on 15/04/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED + +// Detect a number of compiler features - mostly C++11/14 conformance - by compiler +// The following features are defined: +// +// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? +// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? +// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods +// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? +// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported +// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported? +// CATCH_CONFIG_CPP11_OVERRIDE : is override supported? +// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) +// CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported? +// CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported? + +// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? + +// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 + +#ifdef __cplusplus + +# if __cplusplus >= 201103L +# define CATCH_CPP11_OR_GREATER +# endif + +# if __cplusplus >= 201402L +# define CATCH_CPP14_OR_GREATER +# endif + +#endif + +#ifdef __clang__ + +# if __has_feature(cxx_nullptr) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# if __has_feature(cxx_noexcept) +# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# endif + +# if defined(CATCH_CPP11_OR_GREATER) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic push" ) \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic pop" ) +# endif + +#endif // __clang__ + + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +# if !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# endif + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE + +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Borland +#ifdef __BORLANDC__ + + +#endif // __BORLANDC__ + +//////////////////////////////////////////////////////////////////////////////// +// EDG +#ifdef __EDG_VERSION__ + + +#endif // __EDG_VERSION__ + +//////////////////////////////////////////////////////////////////////////////// +// Digital Mars +#ifdef __DMC__ + + +#endif // __DMC__ + +//////////////////////////////////////////////////////////////////////////////// +// GCC +#ifdef __GNUC__ + +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +# define CATCH_GCC_HAS_NEW_PRAGMA +# endif + +# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_GCC_HAS_NEW_PRAGMA) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "GCC diagnostic push" ) \ + _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" ) +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "GCC diagnostic pop" ) +# endif + + + +// - otherwise more recent versions define __cplusplus >= 201103L +// and will get picked up below + + +#endif // __GNUC__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH + +#if (_MSC_VER >= 1600) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) +#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE +#define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS +#endif + +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// + +// Use variadic macros if the compiler supports them +#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ + ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ + ( defined __GNUC__ && __GNUC__ >= 3 ) || \ + ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) + +#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS + +#endif + +// Use __COUNTER__ if the compiler supports it +#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ + ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \ + ( defined __clang__ && __clang_major__ >= 3 ) + +#define CATCH_INTERNAL_CONFIG_COUNTER + +#endif + +//////////////////////////////////////////////////////////////////////////////// +// C++ language feature support + +// catch all support for C++11 +#if defined(CATCH_CPP11_OR_GREATER) + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM +# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE +# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE +# endif + +# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS +# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS +# endif + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) +# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG +# endif + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) +# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE +# endif +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) +# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +# endif +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) +# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE +# endif +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) +# define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS +# endif + +#endif // __cplusplus >= 201103L + +// Now set the actual defines based on the above + anything the user has configured +#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_NULLPTR +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_NOEXCEPT +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_GENERATED_METHODS +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_IS_ENUM +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_TUPLE +#endif +#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) +# define CATCH_CONFIG_VARIADIC_MACROS +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_LONG_LONG +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_OVERRIDE +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_UNIQUE_PTR +#endif +// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for +// analytics) because, at time of writing, __COUNTER__ is not properly handled by it. +// This does not affect compilation +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_SHUFFLE +#endif +# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_TYPE_TRAITS +# endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS +#endif + +// noexcept support: +#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) +# define CATCH_NOEXCEPT noexcept +# define CATCH_NOEXCEPT_IS(x) noexcept(x) +#else +# define CATCH_NOEXCEPT throw() +# define CATCH_NOEXCEPT_IS(x) +#endif + +// nullptr support +#ifdef CATCH_CONFIG_CPP11_NULLPTR +# define CATCH_NULL nullptr +#else +# define CATCH_NULL NULL +#endif + +// override support +#ifdef CATCH_CONFIG_CPP11_OVERRIDE +# define CATCH_OVERRIDE override +#else +# define CATCH_OVERRIDE +#endif + +// unique_ptr support +#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR +# define CATCH_AUTO_PTR( T ) std::unique_ptr +#else +# define CATCH_AUTO_PTR( T ) std::auto_ptr +#endif + +#endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED + diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_config.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_config.hpp new file mode 100644 index 0000000..174850b --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_config.hpp @@ -0,0 +1,158 @@ +/* + * Created by Phil on 08/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED + +#include "catch_test_spec_parser.hpp" +#include "catch_context.h" +#include "catch_interfaces_config.h" +#include "catch_stream.h" + +#include +#include +#include +#include + +#ifndef CATCH_CONFIG_CONSOLE_WIDTH +#define CATCH_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { + + struct ConfigData { + + ConfigData() + : listTests( false ), + listTags( false ), + listReporters( false ), + listTestNamesOnly( false ), + showSuccessfulTests( false ), + shouldDebugBreak( false ), + noThrow( false ), + showHelp( false ), + showInvisibles( false ), + filenamesAsTags( false ), + abortAfter( -1 ), + rngSeed( 0 ), + verbosity( Verbosity::Normal ), + warnings( WarnAbout::Nothing ), + showDurations( ShowDurations::DefaultForReporter ), + runOrder( RunTests::InDeclarationOrder ), + useColour( UseColour::Auto ) + {} + + bool listTests; + bool listTags; + bool listReporters; + bool listTestNamesOnly; + + bool showSuccessfulTests; + bool shouldDebugBreak; + bool noThrow; + bool showHelp; + bool showInvisibles; + bool filenamesAsTags; + + int abortAfter; + unsigned int rngSeed; + + Verbosity::Level verbosity; + WarnAbout::What warnings; + ShowDurations::OrNot showDurations; + RunTests::InWhatOrder runOrder; + UseColour::YesOrNo useColour; + + std::string outputFilename; + std::string name; + std::string processName; + + std::vector reporterNames; + std::vector testsOrTags; + std::vector sectionsToRun; + }; + + + class Config : public SharedImpl { + private: + Config( Config const& other ); + Config& operator = ( Config const& other ); + virtual void dummy(); + public: + + Config() + {} + + Config( ConfigData const& data ) + : m_data( data ), + m_stream( openStream() ) + { + if( !data.testsOrTags.empty() ) { + TestSpecParser parser( ITagAliasRegistry::get() ); + for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) + parser.parse( data.testsOrTags[i] ); + m_testSpec = parser.testSpec(); + } + } + + virtual ~Config() {} + + std::string const& getFilename() const { + return m_data.outputFilename ; + } + + bool listTests() const { return m_data.listTests; } + bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } + bool listTags() const { return m_data.listTags; } + bool listReporters() const { return m_data.listReporters; } + + std::string getProcessName() const { return m_data.processName; } + + std::vector const& getReporterNames() const { return m_data.reporterNames; } + std::vector const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; } + + virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; } + + bool showHelp() const { return m_data.showHelp; } + + // IConfig interface + virtual bool allowThrows() const CATCH_OVERRIDE { return !m_data.noThrow; } + virtual std::ostream& stream() const CATCH_OVERRIDE { return m_stream->stream(); } + virtual std::string name() const CATCH_OVERRIDE { return m_data.name.empty() ? m_data.processName : m_data.name; } + virtual bool includeSuccessfulResults() const CATCH_OVERRIDE { return m_data.showSuccessfulTests; } + virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE { return m_data.warnings & WarnAbout::NoAssertions; } + virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; } + virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE { return m_data.runOrder; } + virtual unsigned int rngSeed() const CATCH_OVERRIDE { return m_data.rngSeed; } + virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE { return m_data.useColour; } + virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; } + virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; } + virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; } + + private: + + IStream const* openStream() { + if( m_data.outputFilename.empty() ) + return new CoutStream(); + else if( m_data.outputFilename[0] == '%' ) { + if( m_data.outputFilename == "%debug" ) + return new DebugOutStream(); + else + throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename ); + } + else + return new FileStream( m_data.outputFilename ); + } + ConfigData m_data; + + CATCH_AUTO_PTR( IStream const ) m_stream; + TestSpec m_testSpec; + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_console_colour.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_console_colour.hpp new file mode 100644 index 0000000..f0a8a69 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_console_colour.hpp @@ -0,0 +1,67 @@ +/* + * Created by Phil on 25/2/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED + +#include "catch_common.h" + +namespace Catch { + + struct Colour { + enum Code { + None = 0, + + White, + Red, + Green, + Blue, + Cyan, + Yellow, + Grey, + + Bright = 0x10, + + BrightRed = Bright | Red, + BrightGreen = Bright | Green, + LightGrey = Bright | Grey, + BrightWhite = Bright | White, + + // By intention + FileName = LightGrey, + Warning = Yellow, + ResultError = BrightRed, + ResultSuccess = BrightGreen, + ResultExpectedFailure = Warning, + + Error = BrightRed, + Success = Green, + + OriginalExpression = Cyan, + ReconstructedExpression = Yellow, + + SecondaryText = LightGrey, + Headers = White + }; + + // Use constructed object for RAII guard + Colour( Code _colourCode ); + Colour( Colour const& other ); + ~Colour(); + + // Use static method for one-shot changes + static void use( Code _colourCode ); + + private: + bool m_moved; + }; + + inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_console_colour_impl.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_console_colour_impl.hpp new file mode 100644 index 0000000..ba2a9d1 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_console_colour_impl.hpp @@ -0,0 +1,190 @@ +/* + * Created by Phil on 25/2/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED + +#include "catch_console_colour.hpp" + +namespace Catch { + namespace { + + struct IColourImpl { + virtual ~IColourImpl() {} + virtual void use( Colour::Code _colourCode ) = 0; + }; + + struct NoColourImpl : IColourImpl { + void use( Colour::Code ) {} + + static IColourImpl* instance() { + static NoColourImpl s_instance; + return &s_instance; + } + }; + + } // anon namespace +} // namespace Catch + +#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) +# ifdef CATCH_PLATFORM_WINDOWS +# define CATCH_CONFIG_COLOUR_WINDOWS +# else +# define CATCH_CONFIG_COLOUR_ANSI +# endif +#endif + + +#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// + +#include "catch_windows_h_proxy.h" + +namespace Catch { +namespace { + + class Win32ColourImpl : public IColourImpl { + public: + Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) + { + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); + originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); + originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); + } + + virtual void use( Colour::Code _colourCode ) { + switch( _colourCode ) { + case Colour::None: return setTextAttribute( originalForegroundAttributes ); + case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + case Colour::Red: return setTextAttribute( FOREGROUND_RED ); + case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); + case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); + case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); + case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); + case Colour::Grey: return setTextAttribute( 0 ); + + case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); + case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); + case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); + case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + + case Colour::Bright: throw std::logic_error( "not a colour" ); + } + } + + private: + void setTextAttribute( WORD _textAttribute ) { + SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); + } + HANDLE stdoutHandle; + WORD originalForegroundAttributes; + WORD originalBackgroundAttributes; + }; + + IColourImpl* platformColourInstance() { + static Win32ColourImpl s_instance; + + Ptr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = !isDebuggerActive() + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? &s_instance + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// + +#include + +namespace Catch { +namespace { + + // use POSIX/ ANSI console terminal codes + // Thanks to Adam Strzelecki for original contribution + // (http://github.com/nanoant) + // https://github.com/philsquared/Catch/pull/131 + class PosixColourImpl : public IColourImpl { + public: + virtual void use( Colour::Code _colourCode ) { + switch( _colourCode ) { + case Colour::None: + case Colour::White: return setColour( "[0m" ); + case Colour::Red: return setColour( "[0;31m" ); + case Colour::Green: return setColour( "[0;32m" ); + case Colour::Blue: return setColour( "[0;34m" ); + case Colour::Cyan: return setColour( "[0;36m" ); + case Colour::Yellow: return setColour( "[0;33m" ); + case Colour::Grey: return setColour( "[1;30m" ); + + case Colour::LightGrey: return setColour( "[0;37m" ); + case Colour::BrightRed: return setColour( "[1;31m" ); + case Colour::BrightGreen: return setColour( "[1;32m" ); + case Colour::BrightWhite: return setColour( "[1;37m" ); + + case Colour::Bright: throw std::logic_error( "not a colour" ); + } + } + static IColourImpl* instance() { + static PosixColourImpl s_instance; + return &s_instance; + } + + private: + void setColour( const char* _escapeCode ) { + Catch::cout() << '\033' << _escapeCode; + } + }; + + IColourImpl* platformColourInstance() { + Ptr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) ) + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? PosixColourImpl::instance() + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#else // not Windows or ANSI /////////////////////////////////////////////// + +namespace Catch { + + static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } + +} // end namespace Catch + +#endif // Windows/ ANSI/ None + +namespace Catch { + + Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } + Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast( _other ).m_moved = true; } + Colour::~Colour(){ if( !m_moved ) use( None ); } + + void Colour::use( Code _colourCode ) { + static IColourImpl* impl = platformColourInstance(); + impl->use( _colourCode ); + } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_context.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_context.h new file mode 100644 index 0000000..8b68386 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_context.h @@ -0,0 +1,50 @@ +/* + * Created by Phil on 31/12/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED +#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED + +#include "catch_interfaces_generators.h" +#include "catch_ptr.hpp" + + +namespace Catch { + + class TestCase; + class Stream; + struct IResultCapture; + struct IRunner; + struct IGeneratorsForTest; + struct IConfig; + + struct IContext + { + virtual ~IContext(); + + virtual IResultCapture* getResultCapture() = 0; + virtual IRunner* getRunner() = 0; + virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; + virtual bool advanceGeneratorsForCurrentTest() = 0; + virtual Ptr getConfig() const = 0; + }; + + struct IMutableContext : IContext + { + virtual ~IMutableContext(); + virtual void setResultCapture( IResultCapture* resultCapture ) = 0; + virtual void setRunner( IRunner* runner ) = 0; + virtual void setConfig( Ptr const& config ) = 0; + }; + + IContext& getCurrentContext(); + IMutableContext& getCurrentMutableContext(); + void cleanUpContext(); + Stream createStream( std::string const& streamName ); + +} + +#endif // TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_context_impl.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_context_impl.hpp new file mode 100644 index 0000000..8516ad9 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_context_impl.hpp @@ -0,0 +1,110 @@ +/* + * Created by Phil on 31/12/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED + +#include "catch_run_context.hpp" + +#include "catch_context.h" +#include "catch_stream.hpp" +#include "catch_common.h" + +namespace Catch { + + class Context : public IMutableContext { + + Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {} + Context( Context const& ); + void operator=( Context const& ); + + public: + virtual ~Context() { + deleteAllValues( m_generatorsByTestName ); + } + + public: // IContext + virtual IResultCapture* getResultCapture() { + return m_resultCapture; + } + virtual IRunner* getRunner() { + return m_runner; + } + virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { + return getGeneratorsForCurrentTest() + .getGeneratorInfo( fileInfo, totalSize ) + .getCurrentIndex(); + } + virtual bool advanceGeneratorsForCurrentTest() { + IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); + return generators && generators->moveNext(); + } + + virtual Ptr getConfig() const { + return m_config; + } + + public: // IMutableContext + virtual void setResultCapture( IResultCapture* resultCapture ) { + m_resultCapture = resultCapture; + } + virtual void setRunner( IRunner* runner ) { + m_runner = runner; + } + virtual void setConfig( Ptr const& config ) { + m_config = config; + } + + friend IMutableContext& getCurrentMutableContext(); + + private: + IGeneratorsForTest* findGeneratorsForCurrentTest() { + std::string testName = getResultCapture()->getCurrentTestName(); + + std::map::const_iterator it = + m_generatorsByTestName.find( testName ); + return it != m_generatorsByTestName.end() + ? it->second + : CATCH_NULL; + } + + IGeneratorsForTest& getGeneratorsForCurrentTest() { + IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); + if( !generators ) { + std::string testName = getResultCapture()->getCurrentTestName(); + generators = createGeneratorsForTest(); + m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); + } + return *generators; + } + + private: + Ptr m_config; + IRunner* m_runner; + IResultCapture* m_resultCapture; + std::map m_generatorsByTestName; + }; + + namespace { + Context* currentContext = CATCH_NULL; + } + IMutableContext& getCurrentMutableContext() { + if( !currentContext ) + currentContext = new Context(); + return *currentContext; + } + IContext& getCurrentContext() { + return getCurrentMutableContext(); + } + + void cleanUpContext() { + delete currentContext; + currentContext = CATCH_NULL; + } +} + +#endif // TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_debugger.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_debugger.h new file mode 100644 index 0000000..15a4c64 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_debugger.h @@ -0,0 +1,58 @@ +/* + * Created by Phil on 3/12/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ +#ifndef TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED +#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED + +#include "catch_platform.h" + +#include + +namespace Catch{ + + bool isDebuggerActive(); + void writeToDebugConsole( std::string const& text ); +} + +#ifdef CATCH_PLATFORM_MAC + + // The following code snippet based on: + // http://cocoawithlove.com/2008/03/break-into-debugger.html + #if defined(__ppc64__) || defined(__ppc__) + #define CATCH_TRAP() \ + __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ + : : : "memory","r0","r3","r4" ) + #else + #define CATCH_TRAP() __asm__("int $3\n" : : ) + #endif + +#elif defined(CATCH_PLATFORM_LINUX) + // If we can use inline assembler, do it because this allows us to break + // directly at the location of the failing check instead of breaking inside + // raise() called from it, i.e. one stack frame below. + #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) + #define CATCH_TRAP() asm volatile ("int $3") + #else // Fall back to the generic way. + #include + + #define CATCH_TRAP() raise(SIGTRAP) + #endif +#elif defined(_MSC_VER) + #define CATCH_TRAP() __debugbreak() +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) void __stdcall DebugBreak(); + #define CATCH_TRAP() DebugBreak() +#endif + +#ifdef CATCH_TRAP + #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } +#else + #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); +#endif + +#endif // TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_debugger.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_debugger.hpp new file mode 100644 index 0000000..47daf8a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_debugger.hpp @@ -0,0 +1,127 @@ +/* + * Created by Phil on 27/12/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ +#ifndef TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED + +#include "catch_debugger.h" + +#ifdef CATCH_PLATFORM_MAC + + #include + #include + #include + #include + #include + + namespace Catch{ + + // The following function is taken directly from the following technical note: + // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html + + // Returns true if the current process is being debugged (either + // running under the debugger or has a debugger attached post facto). + bool isDebuggerActive(){ + + int mib[4]; + struct kinfo_proc info; + size_t size; + + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) { + Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; + return false; + } + + // We're being debugged if the P_TRACED flag is set. + + return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); + } + } // namespace Catch + +#elif defined(CATCH_PLATFORM_LINUX) + #include + #include + + namespace Catch{ + // The standard POSIX way of detecting a debugger is to attempt to + // ptrace() the process, but this needs to be done from a child and not + // this process itself to still allow attaching to this process later + // if wanted, so is rather heavy. Under Linux we have the PID of the + // "debugger" (which doesn't need to be gdb, of course, it could also + // be strace, for example) in /proc/$PID/status, so just get it from + // there instead. + bool isDebuggerActive(){ + std::ifstream in("/proc/self/status"); + for( std::string line; std::getline(in, line); ) { + static const int PREFIX_LEN = 11; + if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { + // We're traced if the PID is not 0 and no other PID starts + // with 0 digit, so it's enough to check for just a single + // character. + return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; + } + } + + return false; + } + } // namespace Catch +#elif defined(_MSC_VER) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#else + namespace Catch { + inline bool isDebuggerActive() { return false; } + } +#endif // Platform + +#ifdef CATCH_PLATFORM_WINDOWS + +#include "catch_windows_h_proxy.h" + + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + ::OutputDebugStringA( text.c_str() ); + } + } +#else + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + // !TBD: Need a version for Mac/ XCode and other IDEs + Catch::cout() << text; + } + } +#endif // Platform + +#endif // TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_default_main.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_default_main.hpp new file mode 100644 index 0000000..a0c4239 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_default_main.hpp @@ -0,0 +1,39 @@ +/* + * Created by Phil on 20/05/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED + +#ifndef __OBJC__ + +// Standard C/C++ main entry point +int main (int argc, char * argv[]) { + int result = Catch::Session().run( argc, argv ); + return ( result < 0xff ? result : 0xff ); +} + +#else // __OBJC__ + +// Objective-C entry point +int main (int argc, char * const argv[]) { +#if !CATCH_ARC_ENABLED + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +#endif + + Catch::registerTestMethods(); + int result = Catch::Session().run( argc, (char* const*)argv ); + +#if !CATCH_ARC_ENABLED + [pool drain]; +#endif + + return ( result < 0xff ? result : 0xff ); +} + +#endif // __OBJC__ + +#endif // TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_evaluate.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_evaluate.hpp new file mode 100644 index 0000000..87fcc17 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_evaluate.hpp @@ -0,0 +1,219 @@ +/* + * Created by Phil on 04/03/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4389) // '==' : signed/unsigned mismatch +#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) +#endif + +#include + +namespace Catch { +namespace Internal { + + enum Operator { + IsEqualTo, + IsNotEqualTo, + IsLessThan, + IsGreaterThan, + IsLessThanOrEqualTo, + IsGreaterThanOrEqualTo + }; + + template struct OperatorTraits { static const char* getName(){ return "*error*"; } }; + template<> struct OperatorTraits { static const char* getName(){ return "=="; } }; + template<> struct OperatorTraits { static const char* getName(){ return "!="; } }; + template<> struct OperatorTraits { static const char* getName(){ return "<"; } }; + template<> struct OperatorTraits { static const char* getName(){ return ">"; } }; + template<> struct OperatorTraits { static const char* getName(){ return "<="; } }; + template<> struct OperatorTraits{ static const char* getName(){ return ">="; } }; + + template + inline T& opCast(T const& t) { return const_cast(t); } + +// nullptr_t support based on pull request #154 from Konstantin Baumann +#ifdef CATCH_CONFIG_CPP11_NULLPTR + inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } +#endif // CATCH_CONFIG_CPP11_NULLPTR + + + // So the compare overloads can be operator agnostic we convey the operator as a template + // enum, which is used to specialise an Evaluator for doing the comparison. + template + class Evaluator{}; + + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs) { + return bool( opCast( lhs ) == opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) != opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) < opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) > opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) >= opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) <= opCast( rhs ) ); + } + }; + + template + bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, rhs ); + } + + // This level of indirection allows us to specialise for integer types + // to avoid signed/ unsigned warnings + + // "base" overload + template + bool compare( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, rhs ); + } + + // unsigned X to int + template bool compare( unsigned int lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned long lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned char lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + + // unsigned X to long + template bool compare( unsigned int lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned long lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned char lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + + // int to unsigned X + template bool compare( int lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( int lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( int lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // long to unsigned X + template bool compare( long lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // pointer to long (when comparing against NULL) + template bool compare( long lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, long rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } + + // pointer to int (when comparing against NULL) + template bool compare( int lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, int rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG + // long long to unsigned X + template bool compare( long long lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned long long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // unsigned long long to X + template bool compare( unsigned long long lhs, int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, long long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // pointer to long long (when comparing against NULL) + template bool compare( long long lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, long long rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } +#endif // CATCH_CONFIG_CPP11_LONG_LONG + +#ifdef CATCH_CONFIG_CPP11_NULLPTR + // pointer to nullptr_t (when comparing against nullptr) + template bool compare( std::nullptr_t, T* rhs ) { + return Evaluator::evaluate( nullptr, rhs ); + } + template bool compare( T* lhs, std::nullptr_t ) { + return Evaluator::evaluate( lhs, nullptr ); + } +#endif // CATCH_CONFIG_CPP11_NULLPTR + +} // end of namespace Internal +} // end of namespace Catch + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_exception_translator_registry.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_exception_translator_registry.hpp new file mode 100644 index 0000000..c4bdb40 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_exception_translator_registry.hpp @@ -0,0 +1,73 @@ +/* + * Created by Phil on 20/04/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED + +#include "catch_interfaces_exception.h" +#include "catch_tostring.h" + +#ifdef __OBJC__ +#import "Foundation/Foundation.h" +#endif + +namespace Catch { + + class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { + public: + ~ExceptionTranslatorRegistry() { + deleteAll( m_translators ); + } + + virtual void registerTranslator( const IExceptionTranslator* translator ) { + m_translators.push_back( translator ); + } + + virtual std::string translateActiveException() const { + try { +#ifdef __OBJC__ + // In Objective-C try objective-c exceptions first + @try { + return tryTranslators(); + } + @catch (NSException *exception) { + return Catch::toString( [exception description] ); + } +#else + return tryTranslators(); +#endif + } + catch( TestFailureException& ) { + throw; + } + catch( std::exception& ex ) { + return ex.what(); + } + catch( std::string& msg ) { + return msg; + } + catch( const char* msg ) { + return msg; + } + catch(...) { + return "Unknown exception"; + } + } + + std::string tryTranslators() const { + if( m_translators.empty() ) + throw; + else + return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); + } + + private: + std::vector m_translators; + }; +} + +#endif // TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_expression_lhs.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_expression_lhs.hpp new file mode 100644 index 0000000..106a6b0 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_expression_lhs.hpp @@ -0,0 +1,174 @@ +/* + * Created by Phil on 11/5/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED + +#include "catch_result_builder.h" +#include "catch_evaluate.hpp" +#include "catch_tostring.h" + +namespace Catch { + +template +class BinaryExpression; + +template +class MatchExpression; + +// Wraps the LHS of an expression and overloads comparison operators +// for also capturing those and RHS (if any) +template +class ExpressionLhs : public DecomposedExpression { +public: + ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {} + + ExpressionLhs& operator = ( const ExpressionLhs& ); + + template + BinaryExpression + operator == ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator != ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator < ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator > ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator <= ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator >= ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + BinaryExpression operator == ( bool rhs ) { + return captureExpression( rhs ); + } + + BinaryExpression operator != ( bool rhs ) { + return captureExpression( rhs ); + } + + void endExpression() { + m_truthy = m_lhs ? true : false; + m_rb + .setResultType( m_truthy ) + .endExpression( *this ); + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + dest = Catch::toString( m_truthy ); + } + +private: + template + BinaryExpression captureExpression( RhsT& rhs ) const { + return BinaryExpression( m_rb, m_lhs, rhs ); + } + + template + BinaryExpression captureExpression( bool rhs ) const { + return BinaryExpression( m_rb, m_lhs, rhs ); + } + +private: + ResultBuilder& m_rb; + T m_lhs; + bool m_truthy; +}; + +template +class BinaryExpression : public DecomposedExpression { +public: + BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs ) + : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {} + + BinaryExpression& operator = ( BinaryExpression& ); + + void endExpression() const { + m_rb + .setResultType( Internal::compare( m_lhs, m_rhs ) ) + .endExpression( *this ); + } + + virtual bool isBinaryExpression() const CATCH_OVERRIDE { + return true; + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + std::string lhs = Catch::toString( m_lhs ); + std::string rhs = Catch::toString( m_rhs ); + char delim = lhs.size() + rhs.size() < 40 && + lhs.find('\n') == std::string::npos && + rhs.find('\n') == std::string::npos ? ' ' : '\n'; + dest.reserve( 7 + lhs.size() + rhs.size() ); + // 2 for spaces around operator + // 2 for operator + // 2 for parentheses (conditionally added later) + // 1 for negation (conditionally added later) + dest = lhs; + dest += delim; + dest += Internal::OperatorTraits::getName(); + dest += delim; + dest += rhs; + } + +private: + ResultBuilder& m_rb; + LhsT m_lhs; + RhsT m_rhs; +}; + +template +class MatchExpression : public DecomposedExpression { +public: + MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString ) + : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {} + + virtual bool isBinaryExpression() const CATCH_OVERRIDE { + return true; + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + std::string matcherAsString = m_matcher.toString(); + dest = Catch::toString( m_arg ); + dest += ' '; + if( matcherAsString == Detail::unprintableString ) + dest += m_matcherString; + else + dest += matcherAsString; + } + +private: + ArgT m_arg; + MatcherT m_matcher; + char const* m_matcherString; +}; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_fatal_condition.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_fatal_condition.hpp new file mode 100644 index 0000000..1d6674f --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_fatal_condition.hpp @@ -0,0 +1,200 @@ +/* + * Created by Phil on 21/08/2014 + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ +#ifndef TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED +#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED + + +namespace Catch { + + // Report the error condition + inline void reportFatal( std::string const& message ) { + IContext& context = Catch::getCurrentContext(); + IResultCapture* resultCapture = context.getResultCapture(); + resultCapture->handleFatalErrorCondition( message ); + } + +} // namespace Catch + +#if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// +#include "catch_windows_h_proxy.h" + +# if !defined ( CATCH_CONFIG_WINDOWS_SEH ) + +namespace Catch { + struct FatalConditionHandler { + void reset() {} + }; +} + +# else // CATCH_CONFIG_WINDOWS_SEH is defined + +namespace Catch { + + struct SignalDefs { DWORD id; const char* name; }; + extern SignalDefs signalDefs[]; + // There is no 1-1 mapping between signals and windows exceptions. + // Windows can easily distinguish between SO and SigSegV, + // but SigInt, SigTerm, etc are handled differently. + SignalDefs signalDefs[] = { + { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" }, + { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, + { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, + { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, + }; + + struct FatalConditionHandler { + + static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { + for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { + reportFatal(signalDefs[i].name); + } + } + // If its not an exception we care about, pass it along. + // This stops us from eating debugger breaks etc. + return EXCEPTION_CONTINUE_SEARCH; + } + + FatalConditionHandler() { + isSet = true; + // 32k seems enough for Catch to handle stack overflow, + // but the value was found experimentally, so there is no strong guarantee + guaranteeSize = 32 * 1024; + exceptionHandlerHandle = CATCH_NULL; + // Register as first handler in current chain + exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); + // Pass in guarantee size to be filled + SetThreadStackGuarantee(&guaranteeSize); + } + + static void reset() { + if (isSet) { + // Unregister handler and restore the old guarantee + RemoveVectoredExceptionHandler(exceptionHandlerHandle); + SetThreadStackGuarantee(&guaranteeSize); + exceptionHandlerHandle = CATCH_NULL; + isSet = false; + } + } + + ~FatalConditionHandler() { + reset(); + } + private: + static bool isSet; + static ULONG guaranteeSize; + static PVOID exceptionHandlerHandle; + }; + + bool FatalConditionHandler::isSet = false; + ULONG FatalConditionHandler::guaranteeSize = 0; + PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL; + +} // namespace Catch + +# endif // CATCH_CONFIG_WINDOWS_SEH + +#else // Not Windows - assumed to be POSIX compatible ////////////////////////// + +# if !defined(CATCH_CONFIG_POSIX_SIGNALS) + +namespace Catch { + struct FatalConditionHandler { + void reset() {} + }; +} + + +# else // CATCH_CONFIG_POSIX_SIGNALS is defined + +#include + +namespace Catch { + + struct SignalDefs { + int id; + const char* name; + }; + extern SignalDefs signalDefs[]; + SignalDefs signalDefs[] = { + { SIGINT, "SIGINT - Terminal interrupt signal" }, + { SIGILL, "SIGILL - Illegal instruction signal" }, + { SIGFPE, "SIGFPE - Floating point error signal" }, + { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, + { SIGTERM, "SIGTERM - Termination request signal" }, + { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } + }; + + struct FatalConditionHandler { + + static bool isSet; + static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)]; + static stack_t oldSigStack; + static char altStackMem[SIGSTKSZ]; + + static void handleSignal( int sig ) { + std::string name = ""; + for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + SignalDefs &def = signalDefs[i]; + if (sig == def.id) { + name = def.name; + break; + } + } + reset(); + reportFatal(name); + raise( sig ); + } + + FatalConditionHandler() { + isSet = true; + stack_t sigStack; + sigStack.ss_sp = altStackMem; + sigStack.ss_size = SIGSTKSZ; + sigStack.ss_flags = 0; + sigaltstack(&sigStack, &oldSigStack); + struct sigaction sa = { 0 }; + + sa.sa_handler = handleSignal; + sa.sa_flags = SA_ONSTACK; + for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); + } + } + + + ~FatalConditionHandler() { + reset(); + } + static void reset() { + if( isSet ) { + // Set signals back to previous values -- hopefully nobody overwrote them in the meantime + for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { + sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL); + } + // Return the old stack + sigaltstack(&oldSigStack, CATCH_NULL); + isSet = false; + } + } + }; + + bool FatalConditionHandler::isSet = false; + struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; + stack_t FatalConditionHandler::oldSigStack = {}; + char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; + + +} // namespace Catch + +# endif // CATCH_CONFIG_POSIX_SIGNALS + +#endif // not Windows + +#endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_generators.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_generators.hpp new file mode 100644 index 0000000..84eb22f --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_generators.hpp @@ -0,0 +1,190 @@ +/* + * Created by Phil on 27/01/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED + +#include "catch_context.h" + +#include +#include +#include +#include + +namespace Catch { + +template +struct IGenerator { + virtual ~IGenerator() {} + virtual T getValue( std::size_t index ) const = 0; + virtual std::size_t size () const = 0; +}; + +template +class BetweenGenerator : public IGenerator { +public: + BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} + + virtual T getValue( std::size_t index ) const { + return m_from+static_cast( index ); + } + + virtual std::size_t size() const { + return static_cast( 1+m_to-m_from ); + } + +private: + + T m_from; + T m_to; +}; + +template +class ValuesGenerator : public IGenerator { +public: + ValuesGenerator(){} + + void add( T value ) { + m_values.push_back( value ); + } + + virtual T getValue( std::size_t index ) const { + return m_values[index]; + } + + virtual std::size_t size() const { + return m_values.size(); + } + +private: + std::vector m_values; +}; + +template +class CompositeGenerator { +public: + CompositeGenerator() : m_totalSize( 0 ) {} + + // *** Move semantics, similar to auto_ptr *** + CompositeGenerator( CompositeGenerator& other ) + : m_fileInfo( other.m_fileInfo ), + m_totalSize( 0 ) + { + move( other ); + } + + CompositeGenerator& setFileInfo( const char* fileInfo ) { + m_fileInfo = fileInfo; + return *this; + } + + ~CompositeGenerator() { + deleteAll( m_composed ); + } + + operator T () const { + size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); + + typename std::vector*>::const_iterator it = m_composed.begin(); + typename std::vector*>::const_iterator itEnd = m_composed.end(); + for( size_t index = 0; it != itEnd; ++it ) + { + const IGenerator* generator = *it; + if( overallIndex >= index && overallIndex < index + generator->size() ) + { + return generator->getValue( overallIndex-index ); + } + index += generator->size(); + } + CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); + return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so + } + + void add( const IGenerator* generator ) { + m_totalSize += generator->size(); + m_composed.push_back( generator ); + } + + CompositeGenerator& then( CompositeGenerator& other ) { + move( other ); + return *this; + } + + CompositeGenerator& then( T value ) { + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( value ); + add( valuesGen ); + return *this; + } + +private: + + void move( CompositeGenerator& other ) { + std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) ); + m_totalSize += other.m_totalSize; + other.m_composed.clear(); + } + + std::vector*> m_composed; + std::string m_fileInfo; + size_t m_totalSize; +}; + +namespace Generators +{ + template + CompositeGenerator between( T from, T to ) { + CompositeGenerator generators; + generators.add( new BetweenGenerator( from, to ) ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2 ) { + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + generators.add( valuesGen ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2, T val3 ){ + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + valuesGen->add( val3 ); + generators.add( valuesGen ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2, T val3, T val4 ) { + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + valuesGen->add( val3 ); + valuesGen->add( val4 ); + generators.add( valuesGen ); + return generators; + } + +} // end namespace Generators + +using namespace Generators; + +} // end namespace Catch + +#define INTERNAL_CATCH_LINESTR2( line ) #line +#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) + +#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) + +#endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_generators_impl.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_generators_impl.hpp new file mode 100644 index 0000000..fea699a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_generators_impl.hpp @@ -0,0 +1,86 @@ +/* + * Created by Phil on 28/01/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED + +#include "catch_interfaces_generators.h" + +#include "catch_common.h" + +#include +#include +#include + +namespace Catch { + + struct GeneratorInfo : IGeneratorInfo { + + GeneratorInfo( std::size_t size ) + : m_size( size ), + m_currentIndex( 0 ) + {} + + bool moveNext() { + if( ++m_currentIndex == m_size ) { + m_currentIndex = 0; + return false; + } + return true; + } + + std::size_t getCurrentIndex() const { + return m_currentIndex; + } + + std::size_t m_size; + std::size_t m_currentIndex; + }; + + /////////////////////////////////////////////////////////////////////////// + + class GeneratorsForTest : public IGeneratorsForTest { + + public: + ~GeneratorsForTest() { + deleteAll( m_generatorsInOrder ); + } + + IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { + std::map::const_iterator it = m_generatorsByName.find( fileInfo ); + if( it == m_generatorsByName.end() ) { + IGeneratorInfo* info = new GeneratorInfo( size ); + m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); + m_generatorsInOrder.push_back( info ); + return *info; + } + return *it->second; + } + + bool moveNext() { + std::vector::const_iterator it = m_generatorsInOrder.begin(); + std::vector::const_iterator itEnd = m_generatorsInOrder.end(); + for(; it != itEnd; ++it ) { + if( (*it)->moveNext() ) + return true; + } + return false; + } + + private: + std::map m_generatorsByName; + std::vector m_generatorsInOrder; + }; + + IGeneratorsForTest* createGeneratorsForTest() + { + return new GeneratorsForTest(); + } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_impl.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_impl.hpp new file mode 100644 index 0000000..3886136 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_impl.hpp @@ -0,0 +1,109 @@ +/* + * Created by Phil on 5/8/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED + +// Collect all the implementation files together here +// These are the equivalent of what would usually be cpp files + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#endif + +#include "../catch_session.hpp" +#include "catch_registry_hub.hpp" +#include "catch_notimplemented_exception.hpp" +#include "catch_context_impl.hpp" +#include "catch_console_colour_impl.hpp" +#include "catch_generators_impl.hpp" +#include "catch_assertionresult.hpp" +#include "catch_test_case_info.hpp" +#include "catch_test_spec.hpp" +#include "catch_version.hpp" +#include "catch_message.hpp" +#include "catch_legacy_reporter_adapter.hpp" +#include "catch_timer.hpp" +#include "catch_common.hpp" +#include "catch_section.hpp" +#include "catch_debugger.hpp" +#include "catch_tostring.hpp" +#include "catch_result_builder.hpp" +#include "catch_tag_alias_registry.hpp" +#include "catch_test_case_tracker.hpp" +#include "catch_matchers_string.hpp" + +#include "../reporters/catch_reporter_multi.hpp" +#include "../reporters/catch_reporter_xml.hpp" +#include "../reporters/catch_reporter_junit.hpp" +#include "../reporters/catch_reporter_console.hpp" +#include "../reporters/catch_reporter_compact.hpp" + +namespace Catch { + // These are all here to avoid warnings about not having any out of line + // virtual methods + NonCopyable::~NonCopyable() {} + IShared::~IShared() {} + IStream::~IStream() CATCH_NOEXCEPT {} + FileStream::~FileStream() CATCH_NOEXCEPT {} + CoutStream::~CoutStream() CATCH_NOEXCEPT {} + DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {} + StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} + IContext::~IContext() {} + IResultCapture::~IResultCapture() {} + ITestCase::~ITestCase() {} + ITestCaseRegistry::~ITestCaseRegistry() {} + IRegistryHub::~IRegistryHub() {} + IMutableRegistryHub::~IMutableRegistryHub() {} + IExceptionTranslator::~IExceptionTranslator() {} + IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} + IReporter::~IReporter() {} + IReporterFactory::~IReporterFactory() {} + IReporterRegistry::~IReporterRegistry() {} + IStreamingReporter::~IStreamingReporter() {} + AssertionStats::~AssertionStats() {} + SectionStats::~SectionStats() {} + TestCaseStats::~TestCaseStats() {} + TestGroupStats::~TestGroupStats() {} + TestRunStats::~TestRunStats() {} + CumulativeReporterBase::SectionNode::~SectionNode() {} + CumulativeReporterBase::~CumulativeReporterBase() {} + + StreamingReporterBase::~StreamingReporterBase() {} + ConsoleReporter::~ConsoleReporter() {} + CompactReporter::~CompactReporter() {} + IRunner::~IRunner() {} + IMutableContext::~IMutableContext() {} + IConfig::~IConfig() {} + XmlReporter::~XmlReporter() {} + JunitReporter::~JunitReporter() {} + TestRegistry::~TestRegistry() {} + FreeFunctionTestCase::~FreeFunctionTestCase() {} + IGeneratorInfo::~IGeneratorInfo() {} + IGeneratorsForTest::~IGeneratorsForTest() {} + WildcardPattern::~WildcardPattern() {} + TestSpec::Pattern::~Pattern() {} + TestSpec::NamePattern::~NamePattern() {} + TestSpec::TagPattern::~TagPattern() {} + TestSpec::ExcludedPattern::~ExcludedPattern() {} + + void Config::dummy() {} + + namespace TestCaseTracking { + ITracker::~ITracker() {} + TrackerBase::~TrackerBase() {} + SectionTracker::~SectionTracker() {} + IndexTracker::~IndexTracker() {} + } +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif // TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_capture.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_capture.h new file mode 100644 index 0000000..b7b6e32 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_capture.h @@ -0,0 +1,47 @@ +/* + * Created by Phil on 07/01/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED +#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED + +#include +#include "catch_result_type.h" +#include "catch_common.h" + +namespace Catch { + + class TestCase; + class AssertionResult; + struct AssertionInfo; + struct SectionInfo; + struct SectionEndInfo; + struct MessageInfo; + class ScopedMessageBuilder; + struct Counts; + + struct IResultCapture { + + virtual ~IResultCapture(); + + virtual void assertionEnded( AssertionResult const& result ) = 0; + virtual bool sectionStarted( SectionInfo const& sectionInfo, + Counts& assertions ) = 0; + virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; + virtual void pushScopedMessage( MessageInfo const& message ) = 0; + virtual void popScopedMessage( MessageInfo const& message ) = 0; + + virtual std::string getCurrentTestName() const = 0; + virtual const AssertionResult* getLastResult() const = 0; + + virtual void handleFatalErrorCondition( std::string const& message ) = 0; + }; + + IResultCapture& getResultCapture(); +} + +#endif // TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_config.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_config.h new file mode 100644 index 0000000..5730a8c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_config.h @@ -0,0 +1,70 @@ +/* + * Created by Phil on 05/06/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED +#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED + +#include +#include +#include + +#include "catch_ptr.hpp" + +namespace Catch { + + struct Verbosity { enum Level { + NoOutput = 0, + Quiet, + Normal + }; }; + + struct WarnAbout { enum What { + Nothing = 0x00, + NoAssertions = 0x01 + }; }; + + struct ShowDurations { enum OrNot { + DefaultForReporter, + Always, + Never + }; }; + struct RunTests { enum InWhatOrder { + InDeclarationOrder, + InLexicographicalOrder, + InRandomOrder + }; }; + struct UseColour { enum YesOrNo { + Auto, + Yes, + No + }; }; + + class TestSpec; + + struct IConfig : IShared { + + virtual ~IConfig(); + + virtual bool allowThrows() const = 0; + virtual std::ostream& stream() const = 0; + virtual std::string name() const = 0; + virtual bool includeSuccessfulResults() const = 0; + virtual bool shouldDebugBreak() const = 0; + virtual bool warnAboutMissingAssertions() const = 0; + virtual int abortAfter() const = 0; + virtual bool showInvisibles() const = 0; + virtual ShowDurations::OrNot showDurations() const = 0; + virtual TestSpec const& testSpec() const = 0; + virtual RunTests::InWhatOrder runOrder() const = 0; + virtual unsigned int rngSeed() const = 0; + virtual UseColour::YesOrNo useColour() const = 0; + virtual std::vector const& getSectionsToRun() const = 0; + + }; +} + +#endif // TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_exception.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_exception.h new file mode 100644 index 0000000..bf29b71 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_exception.h @@ -0,0 +1,76 @@ +/* + * Created by Phil on 20/04/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED +#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED + +#include +#include + +#include "catch_interfaces_registry_hub.h" + +namespace Catch { + + typedef std::string(*exceptionTranslateFunction)(); + + struct IExceptionTranslator; + typedef std::vector ExceptionTranslators; + + struct IExceptionTranslator { + virtual ~IExceptionTranslator(); + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; + }; + + struct IExceptionTranslatorRegistry { + virtual ~IExceptionTranslatorRegistry(); + + virtual std::string translateActiveException() const = 0; + }; + + class ExceptionTranslatorRegistrar { + template + class ExceptionTranslator : public IExceptionTranslator { + public: + + ExceptionTranslator( std::string(*translateFunction)( T& ) ) + : m_translateFunction( translateFunction ) + {} + + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE { + try { + if( it == itEnd ) + throw; + else + return (*it)->translate( it+1, itEnd ); + } + catch( T& ex ) { + return m_translateFunction( ex ); + } + } + + protected: + std::string(*m_translateFunction)( T& ); + }; + + public: + template + ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { + getMutableRegistryHub().registerTranslator + ( new ExceptionTranslator( translateFunction ) ); + } + }; +} + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ + static std::string translatorName( signature ); \ + namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\ + static std::string translatorName( signature ) + +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) + +#endif // TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_generators.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_generators.h new file mode 100644 index 0000000..d163d5a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_generators.h @@ -0,0 +1,32 @@ +/* + * Created by Phil on 7/8/2012. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED +#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED + +#include + +namespace Catch { + + struct IGeneratorInfo { + virtual ~IGeneratorInfo(); + virtual bool moveNext() = 0; + virtual std::size_t getCurrentIndex() const = 0; + }; + + struct IGeneratorsForTest { + virtual ~IGeneratorsForTest(); + + virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; + virtual bool moveNext() = 0; + }; + + IGeneratorsForTest* createGeneratorsForTest(); + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_registry_hub.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_registry_hub.h new file mode 100644 index 0000000..ec06ca2 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_registry_hub.h @@ -0,0 +1,47 @@ +/* + * Created by Phil on 5/8/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED +#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED + +#include "catch_ptr.hpp" + +#include + +namespace Catch { + + class TestCase; + struct ITestCaseRegistry; + struct IExceptionTranslatorRegistry; + struct IExceptionTranslator; + struct IReporterRegistry; + struct IReporterFactory; + + struct IRegistryHub { + virtual ~IRegistryHub(); + + virtual IReporterRegistry const& getReporterRegistry() const = 0; + virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; + virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; + }; + + struct IMutableRegistryHub { + virtual ~IMutableRegistryHub(); + virtual void registerReporter( std::string const& name, Ptr const& factory ) = 0; + virtual void registerListener( Ptr const& factory ) = 0; + virtual void registerTest( TestCase const& testInfo ) = 0; + virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; + }; + + IRegistryHub& getRegistryHub(); + IMutableRegistryHub& getMutableRegistryHub(); + void cleanUp(); + std::string translateActiveException(); + +} + +#endif // TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_reporter.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_reporter.h new file mode 100644 index 0000000..6c47d8e --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_reporter.h @@ -0,0 +1,275 @@ +/* + * Created by Phil on 31/12/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED +#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED + +#include "catch_section_info.h" +#include "catch_common.h" +#include "catch_totals.hpp" +#include "catch_ptr.hpp" +#include "catch_config.hpp" +#include "catch_test_case_info.h" +#include "catch_assertionresult.h" +#include "catch_message.h" +#include "catch_option.hpp" + +#include +#include +#include + +namespace Catch +{ + struct ReporterConfig { + explicit ReporterConfig( Ptr const& _fullConfig ) + : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} + + ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) + : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} + + std::ostream& stream() const { return *m_stream; } + Ptr fullConfig() const { return m_fullConfig; } + + private: + std::ostream* m_stream; + Ptr m_fullConfig; + }; + + struct ReporterPreferences { + ReporterPreferences() + : shouldRedirectStdOut( false ) + {} + + bool shouldRedirectStdOut; + }; + + template + struct LazyStat : Option { + LazyStat() : used( false ) {} + LazyStat& operator=( T const& _value ) { + Option::operator=( _value ); + used = false; + return *this; + } + void reset() { + Option::reset(); + used = false; + } + bool used; + }; + + struct TestRunInfo { + TestRunInfo( std::string const& _name ) : name( _name ) {} + std::string name; + }; + struct GroupInfo { + GroupInfo( std::string const& _name, + std::size_t _groupIndex, + std::size_t _groupsCount ) + : name( _name ), + groupIndex( _groupIndex ), + groupsCounts( _groupsCount ) + {} + + std::string name; + std::size_t groupIndex; + std::size_t groupsCounts; + }; + + struct AssertionStats { + AssertionStats( AssertionResult const& _assertionResult, + std::vector const& _infoMessages, + Totals const& _totals ) + : assertionResult( _assertionResult ), + infoMessages( _infoMessages ), + totals( _totals ) + { + if( assertionResult.hasMessage() ) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); + builder << assertionResult.getMessage(); + builder.m_info.message = builder.m_stream.str(); + + infoMessages.push_back( builder.m_info ); + } + } + virtual ~AssertionStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + AssertionStats( AssertionStats const& ) = default; + AssertionStats( AssertionStats && ) = default; + AssertionStats& operator = ( AssertionStats const& ) = default; + AssertionStats& operator = ( AssertionStats && ) = default; +# endif + + AssertionResult assertionResult; + std::vector infoMessages; + Totals totals; + }; + + struct SectionStats { + SectionStats( SectionInfo const& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ) + : sectionInfo( _sectionInfo ), + assertions( _assertions ), + durationInSeconds( _durationInSeconds ), + missingAssertions( _missingAssertions ) + {} + virtual ~SectionStats(); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + SectionStats( SectionStats const& ) = default; + SectionStats( SectionStats && ) = default; + SectionStats& operator = ( SectionStats const& ) = default; + SectionStats& operator = ( SectionStats && ) = default; +# endif + + SectionInfo sectionInfo; + Counts assertions; + double durationInSeconds; + bool missingAssertions; + }; + + struct TestCaseStats { + TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string const& _stdOut, + std::string const& _stdErr, + bool _aborting ) + : testInfo( _testInfo ), + totals( _totals ), + stdOut( _stdOut ), + stdErr( _stdErr ), + aborting( _aborting ) + {} + virtual ~TestCaseStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestCaseStats( TestCaseStats const& ) = default; + TestCaseStats( TestCaseStats && ) = default; + TestCaseStats& operator = ( TestCaseStats const& ) = default; + TestCaseStats& operator = ( TestCaseStats && ) = default; +# endif + + TestCaseInfo testInfo; + Totals totals; + std::string stdOut; + std::string stdErr; + bool aborting; + }; + + struct TestGroupStats { + TestGroupStats( GroupInfo const& _groupInfo, + Totals const& _totals, + bool _aborting ) + : groupInfo( _groupInfo ), + totals( _totals ), + aborting( _aborting ) + {} + TestGroupStats( GroupInfo const& _groupInfo ) + : groupInfo( _groupInfo ), + aborting( false ) + {} + virtual ~TestGroupStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestGroupStats( TestGroupStats const& ) = default; + TestGroupStats( TestGroupStats && ) = default; + TestGroupStats& operator = ( TestGroupStats const& ) = default; + TestGroupStats& operator = ( TestGroupStats && ) = default; +# endif + + GroupInfo groupInfo; + Totals totals; + bool aborting; + }; + + struct TestRunStats { + TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ) + : runInfo( _runInfo ), + totals( _totals ), + aborting( _aborting ) + {} + virtual ~TestRunStats(); + +# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestRunStats( TestRunStats const& _other ) + : runInfo( _other.runInfo ), + totals( _other.totals ), + aborting( _other.aborting ) + {} +# else + TestRunStats( TestRunStats const& ) = default; + TestRunStats( TestRunStats && ) = default; + TestRunStats& operator = ( TestRunStats const& ) = default; + TestRunStats& operator = ( TestRunStats && ) = default; +# endif + + TestRunInfo runInfo; + Totals totals; + bool aborting; + }; + + class MultipleReporters; + + struct IStreamingReporter : IShared { + virtual ~IStreamingReporter(); + + // Implementing class must also provide the following static method: + // static std::string getDescription(); + + virtual ReporterPreferences getPreferences() const = 0; + + virtual void noMatchingTestCases( std::string const& spec ) = 0; + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; + virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; + virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; + + virtual void sectionEnded( SectionStats const& sectionStats ) = 0; + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; + virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; + + virtual void skipTest( TestCaseInfo const& testInfo ) = 0; + + virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; } + }; + + + struct IReporterFactory : IShared { + virtual ~IReporterFactory(); + virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; + virtual std::string getDescription() const = 0; + }; + + struct IReporterRegistry { + typedef std::map > FactoryMap; + typedef std::vector > Listeners; + + virtual ~IReporterRegistry(); + virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; + virtual FactoryMap const& getFactories() const = 0; + virtual Listeners const& getListeners() const = 0; + }; + + Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ); + +} + +#endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_runner.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_runner.h new file mode 100644 index 0000000..25decfb --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_runner.h @@ -0,0 +1,20 @@ +/* + * Created by Phil on 07/01/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED +#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED + +namespace Catch { + class TestCase; + + struct IRunner { + virtual ~IRunner(); + virtual bool aborting() const = 0; + }; +} + +#endif // TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_tag_alias_registry.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_tag_alias_registry.h new file mode 100644 index 0000000..cd6ac51 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_tag_alias_registry.h @@ -0,0 +1,26 @@ +/* + * Created by Phil on 27/6/2014. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED +#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED + +#include "catch_tag_alias.h" +#include "catch_option.hpp" + +namespace Catch { + + struct ITagAliasRegistry { + virtual ~ITagAliasRegistry(); + virtual Option find( std::string const& alias ) const = 0; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; + + static ITagAliasRegistry const& get(); + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_testcase.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_testcase.h new file mode 100644 index 0000000..a1052b7 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_interfaces_testcase.h @@ -0,0 +1,40 @@ +/* + * Created by Phil on 07/01/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED +#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED + +#include "catch_ptr.hpp" + +#include + +namespace Catch { + + class TestSpec; + + struct ITestCase : IShared { + virtual void invoke () const = 0; + protected: + virtual ~ITestCase(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +#endif // TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_legacy_reporter_adapter.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_legacy_reporter_adapter.h new file mode 100644 index 0000000..72c43d7 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_legacy_reporter_adapter.h @@ -0,0 +1,60 @@ +/* + * Created by Phil on 6th April 2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED +#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED + +#include "catch_interfaces_reporter.h" + +namespace Catch +{ + // Deprecated + struct IReporter : IShared { + virtual ~IReporter(); + + virtual bool shouldRedirectStdout() const = 0; + + virtual void StartTesting() = 0; + virtual void EndTesting( Totals const& totals ) = 0; + virtual void StartGroup( std::string const& groupName ) = 0; + virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; + virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; + virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; + virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; + virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; + virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; + virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; + virtual void Aborted() = 0; + virtual void Result( AssertionResult const& result ) = 0; + }; + + class LegacyReporterAdapter : public SharedImpl + { + public: + LegacyReporterAdapter( Ptr const& legacyReporter ); + virtual ~LegacyReporterAdapter(); + + virtual ReporterPreferences getPreferences() const; + virtual void noMatchingTestCases( std::string const& ); + virtual void testRunStarting( TestRunInfo const& ); + virtual void testGroupStarting( GroupInfo const& groupInfo ); + virtual void testCaseStarting( TestCaseInfo const& testInfo ); + virtual void sectionStarting( SectionInfo const& sectionInfo ); + virtual void assertionStarting( AssertionInfo const& ); + virtual bool assertionEnded( AssertionStats const& assertionStats ); + virtual void sectionEnded( SectionStats const& sectionStats ); + virtual void testCaseEnded( TestCaseStats const& testCaseStats ); + virtual void testGroupEnded( TestGroupStats const& testGroupStats ); + virtual void testRunEnded( TestRunStats const& testRunStats ); + virtual void skipTest( TestCaseInfo const& ); + + private: + Ptr m_legacyReporter; + }; +} + +#endif // TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_legacy_reporter_adapter.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_legacy_reporter_adapter.hpp new file mode 100644 index 0000000..6034581 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_legacy_reporter_adapter.hpp @@ -0,0 +1,84 @@ +/* + * Created by Phil on 6th April 2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED + +#include "catch_legacy_reporter_adapter.h" + +namespace Catch +{ + LegacyReporterAdapter::LegacyReporterAdapter( Ptr const& legacyReporter ) + : m_legacyReporter( legacyReporter ) + {} + LegacyReporterAdapter::~LegacyReporterAdapter() {} + + ReporterPreferences LegacyReporterAdapter::getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); + return prefs; + } + + void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} + void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { + m_legacyReporter->StartTesting(); + } + void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { + m_legacyReporter->StartGroup( groupInfo.name ); + } + void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { + m_legacyReporter->StartTestCase( testInfo ); + } + void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { + m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); + } + void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { + // Not on legacy interface + } + + bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { + if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { + for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); + it != itEnd; + ++it ) { + if( it->type == ResultWas::Info ) { + ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); + rb << it->message; + rb.setResultType( ResultWas::Info ); + AssertionResult result = rb.build(); + m_legacyReporter->Result( result ); + } + } + } + m_legacyReporter->Result( assertionStats.assertionResult ); + return true; + } + void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { + if( sectionStats.missingAssertions ) + m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); + m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); + } + void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { + m_legacyReporter->EndTestCase + ( testCaseStats.testInfo, + testCaseStats.totals, + testCaseStats.stdOut, + testCaseStats.stdErr ); + } + void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { + if( testGroupStats.aborting ) + m_legacyReporter->Aborted(); + m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); + } + void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { + m_legacyReporter->EndTesting( testRunStats.totals ); + } + void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { + } +} + +#endif // TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_list.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_list.hpp new file mode 100644 index 0000000..e09898e --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_list.hpp @@ -0,0 +1,179 @@ +/* + * Created by Phil on 5/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED + +#include "catch_commandline.hpp" +#include "catch_text.h" +#include "catch_console_colour.hpp" +#include "catch_interfaces_reporter.h" +#include "catch_test_spec_parser.hpp" + +#include +#include + +namespace Catch { + + inline std::size_t listTests( Config const& config ) { + + TestSpec testSpec = config.testSpec(); + if( config.testSpec().hasFilters() ) + Catch::cout() << "Matching test cases:\n"; + else { + Catch::cout() << "All available test cases:\n"; + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + } + + std::size_t matchedTests = 0; + TextAttributes nameAttr, tagsAttr; + nameAttr.setInitialIndent( 2 ).setIndent( 4 ); + tagsAttr.setIndent( 6 ); + + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + matchedTests++; + TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); + Colour::Code colour = testCaseInfo.isHidden() + ? Colour::SecondaryText + : Colour::None; + Colour colourGuard( colour ); + + Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; + if( !testCaseInfo.tags.empty() ) + Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; + } + + if( !config.testSpec().hasFilters() ) + Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl; + else + Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl; + return matchedTests; + } + + inline std::size_t listTestsNamesOnly( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( !config.testSpec().hasFilters() ) + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + std::size_t matchedTests = 0; + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + matchedTests++; + TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); + if( startsWith( testCaseInfo.name, '#' ) ) + Catch::cout() << '"' << testCaseInfo.name << '"' << std::endl; + else + Catch::cout() << testCaseInfo.name << std::endl; + } + return matchedTests; + } + + struct TagInfo { + TagInfo() : count ( 0 ) {} + void add( std::string const& spelling ) { + ++count; + spellings.insert( spelling ); + } + std::string all() const { + std::string out; + for( std::set::const_iterator it = spellings.begin(), itEnd = spellings.end(); + it != itEnd; + ++it ) + out += "[" + *it + "]"; + return out; + } + std::set spellings; + std::size_t count; + }; + + inline std::size_t listTags( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( config.testSpec().hasFilters() ) + Catch::cout() << "Tags for matching test cases:\n"; + else { + Catch::cout() << "All available tags:\n"; + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + } + + std::map tagCounts; + + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + for( std::set::const_iterator tagIt = it->getTestCaseInfo().tags.begin(), + tagItEnd = it->getTestCaseInfo().tags.end(); + tagIt != tagItEnd; + ++tagIt ) { + std::string tagName = *tagIt; + std::string lcaseTagName = toLower( tagName ); + std::map::iterator countIt = tagCounts.find( lcaseTagName ); + if( countIt == tagCounts.end() ) + countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; + countIt->second.add( tagName ); + } + } + + for( std::map::const_iterator countIt = tagCounts.begin(), + countItEnd = tagCounts.end(); + countIt != countItEnd; + ++countIt ) { + std::ostringstream oss; + oss << " " << std::setw(2) << countIt->second.count << " "; + Text wrapper( countIt->second.all(), TextAttributes() + .setInitialIndent( 0 ) + .setIndent( oss.str().size() ) + .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); + Catch::cout() << oss.str() << wrapper << '\n'; + } + Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; + return tagCounts.size(); + } + + inline std::size_t listReporters( Config const& /*config*/ ) { + Catch::cout() << "Available reporters:\n"; + IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); + IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; + std::size_t maxNameLen = 0; + for(it = itBegin; it != itEnd; ++it ) + maxNameLen = (std::max)( maxNameLen, it->first.size() ); + + for(it = itBegin; it != itEnd; ++it ) { + Text wrapper( it->second->getDescription(), TextAttributes() + .setInitialIndent( 0 ) + .setIndent( 7+maxNameLen ) + .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); + Catch::cout() << " " + << it->first + << ':' + << std::string( maxNameLen - it->first.size() + 2, ' ' ) + << wrapper << '\n'; + } + Catch::cout() << std::endl; + return factories.size(); + } + + inline Option list( Config const& config ) { + Option listedCount; + if( config.listTests() ) + listedCount = listedCount.valueOr(0) + listTests( config ); + if( config.listTestNamesOnly() ) + listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); + if( config.listTags() ) + listedCount = listedCount.valueOr(0) + listTags( config ); + if( config.listReporters() ) + listedCount = listedCount.valueOr(0) + listReporters( config ); + return listedCount; + } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers.hpp new file mode 100644 index 0000000..de7d64c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers.hpp @@ -0,0 +1,168 @@ +/* + * Created by Phil Nash on 04/03/2012. + * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED + +#include "catch_common.h" + +namespace Catch { +namespace Matchers { + namespace Impl { + + template struct MatchAllOf; + template struct MatchAnyOf; + template struct MatchNotOf; + + class MatcherUntypedBase { + public: + std::string toString() const { + if( m_cachedToString.empty() ) + m_cachedToString = describe(); + return m_cachedToString; + } + + protected: + virtual std::string describe() const = 0; + mutable std::string m_cachedToString; + private: + MatcherUntypedBase& operator = ( MatcherUntypedBase const& ); + }; + + template + struct MatcherBase : MatcherUntypedBase { + + virtual bool match( ObjectT const& arg ) const = 0; + + MatchAllOf operator && ( MatcherBase const& other ) const; + MatchAnyOf operator || ( MatcherBase const& other ) const; + MatchNotOf operator ! () const; + }; + + template + struct MatchAllOf : MatcherBase { + virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if (!m_matchers[i]->match(arg)) + return false; + } + return true; + } + virtual std::string describe() const CATCH_OVERRIDE { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if( i != 0 ) + description += " and "; + description += m_matchers[i]->toString(); + } + description += " )"; + return description; + } + + MatchAllOf& operator && ( MatcherBase const& other ) { + m_matchers.push_back( &other ); + return *this; + } + + std::vector const*> m_matchers; + }; + template + struct MatchAnyOf : MatcherBase { + + virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if (m_matchers[i]->match(arg)) + return true; + } + return false; + } + virtual std::string describe() const CATCH_OVERRIDE { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if( i != 0 ) + description += " or "; + description += m_matchers[i]->toString(); + } + description += " )"; + return description; + } + + MatchAnyOf& operator || ( MatcherBase const& other ) { + m_matchers.push_back( &other ); + return *this; + } + + std::vector const*> m_matchers; + }; + + template + struct MatchNotOf : MatcherBase { + + MatchNotOf( MatcherBase const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} + + virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { + return !m_underlyingMatcher.match( arg ); + } + + virtual std::string describe() const CATCH_OVERRIDE { + return "not " + m_underlyingMatcher.toString(); + } + MatcherBase const& m_underlyingMatcher; + }; + + template + MatchAllOf MatcherBase::operator && ( MatcherBase const& other ) const { + return MatchAllOf() && *this && other; + } + template + MatchAnyOf MatcherBase::operator || ( MatcherBase const& other ) const { + return MatchAnyOf() || *this || other; + } + template + MatchNotOf MatcherBase::operator ! () const { + return MatchNotOf( *this ); + } + + } // namespace Impl + + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + // - deprecated: prefer ||, && and ! + template + inline Impl::MatchNotOf Not( Impl::MatcherBase const& underlyingMatcher ) { + return Impl::MatchNotOf( underlyingMatcher ); + } + template + inline Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { + return Impl::MatchAllOf() && m1 && m2; + } + template + inline Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { + return Impl::MatchAllOf() && m1 && m2 && m3; + } + template + inline Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { + return Impl::MatchAnyOf() || m1 || m2; + } + template + inline Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { + return Impl::MatchAnyOf() || m1 || m2 || m3; + } + +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch + +#endif // TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers_string.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers_string.h new file mode 100644 index 0000000..2a6d3ba --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers_string.h @@ -0,0 +1,67 @@ +/* + * Created by Phil Nash on 08/02/2017. + * Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED +#define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED + +#include "catch_matchers.hpp" + +namespace Catch { +namespace Matchers { + + namespace StdString { + + struct CasedString + { + CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ); + std::string adjustString( std::string const& str ) const; + std::string caseSensitivitySuffix() const; + + CaseSensitive::Choice m_caseSensitivity; + std::string m_str; + }; + + struct StringMatcherBase : MatcherBase { + StringMatcherBase( std::string operation, CasedString const& comparator ); + virtual std::string describe() const CATCH_OVERRIDE; + + CasedString m_comparator; + std::string m_operation; + }; + + struct EqualsMatcher : StringMatcherBase { + EqualsMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + struct ContainsMatcher : StringMatcherBase { + ContainsMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + struct StartsWithMatcher : StringMatcherBase { + StartsWithMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + struct EndsWithMatcher : StringMatcherBase { + EndsWithMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + + } // namespace StdString + + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + +} // namespace Matchers +} // namespace Catch + +#endif // TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers_string.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers_string.hpp new file mode 100644 index 0000000..107d8e2 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers_string.hpp @@ -0,0 +1,93 @@ +/* + * Created by Phil Nash on 08/02/2017. + * Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch_matchers.hpp" + +namespace Catch { +namespace Matchers { + + namespace StdString { + + CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_str( adjustString( str ) ) + {} + std::string CasedString::adjustString( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No + ? toLower( str ) + : str; + } + std::string CasedString::caseSensitivitySuffix() const { + return m_caseSensitivity == CaseSensitive::No + ? " (case insensitive)" + : std::string(); + } + + + StringMatcherBase::StringMatcherBase( std::string operation, CasedString const& comparator ) + : m_comparator( comparator ), + m_operation( operation ) { + } + + std::string StringMatcherBase::describe() const { + std::string description; + description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + + m_comparator.caseSensitivitySuffix().size()); + description += m_operation; + description += ": \""; + description += m_comparator.m_str; + description += "\""; + description += m_comparator.caseSensitivitySuffix(); + return description; + } + + EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {} + + bool EqualsMatcher::match( std::string const& source ) const { + return m_comparator.adjustString( source ) == m_comparator.m_str; + } + + + ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {} + + bool ContainsMatcher::match( std::string const& source ) const { + return contains( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + + StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {} + + bool StartsWithMatcher::match( std::string const& source ) const { + return startsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + + EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {} + + bool EndsWithMatcher::match( std::string const& source ) const { + return endsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + } // namespace StdString + + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + +} // namespace Matchers +} // namespace Catch diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers_vector.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers_vector.h new file mode 100644 index 0000000..6a48a4e --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_matchers_vector.h @@ -0,0 +1,101 @@ +/* + * Created by Phil Nash on 21/02/2017. + * Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED +#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED + +#include "catch_matchers.hpp" + +namespace Catch { +namespace Matchers { + + namespace Vector { + + template + struct ContainsElementMatcher : MatcherBase, T> { + + ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} + + bool match(std::vector const &v) const CATCH_OVERRIDE { + return std::find(v.begin(), v.end(), m_comparator) != v.end(); + } + + virtual std::string describe() const CATCH_OVERRIDE { + return "Contains: " + Catch::toString( m_comparator ); + } + + T const& m_comparator; + }; + + template + struct ContainsMatcher : MatcherBase, std::vector > { + + ContainsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector const &v) const CATCH_OVERRIDE { + // !TBD: see note in EqualsMatcher + if (m_comparator.size() > v.size()) + return false; + for (size_t i = 0; i < m_comparator.size(); ++i) + if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end()) + return false; + return true; + } + virtual std::string describe() const CATCH_OVERRIDE { + return "Contains: " + Catch::toString( m_comparator ); + } + + std::vector const& m_comparator; + }; + + template + struct EqualsMatcher : MatcherBase, std::vector > { + + EqualsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector const &v) const CATCH_OVERRIDE { + // !TBD: This currently works if all elements can be compared using != + // - a more general approach would be via a compare template that defaults + // to using !=. but could be specialised for, e.g. std::vector etc + // - then just call that directly + if (m_comparator.size() != v.size()) + return false; + for (size_t i = 0; i < v.size(); ++i) + if (m_comparator[i] != v[i]) + return false; + return true; + } + virtual std::string describe() const CATCH_OVERRIDE { + return "Equals: " + Catch::toString( m_comparator ); + } + std::vector const& m_comparator; + }; + + } // namespace Vector + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + template + Vector::ContainsMatcher Contains( std::vector const& comparator ) { + return Vector::ContainsMatcher( comparator ); + } + + template + Vector::ContainsElementMatcher VectorContains( T const& comparator ) { + return Vector::ContainsElementMatcher( comparator ); + } + + template + Vector::EqualsMatcher Equals( std::vector const& comparator ) { + return Vector::EqualsMatcher( comparator ); + } + +} // namespace Matchers +} // namespace Catch + +#endif // TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_message.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_message.h new file mode 100644 index 0000000..84ff95e --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_message.h @@ -0,0 +1,66 @@ +/* + * Created by Phil Nash on 1/2/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED +#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED + +#include +#include "catch_result_type.h" +#include "catch_common.h" + +namespace Catch { + + struct MessageInfo { + MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + std::string macroName; + SourceLineInfo lineInfo; + ResultWas::OfType type; + std::string message; + unsigned int sequence; + + bool operator == ( MessageInfo const& other ) const { + return sequence == other.sequence; + } + bool operator < ( MessageInfo const& other ) const { + return sequence < other.sequence; + } + private: + static unsigned int globalCount; + }; + + struct MessageBuilder { + MessageBuilder( std::string const& macroName, + SourceLineInfo const& lineInfo, + ResultWas::OfType type ) + : m_info( macroName, lineInfo, type ) + {} + + template + MessageBuilder& operator << ( T const& value ) { + m_stream << value; + return *this; + } + + MessageInfo m_info; + std::ostringstream m_stream; + }; + + class ScopedMessage { + public: + ScopedMessage( MessageBuilder const& builder ); + ScopedMessage( ScopedMessage const& other ); + ~ScopedMessage(); + + MessageInfo m_info; + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_message.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_message.hpp new file mode 100644 index 0000000..42866be --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_message.hpp @@ -0,0 +1,47 @@ +/* + * Created by Phil Nash on 1/2/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED + +#include "catch_message.h" + +namespace Catch { + + MessageInfo::MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + type( _type ), + sequence( ++globalCount ) + {} + + // This may need protecting if threading support is added + unsigned int MessageInfo::globalCount = 0; + + + //////////////////////////////////////////////////////////////////////////// + + ScopedMessage::ScopedMessage( MessageBuilder const& builder ) + : m_info( builder.m_info ) + { + m_info.message = builder.m_stream.str(); + getResultCapture().pushScopedMessage( m_info ); + } + ScopedMessage::ScopedMessage( ScopedMessage const& other ) + : m_info( other.m_info ) + {} + + ScopedMessage::~ScopedMessage() { + getResultCapture().popScopedMessage( m_info ); + } + + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_notimplemented_exception.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_notimplemented_exception.h new file mode 100644 index 0000000..128fff2 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_notimplemented_exception.h @@ -0,0 +1,35 @@ +/* + * Created by Phil on 5/8/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED +#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED + +#include "catch_common.h" + +namespace Catch { + + class NotImplementedException : public std::exception + { + public: + NotImplementedException( SourceLineInfo const& lineInfo ); + NotImplementedException( NotImplementedException const& ) {} + + virtual ~NotImplementedException() CATCH_NOEXCEPT {} + + virtual const char* what() const CATCH_NOEXCEPT; + + private: + std::string m_what; + SourceLineInfo m_lineInfo; + }; + +} // end namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) + +#endif // TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_notimplemented_exception.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_notimplemented_exception.hpp new file mode 100644 index 0000000..e4afdc6 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_notimplemented_exception.hpp @@ -0,0 +1,30 @@ +/* + * Created by Phil on 5/8/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED + +#include "catch_notimplemented_exception.h" +#include + +namespace Catch { + + NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) + : m_lineInfo( lineInfo ) { + std::ostringstream oss; + oss << lineInfo << ": function "; + oss << "not implemented"; + m_what = oss.str(); + } + + const char* NotImplementedException::what() const CATCH_NOEXCEPT { + return m_what.c_str(); + } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_objc.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_objc.hpp new file mode 100644 index 0000000..489cf55 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_objc.hpp @@ -0,0 +1,203 @@ +/* + * Created by Phil on 14/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED + +#include "catch_objc_arc.hpp" + +#import + +#include + +// NB. Any general catch headers included here must be included +// in catch.hpp first to make sure they are included by the single +// header for non obj-usage +#include "catch_test_case_info.h" + +/////////////////////////////////////////////////////////////////////////////// +// This protocol is really only here for (self) documenting purposes, since +// all its methods are optional. +@protocol OcFixture + +@optional + +-(void) setUp; +-(void) tearDown; + +@end + +namespace Catch { + + class OcMethod : public SharedImpl { + + public: + OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} + + virtual void invoke() const { + id obj = [[m_cls alloc] init]; + + performOptionalSelector( obj, @selector(setUp) ); + performOptionalSelector( obj, m_sel ); + performOptionalSelector( obj, @selector(tearDown) ); + + arcSafeRelease( obj ); + } + private: + virtual ~OcMethod() {} + + Class m_cls; + SEL m_sel; + }; + + namespace Detail{ + + + inline std::string getAnnotation( Class cls, + std::string const& annotationName, + std::string const& testCaseName ) { + NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; + SEL sel = NSSelectorFromString( selStr ); + arcSafeRelease( selStr ); + id value = performOptionalSelector( cls, sel ); + if( value ) + return [(NSString*)value UTF8String]; + return ""; + } + } + + inline size_t registerTestMethods() { + size_t noTestMethods = 0; + int noClasses = objc_getClassList( CATCH_NULL, 0 ); + + Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); + objc_getClassList( classes, noClasses ); + + for( int c = 0; c < noClasses; c++ ) { + Class cls = classes[c]; + { + u_int count; + Method* methods = class_copyMethodList( cls, &count ); + for( u_int m = 0; m < count ; m++ ) { + SEL selector = method_getName(methods[m]); + std::string methodName = sel_getName(selector); + if( startsWith( methodName, "Catch_TestCase_" ) ) { + std::string testCaseName = methodName.substr( 15 ); + std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); + std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); + const char* className = class_getName( cls ); + + getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); + noTestMethods++; + } + } + free(methods); + } + } + return noTestMethods; + } + + namespace Matchers { + namespace Impl { + namespace NSStringMatchers { + + template + struct StringHolder : MatcherImpl{ + StringHolder( NSString* substr ) : m_substr( [substr copy] ){} + StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} + StringHolder() { + arcSafeRelease( m_substr ); + } + + NSString* m_substr; + }; + + struct Equals : StringHolder { + Equals( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str isEqualToString:m_substr]; + } + + virtual std::string toString() const { + return "equals string: " + Catch::toString( m_substr ); + } + }; + + struct Contains : StringHolder { + Contains( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location != NSNotFound; + } + + virtual std::string toString() const { + return "contains string: " + Catch::toString( m_substr ); + } + }; + + struct StartsWith : StringHolder { + StartsWith( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == 0; + } + + virtual std::string toString() const { + return "starts with: " + Catch::toString( m_substr ); + } + }; + struct EndsWith : StringHolder { + EndsWith( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == [str length] - [m_substr length]; + } + + virtual std::string toString() const { + return "ends with: " + Catch::toString( m_substr ); + } + }; + + } // namespace NSStringMatchers + } // namespace Impl + + inline Impl::NSStringMatchers::Equals + Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } + + inline Impl::NSStringMatchers::Contains + Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } + + inline Impl::NSStringMatchers::StartsWith + StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } + + inline Impl::NSStringMatchers::EndsWith + EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } + + } // namespace Matchers + + using namespace Matchers; + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define OC_TEST_CASE( name, desc )\ ++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ +{\ +return @ name; \ +}\ ++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ +{ \ +return @ desc; \ +} \ +-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) + +#endif // TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_objc_arc.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_objc_arc.hpp new file mode 100644 index 0000000..6bcd6b8 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_objc_arc.hpp @@ -0,0 +1,51 @@ +/* + * Created by Phil on 1/08/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED + +#import + +#ifdef __has_feature +#define CATCH_ARC_ENABLED __has_feature(objc_arc) +#else +#define CATCH_ARC_ENABLED 0 +#endif + +void arcSafeRelease( NSObject* obj ); +id performOptionalSelector( id obj, SEL sel ); + +#if !CATCH_ARC_ENABLED +inline void arcSafeRelease( NSObject* obj ) { + [obj release]; +} +inline id performOptionalSelector( id obj, SEL sel ) { + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; + return nil; +} +#define CATCH_UNSAFE_UNRETAINED +#define CATCH_ARC_STRONG +#else +inline void arcSafeRelease( NSObject* ){} +inline id performOptionalSelector( id obj, SEL sel ) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#endif + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + return nil; +} +#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained +#define CATCH_ARC_STRONG __strong +#endif + +#endif // TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_option.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_option.hpp new file mode 100644 index 0000000..5413abf --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_option.hpp @@ -0,0 +1,75 @@ +/* + * Created by Phil on 02/12/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED + +#include "catch_common.h" + +namespace Catch { + + // An optional type + template + class Option { + public: + Option() : nullableValue( CATCH_NULL ) {} + Option( T const& _value ) + : nullableValue( new( storage ) T( _value ) ) + {} + Option( Option const& _other ) + : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL ) + {} + + ~Option() { + reset(); + } + + Option& operator= ( Option const& _other ) { + if( &_other != this ) { + reset(); + if( _other ) + nullableValue = new( storage ) T( *_other ); + } + return *this; + } + Option& operator = ( T const& _value ) { + reset(); + nullableValue = new( storage ) T( _value ); + return *this; + } + + void reset() { + if( nullableValue ) + nullableValue->~T(); + nullableValue = CATCH_NULL; + } + + T& operator*() { return *nullableValue; } + T const& operator*() const { return *nullableValue; } + T* operator->() { return nullableValue; } + const T* operator->() const { return nullableValue; } + + T valueOr( T const& defaultValue ) const { + return nullableValue ? *nullableValue : defaultValue; + } + + bool some() const { return nullableValue != CATCH_NULL; } + bool none() const { return nullableValue == CATCH_NULL; } + + bool operator !() const { return nullableValue == CATCH_NULL; } + operator SafeBool::type() const { + return SafeBool::makeSafe( some() ); + } + + private: + T* nullableValue; + char storage[sizeof(T)]; + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_platform.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_platform.h new file mode 100644 index 0000000..09b91bf --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_platform.h @@ -0,0 +1,28 @@ +/* + * Created by Phil on 16/8/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ +#ifndef TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED +#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED + +#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +# define CATCH_PLATFORM_MAC +#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +# define CATCH_PLATFORM_IPHONE +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +# define CATCH_PLATFORM_WINDOWS +# if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) +# define CATCH_DEFINES_NOMINMAX +# endif +# if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) +# define CATCH_DEFINES_WIN32_LEAN_AND_MEAN +# endif +#endif + +#endif // TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_ptr.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_ptr.hpp new file mode 100644 index 0000000..940e5d1 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_ptr.hpp @@ -0,0 +1,93 @@ +/* + * Created by Phil on 02/05/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED + +#include "catch_common.h" + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + // An intrusive reference counting smart pointer. + // T must implement addRef() and release() methods + // typically implementing the IShared interface + template + class Ptr { + public: + Ptr() : m_p( CATCH_NULL ){} + Ptr( T* p ) : m_p( p ){ + if( m_p ) + m_p->addRef(); + } + Ptr( Ptr const& other ) : m_p( other.m_p ){ + if( m_p ) + m_p->addRef(); + } + ~Ptr(){ + if( m_p ) + m_p->release(); + } + void reset() { + if( m_p ) + m_p->release(); + m_p = CATCH_NULL; + } + Ptr& operator = ( T* p ){ + Ptr temp( p ); + swap( temp ); + return *this; + } + Ptr& operator = ( Ptr const& other ){ + Ptr temp( other ); + swap( temp ); + return *this; + } + void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } + T* get() const{ return m_p; } + T& operator*() const { return *m_p; } + T* operator->() const { return m_p; } + bool operator !() const { return m_p == CATCH_NULL; } + operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } + + private: + T* m_p; + }; + + struct IShared : NonCopyable { + virtual ~IShared(); + virtual void addRef() const = 0; + virtual void release() const = 0; + }; + + template + struct SharedImpl : T { + + SharedImpl() : m_rc( 0 ){} + + virtual void addRef() const { + ++m_rc; + } + virtual void release() const { + if( --m_rc == 0 ) + delete this; + } + + mutable unsigned int m_rc; + }; + +} // end namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif // TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_reenable_warnings.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_reenable_warnings.h new file mode 100644 index 0000000..33574e0 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_reenable_warnings.h @@ -0,0 +1,21 @@ +/* + * Copyright 2014 Two Blue Cubes Ltd + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifndef TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED +#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(pop) +# else +# pragma clang diagnostic pop +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic pop +#endif + +#endif // TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_registry_hub.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_registry_hub.hpp new file mode 100644 index 0000000..35293bf --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_registry_hub.hpp @@ -0,0 +1,86 @@ +/* + * Created by Phil on 5/8/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED + +#include "catch_interfaces_registry_hub.h" + +#include "catch_test_case_registry_impl.hpp" +#include "catch_reporter_registry.hpp" +#include "catch_exception_translator_registry.hpp" + +namespace Catch { + + namespace { + + class RegistryHub : public IRegistryHub, public IMutableRegistryHub { + + RegistryHub( RegistryHub const& ); + void operator=( RegistryHub const& ); + + public: // IRegistryHub + RegistryHub() { + } + virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE { + return m_reporterRegistry; + } + virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE { + return m_testCaseRegistry; + } + virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE { + return m_exceptionTranslatorRegistry; + } + + public: // IMutableRegistryHub + virtual void registerReporter( std::string const& name, Ptr const& factory ) CATCH_OVERRIDE { + m_reporterRegistry.registerReporter( name, factory ); + } + virtual void registerListener( Ptr const& factory ) CATCH_OVERRIDE { + m_reporterRegistry.registerListener( factory ); + } + virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE { + m_testCaseRegistry.registerTest( testInfo ); + } + virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE { + m_exceptionTranslatorRegistry.registerTranslator( translator ); + } + + private: + TestRegistry m_testCaseRegistry; + ReporterRegistry m_reporterRegistry; + ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; + }; + + // Single, global, instance + inline RegistryHub*& getTheRegistryHub() { + static RegistryHub* theRegistryHub = CATCH_NULL; + if( !theRegistryHub ) + theRegistryHub = new RegistryHub(); + return theRegistryHub; + } + } + + IRegistryHub& getRegistryHub() { + return *getTheRegistryHub(); + } + IMutableRegistryHub& getMutableRegistryHub() { + return *getTheRegistryHub(); + } + void cleanUp() { + delete getTheRegistryHub(); + getTheRegistryHub() = CATCH_NULL; + cleanUpContext(); + } + std::string translateActiveException() { + return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); + } + + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_reporter_registrars.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_reporter_registrars.hpp new file mode 100644 index 0000000..4d5557e --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_reporter_registrars.hpp @@ -0,0 +1,98 @@ +/* + * Created by Phil on 31/12/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED + +#include "catch_interfaces_registry_hub.h" +#include "catch_legacy_reporter_adapter.h" + +namespace Catch { + + template + class LegacyReporterRegistrar { + + class ReporterFactory : public IReporterFactory { + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new LegacyReporterAdapter( new T( config ) ); + } + + virtual std::string getDescription() const { + return T::getDescription(); + } + }; + + public: + + LegacyReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); + } + }; + + template + class ReporterRegistrar { + + class ReporterFactory : public SharedImpl { + + // *** Please Note ***: + // - If you end up here looking at a compiler error because it's trying to register + // your custom reporter class be aware that the native reporter interface has changed + // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via + // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. + // However please consider updating to the new interface as the old one is now + // deprecated and will probably be removed quite soon! + // Please contact me via github if you have any questions at all about this. + // In fact, ideally, please contact me anyway to let me know you've hit this - as I have + // no idea who is actually using custom reporters at all (possibly no-one!). + // The new interface is designed to minimise exposure to interface changes in the future. + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new T( config ); + } + + virtual std::string getDescription() const { + return T::getDescription(); + } + }; + + public: + + ReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); + } + }; + + template + class ListenerRegistrar { + + class ListenerFactory : public SharedImpl { + + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new T( config ); + } + virtual std::string getDescription() const { + return std::string(); + } + }; + + public: + + ListenerRegistrar() { + getMutableRegistryHub().registerListener( new ListenerFactory() ); + } + }; +} + +#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ + namespace{ Catch::LegacyReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } + +#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ + namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } + +#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \ + namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } + +#endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_reporter_registry.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_reporter_registry.hpp new file mode 100644 index 0000000..71f23ff --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_reporter_registry.hpp @@ -0,0 +1,50 @@ +/* + * Created by Phil on 29/10/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED + +#include "catch_interfaces_reporter.h" + +#include + +namespace Catch { + + class ReporterRegistry : public IReporterRegistry { + + public: + + virtual ~ReporterRegistry() CATCH_OVERRIDE {} + + virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const CATCH_OVERRIDE { + FactoryMap::const_iterator it = m_factories.find( name ); + if( it == m_factories.end() ) + return CATCH_NULL; + return it->second->create( ReporterConfig( config ) ); + } + + void registerReporter( std::string const& name, Ptr const& factory ) { + m_factories.insert( std::make_pair( name, factory ) ); + } + void registerListener( Ptr const& factory ) { + m_listeners.push_back( factory ); + } + + virtual FactoryMap const& getFactories() const CATCH_OVERRIDE { + return m_factories; + } + virtual Listeners const& getListeners() const CATCH_OVERRIDE { + return m_listeners; + } + + private: + FactoryMap m_factories; + Listeners m_listeners; + }; +} + +#endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_result_builder.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_result_builder.h new file mode 100644 index 0000000..305c21e --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_result_builder.h @@ -0,0 +1,112 @@ +/* + * Created by Phil on 28/5/2014. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED +#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED + +#include "catch_result_type.h" +#include "catch_assertionresult.h" +#include "catch_common.h" +#include "catch_matchers.hpp" + +namespace Catch { + + struct TestFailureException{}; + + template class ExpressionLhs; + + struct CopyableStream { + CopyableStream() {} + CopyableStream( CopyableStream const& other ) { + oss << other.oss.str(); + } + CopyableStream& operator=( CopyableStream const& other ) { + oss.str(std::string()); + oss << other.oss.str(); + return *this; + } + std::ostringstream oss; + }; + + class ResultBuilder : public DecomposedExpression { + public: + ResultBuilder( char const* macroName, + SourceLineInfo const& lineInfo, + char const* capturedExpression, + ResultDisposition::Flags resultDisposition, + char const* secondArg = "" ); + + template + ExpressionLhs operator <= ( T const& operand ); + ExpressionLhs operator <= ( bool value ); + + template + ResultBuilder& operator << ( T const& value ) { + m_stream.oss << value; + return *this; + } + + ResultBuilder& setResultType( ResultWas::OfType result ); + ResultBuilder& setResultType( bool result ); + + void endExpression( DecomposedExpression const& expr ); + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE; + + AssertionResult build() const; + AssertionResult build( DecomposedExpression const& expr ) const; + + void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); + void captureResult( ResultWas::OfType resultType ); + void captureExpression(); + void captureExpectedException( std::string const& expectedMessage ); + void captureExpectedException( Matchers::Impl::MatcherBase const& matcher ); + void handleResult( AssertionResult const& result ); + void react(); + bool shouldDebugBreak() const; + bool allowThrows() const; + + template + void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ); + + private: + AssertionInfo m_assertionInfo; + AssertionResultData m_data; + CopyableStream m_stream; + + bool m_shouldDebugBreak; + bool m_shouldThrow; + }; + +} // namespace Catch + +// Include after due to circular dependency: +#include "catch_expression_lhs.hpp" + +namespace Catch { + + template + inline ExpressionLhs ResultBuilder::operator <= ( T const& operand ) { + return ExpressionLhs( *this, operand ); + } + + inline ExpressionLhs ResultBuilder::operator <= ( bool value ) { + return ExpressionLhs( *this, value ); + } + + template + inline void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher, + char const* matcherString ) { + MatchExpression expr( arg, matcher, matcherString ); + setResultType( matcher.match( arg ) ); + endExpression( expr ); + } + + +} // namespace Catch + +#endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_result_builder.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_result_builder.hpp new file mode 100644 index 0000000..aaa37a8 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_result_builder.hpp @@ -0,0 +1,151 @@ +/* + * Created by Phil on 28/5/2014. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED + +#include "catch_result_builder.h" +#include "catch_context.h" +#include "catch_interfaces_config.h" +#include "catch_interfaces_runner.h" +#include "catch_interfaces_capture.h" +#include "catch_interfaces_registry_hub.h" +#include "catch_wildcard_pattern.hpp" + +namespace Catch { + + std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) { + return secondArg.empty() || secondArg == "\"\"" + ? capturedExpression + : capturedExpression + ", " + secondArg; + } + ResultBuilder::ResultBuilder( char const* macroName, + SourceLineInfo const& lineInfo, + char const* capturedExpression, + ResultDisposition::Flags resultDisposition, + char const* secondArg ) + : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ), + m_shouldDebugBreak( false ), + m_shouldThrow( false ) + {} + + ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { + m_data.resultType = result; + return *this; + } + ResultBuilder& ResultBuilder::setResultType( bool result ) { + m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; + return *this; + } + + void ResultBuilder::endExpression( DecomposedExpression const& expr ) { + AssertionResult result = build( expr ); + handleResult( result ); + } + + void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { + m_assertionInfo.resultDisposition = resultDisposition; + m_stream.oss << Catch::translateActiveException(); + captureResult( ResultWas::ThrewException ); + } + + void ResultBuilder::captureResult( ResultWas::OfType resultType ) { + setResultType( resultType ); + captureExpression(); + } + + void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { + if( expectedMessage.empty() ) + captureExpectedException( Matchers::Impl::MatchAllOf() ); + else + captureExpectedException( Matchers::Equals( expectedMessage ) ); + } + + + void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase const& matcher ) { + + assert( !isFalseTest( m_assertionInfo.resultDisposition ) ); + AssertionResultData data = m_data; + data.resultType = ResultWas::Ok; + data.reconstructedExpression = m_assertionInfo.capturedExpression; + + std::string actualMessage = Catch::translateActiveException(); + if( !matcher.match( actualMessage ) ) { + data.resultType = ResultWas::ExpressionFailed; + data.reconstructedExpression = actualMessage; + } + AssertionResult result( m_assertionInfo, data ); + handleResult( result ); + } + + void ResultBuilder::captureExpression() { + AssertionResult result = build(); + handleResult( result ); + } + + void ResultBuilder::handleResult( AssertionResult const& result ) + { + getResultCapture().assertionEnded( result ); + + if( !result.isOk() ) { + if( getCurrentContext().getConfig()->shouldDebugBreak() ) + m_shouldDebugBreak = true; + if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) + m_shouldThrow = true; + } + } + + void ResultBuilder::react() { +#if defined(CATCH_CONFIG_FAST_COMPILE) + if (m_shouldDebugBreak) { + /////////////////////////////////////////////////////////////////// + // To inspect the state during test, you need to go one level up the callstack + // To go back to the test and change execution, jump over the throw statement + /////////////////////////////////////////////////////////////////// + CATCH_BREAK_INTO_DEBUGGER(); + } +#endif + if( m_shouldThrow ) + throw Catch::TestFailureException(); + } + + bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } + bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } + + AssertionResult ResultBuilder::build() const + { + return build( *this ); + } + + // CAVEAT: The returned AssertionResult stores a pointer to the argument expr, + // a temporary DecomposedExpression, which in turn holds references to + // operands, possibly temporary as well. + // It should immediately be passed to handleResult; if the expression + // needs to be reported, its string expansion must be composed before + // the temporaries are destroyed. + AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const + { + assert( m_data.resultType != ResultWas::Unknown ); + AssertionResultData data = m_data; + + // Flip bool results if FalseTest flag is set + if( isFalseTest( m_assertionInfo.resultDisposition ) ) { + data.negate( expr.isBinaryExpression() ); + } + + data.message = m_stream.oss.str(); + data.decomposedExpression = &expr; // for lazy reconstruction + return AssertionResult( m_assertionInfo, data ); + } + + void ResultBuilder::reconstructExpression( std::string& dest ) const { + dest = m_assertionInfo.capturedExpression; + } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_result_type.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_result_type.h new file mode 100644 index 0000000..4c3d77d --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_result_type.h @@ -0,0 +1,61 @@ +/* + * Created by Phil on 07/01/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED +#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED + +namespace Catch { + + // ResultWas::OfType enum + struct ResultWas { enum OfType { + Unknown = -1, + Ok = 0, + Info = 1, + Warning = 2, + + FailureBit = 0x10, + + ExpressionFailed = FailureBit | 1, + ExplicitFailure = FailureBit | 2, + + Exception = 0x100 | FailureBit, + + ThrewException = Exception | 1, + DidntThrowException = Exception | 2, + + FatalErrorCondition = 0x200 | FailureBit + + }; }; + + inline bool isOk( ResultWas::OfType resultType ) { + return ( resultType & ResultWas::FailureBit ) == 0; + } + inline bool isJustInfo( int flags ) { + return flags == ResultWas::Info; + } + + + // ResultDisposition::Flags enum + struct ResultDisposition { enum Flags { + Normal = 0x01, + + ContinueOnFailure = 0x02, // Failures fail test, but execution continues + FalseTest = 0x04, // Prefix expression with ! + SuppressFail = 0x08 // Failures are reported but do not fail the test + }; }; + + inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { + return static_cast( static_cast( lhs ) | static_cast( rhs ) ); + } + + inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } + inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } + inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_run_context.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_run_context.hpp new file mode 100644 index 0000000..496c32c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_run_context.hpp @@ -0,0 +1,367 @@ + /* + * Created by Phil on 22/10/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED + +#include "catch_interfaces_runner.h" +#include "catch_interfaces_reporter.h" +#include "catch_interfaces_exception.h" +#include "catch_config.hpp" +#include "catch_test_registry.hpp" +#include "catch_test_case_info.h" +#include "catch_capture.hpp" +#include "catch_totals.hpp" +#include "catch_test_spec.hpp" +#include "catch_test_case_tracker.hpp" +#include "catch_timer.h" +#include "catch_result_builder.h" +#include "catch_fatal_condition.hpp" + +#include +#include + +namespace Catch { + + class StreamRedirect { + + public: + StreamRedirect( std::ostream& stream, std::string& targetString ) + : m_stream( stream ), + m_prevBuf( stream.rdbuf() ), + m_targetString( targetString ) + { + stream.rdbuf( m_oss.rdbuf() ); + } + + ~StreamRedirect() { + m_targetString += m_oss.str(); + m_stream.rdbuf( m_prevBuf ); + } + + private: + std::ostream& m_stream; + std::streambuf* m_prevBuf; + std::ostringstream m_oss; + std::string& m_targetString; + }; + + /////////////////////////////////////////////////////////////////////////// + + class RunContext : public IResultCapture, public IRunner { + + RunContext( RunContext const& ); + void operator =( RunContext const& ); + + public: + + explicit RunContext( Ptr const& _config, Ptr const& reporter ) + : m_runInfo( _config->name() ), + m_context( getCurrentMutableContext() ), + m_activeTestCase( CATCH_NULL ), + m_config( _config ), + m_reporter( reporter ) + { + m_context.setRunner( this ); + m_context.setConfig( m_config ); + m_context.setResultCapture( this ); + m_reporter->testRunStarting( m_runInfo ); + } + + virtual ~RunContext() { + m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); + } + + void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { + m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) ); + } + void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) { + m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); + } + + Totals runTest( TestCase const& testCase ) { + Totals prevTotals = m_totals; + + std::string redirectedCout; + std::string redirectedCerr; + + TestCaseInfo testInfo = testCase.getTestCaseInfo(); + + m_reporter->testCaseStarting( testInfo ); + + m_activeTestCase = &testCase; + + + do { + ITracker& rootTracker = m_trackerContext.startRun(); + assert( rootTracker.isSectionTracker() ); + static_cast( rootTracker ).addInitialFilters( m_config->getSectionsToRun() ); + do { + m_trackerContext.startCycle(); + m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) ); + runCurrentTest( redirectedCout, redirectedCerr ); + } + while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); + } + // !TBD: deprecated - this will be replaced by indexed trackers + while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); + + Totals deltaTotals = m_totals.delta( prevTotals ); + if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) { + deltaTotals.assertions.failed++; + deltaTotals.testCases.passed--; + deltaTotals.testCases.failed++; + } + m_totals.testCases += deltaTotals.testCases; + m_reporter->testCaseEnded( TestCaseStats( testInfo, + deltaTotals, + redirectedCout, + redirectedCerr, + aborting() ) ); + + m_activeTestCase = CATCH_NULL; + m_testCaseTracker = CATCH_NULL; + + return deltaTotals; + } + + Ptr config() const { + return m_config; + } + + private: // IResultCapture + + + virtual void assertionEnded( AssertionResult const& result ) { + if( result.getResultType() == ResultWas::Ok ) { + m_totals.assertions.passed++; + } + else if( !result.isOk() ) { + m_totals.assertions.failed++; + } + + if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) ) + m_messages.clear(); + + // Reset working state + m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); + m_lastResult = result; + } + + virtual bool sectionStarted ( + SectionInfo const& sectionInfo, + Counts& assertions + ) + { + ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) ); + if( !sectionTracker.isOpen() ) + return false; + m_activeSections.push_back( §ionTracker ); + + m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; + + m_reporter->sectionStarting( sectionInfo ); + + assertions = m_totals.assertions; + + return true; + } + bool testForMissingAssertions( Counts& assertions ) { + if( assertions.total() != 0 ) + return false; + if( !m_config->warnAboutMissingAssertions() ) + return false; + if( m_trackerContext.currentTracker().hasChildren() ) + return false; + m_totals.assertions.failed++; + assertions.failed++; + return true; + } + + virtual void sectionEnded( SectionEndInfo const& endInfo ) { + Counts assertions = m_totals.assertions - endInfo.prevAssertions; + bool missingAssertions = testForMissingAssertions( assertions ); + + if( !m_activeSections.empty() ) { + m_activeSections.back()->close(); + m_activeSections.pop_back(); + } + + m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) ); + m_messages.clear(); + } + + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) { + if( m_unfinishedSections.empty() ) + m_activeSections.back()->fail(); + else + m_activeSections.back()->close(); + m_activeSections.pop_back(); + + m_unfinishedSections.push_back( endInfo ); + } + + virtual void pushScopedMessage( MessageInfo const& message ) { + m_messages.push_back( message ); + } + + virtual void popScopedMessage( MessageInfo const& message ) { + m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() ); + } + + virtual std::string getCurrentTestName() const { + return m_activeTestCase + ? m_activeTestCase->getTestCaseInfo().name + : std::string(); + } + + virtual const AssertionResult* getLastResult() const { + return &m_lastResult; + } + + virtual void handleFatalErrorCondition( std::string const& message ) { + // Don't rebuild the result -- the stringification itself can cause more fatal errors + // Instead, fake a result data. + AssertionResultData tempResult; + tempResult.resultType = ResultWas::FatalErrorCondition; + tempResult.message = message; + AssertionResult result(m_lastAssertionInfo, tempResult); + + getResultCapture().assertionEnded(result); + + handleUnfinishedSections(); + + // Recreate section for test case (as we will lose the one that was in scope) + TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); + + Counts assertions; + assertions.failed = 1; + SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); + m_reporter->sectionEnded( testCaseSectionStats ); + + TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); + + Totals deltaTotals; + deltaTotals.testCases.failed = 1; + m_reporter->testCaseEnded( TestCaseStats( testInfo, + deltaTotals, + std::string(), + std::string(), + false ) ); + m_totals.testCases.failed++; + testGroupEnded( std::string(), m_totals, 1, 1 ); + m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); + } + + public: + // !TBD We need to do this another way! + bool aborting() const { + return m_totals.assertions.failed == static_cast( m_config->abortAfter() ); + } + + private: + + void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { + TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); + m_reporter->sectionStarting( testCaseSection ); + Counts prevAssertions = m_totals.assertions; + double duration = 0; + try { + m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, std::string(), ResultDisposition::Normal ); + + seedRng( *m_config ); + + Timer timer; + timer.start(); + if( m_reporter->getPreferences().shouldRedirectStdOut ) { + StreamRedirect coutRedir( Catch::cout(), redirectedCout ); + StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr ); + invokeActiveTestCase(); + } + else { + invokeActiveTestCase(); + } + duration = timer.getElapsedSeconds(); + } + catch( TestFailureException& ) { + // This just means the test was aborted due to failure + } + catch(...) { + makeUnexpectedResultBuilder().useActiveException(); + } + m_testCaseTracker->close(); + handleUnfinishedSections(); + m_messages.clear(); + + Counts assertions = m_totals.assertions - prevAssertions; + bool missingAssertions = testForMissingAssertions( assertions ); + + if( testCaseInfo.okToFail() ) { + std::swap( assertions.failedButOk, assertions.failed ); + m_totals.assertions.failed -= assertions.failedButOk; + m_totals.assertions.failedButOk += assertions.failedButOk; + } + + SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions ); + m_reporter->sectionEnded( testCaseSectionStats ); + } + + void invokeActiveTestCase() { + FatalConditionHandler fatalConditionHandler; // Handle signals + m_activeTestCase->invoke(); + fatalConditionHandler.reset(); + } + + private: + + ResultBuilder makeUnexpectedResultBuilder() const { + return ResultBuilder( m_lastAssertionInfo.macroName.c_str(), + m_lastAssertionInfo.lineInfo, + m_lastAssertionInfo.capturedExpression.c_str(), + m_lastAssertionInfo.resultDisposition ); + } + + void handleUnfinishedSections() { + // If sections ended prematurely due to an exception we stored their + // infos here so we can tear them down outside the unwind process. + for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), + itEnd = m_unfinishedSections.rend(); + it != itEnd; + ++it ) + sectionEnded( *it ); + m_unfinishedSections.clear(); + } + + TestRunInfo m_runInfo; + IMutableContext& m_context; + TestCase const* m_activeTestCase; + ITracker* m_testCaseTracker; + ITracker* m_currentSectionTracker; + AssertionResult m_lastResult; + + Ptr m_config; + Totals m_totals; + Ptr m_reporter; + std::vector m_messages; + AssertionInfo m_lastAssertionInfo; + std::vector m_unfinishedSections; + std::vector m_activeSections; + TrackerContext m_trackerContext; + }; + + IResultCapture& getResultCapture() { + if( IResultCapture* capture = getCurrentContext().getResultCapture() ) + return *capture; + else + throw std::logic_error( "No result capture instance" ); + } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section.h new file mode 100644 index 0000000..d8b3ae4 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section.h @@ -0,0 +1,46 @@ +/* + * Created by Phil on 03/12/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_SECTION_H_INCLUDED +#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED + +#include "catch_section_info.h" +#include "catch_totals.hpp" +#include "catch_timer.h" + +#include + +namespace Catch { + + class Section : NonCopyable { + public: + Section( SectionInfo const& info ); + ~Section(); + + // This indicates whether the section should be executed or not + operator bool() const; + + private: + SectionInfo m_info; + + std::string m_name; + Counts m_assertions; + bool m_sectionIncluded; + Timer m_timer; + }; + +} // end namespace Catch + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define INTERNAL_CATCH_SECTION( ... ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) +#else + #define INTERNAL_CATCH_SECTION( name, desc ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) +#endif + +#endif // TWOBLUECUBES_CATCH_SECTION_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section.hpp new file mode 100644 index 0000000..a5d1b6d --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section.hpp @@ -0,0 +1,51 @@ +/* + * Created by Phil on 03/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED + +#include "catch_section.h" +#include "catch_capture.hpp" +#include "catch_compiler_capabilities.h" + +namespace Catch { + + SectionInfo::SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description ) + : name( _name ), + description( _description ), + lineInfo( _lineInfo ) + {} + + Section::Section( SectionInfo const& info ) + : m_info( info ), + m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) + { + m_timer.start(); + } + + Section::~Section() { + if( m_sectionIncluded ) { + SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); + if( std::uncaught_exception() ) + getResultCapture().sectionEndedEarly( endInfo ); + else + getResultCapture().sectionEnded( endInfo ); + } + } + + // This indicates whether the section should be executed or not + Section::operator bool() const { + return m_sectionIncluded; + } + + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section_info.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section_info.h new file mode 100644 index 0000000..c9f1c7f --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section_info.h @@ -0,0 +1,41 @@ +/* + * Created by Phil on 03/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED +#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED + +#include "catch_common.h" +#include "catch_totals.hpp" + +#include + +namespace Catch { + + struct SectionInfo { + SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description = std::string() ); + + std::string name; + std::string description; + SourceLineInfo lineInfo; + }; + + struct SectionEndInfo { + SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ) + : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) + {} + + SectionInfo sectionInfo; + Counts prevAssertions; + double durationInSeconds; + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section_info.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section_info.hpp new file mode 100644 index 0000000..aebbf6a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_section_info.hpp @@ -0,0 +1,110 @@ +/* + * Created by Phil Nash on 4/5/2012 + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_SECTION_INFO_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_SECTION_INFO_HPP_INCLUDED + +#include "catch_section_info.h" + +namespace Catch { + + class RunningSection { + public: + + typedef std::vector SubSections; + + enum State { + Root, + Unknown, + Branch, + TestedBranch, + TestedLeaf + }; + + RunningSection( RunningSection* parent, std::string const& name ) + : m_state( Unknown ), + m_parent( parent ), + m_name( name ) + {} + + RunningSection( std::string const& name ) + : m_state( Root ), + m_parent( CATCH_NULL ), + m_name( name ) + {} + + ~RunningSection() { + deleteAll( m_subSections ); + } + + std::string getName() const { + return m_name; + } + + bool shouldRun() const { + return m_state < TestedBranch; + } + + bool isBranch() const { + return m_state == Branch; + } + + const RunningSection* getParent() const { + return m_parent; + } + + bool hasUntestedSections() const { + if( m_state == Unknown ) + return true; + for( SubSections::const_iterator it = m_subSections.begin(); + it != m_subSections.end(); + ++it) + if( (*it)->hasUntestedSections() ) + return true; + return false; + } + + // Mutable methods: + + RunningSection* getParent() { + return m_parent; + } + + RunningSection* findOrAddSubSection( std::string const& name, bool& changed ) { + for( SubSections::const_iterator it = m_subSections.begin(); + it != m_subSections.end(); + ++it) + if( (*it)->getName() == name ) + return *it; + RunningSection* subSection = new RunningSection( this, name ); + m_subSections.push_back( subSection ); + m_state = Branch; + changed = true; + return subSection; + } + + bool ran() { + if( m_state >= Branch ) + return false; + m_state = TestedLeaf; + return true; + } + + void ranToCompletion() { + if( m_state == Branch && !hasUntestedSections() ) + m_state = TestedBranch; + } + + private: + State m_state; + RunningSection* m_parent; + std::string m_name; + SubSections m_subSections; + }; +} + +#endif // TWOBLUECUBES_CATCH_SECTION_INFO_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_stream.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_stream.h new file mode 100644 index 0000000..d8deeba --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_stream.h @@ -0,0 +1,64 @@ +/* + * Created by Phil on 2/12/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ +#ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED +#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED + +#include "catch_compiler_capabilities.h" +#include "catch_streambuf.h" + +#include +#include +#include +#include + +namespace Catch { + + std::ostream& cout(); + std::ostream& cerr(); + + + struct IStream { + virtual ~IStream() CATCH_NOEXCEPT; + virtual std::ostream& stream() const = 0; + }; + + class FileStream : public IStream { + mutable std::ofstream m_ofs; + public: + FileStream( std::string const& filename ); + virtual ~FileStream() CATCH_NOEXCEPT; + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; + + + class CoutStream : public IStream { + mutable std::ostream m_os; + public: + CoutStream(); + virtual ~CoutStream() CATCH_NOEXCEPT; + + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; + + + class DebugOutStream : public IStream { + CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf; + mutable std::ostream m_os; + public: + DebugOutStream(); + virtual ~DebugOutStream() CATCH_NOEXCEPT; + + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; +} + +#endif // TWOBLUECUBES_CATCH_STREAM_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_stream.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_stream.hpp new file mode 100644 index 0000000..42f51e8 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_stream.hpp @@ -0,0 +1,109 @@ +/* + * Created by Phil on 17/01/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ +#ifndef TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED + +#include "catch_stream.h" +#include "catch_debugger.h" + +#include +#include +#include + +namespace Catch { + + template + class StreamBufImpl : public StreamBufBase { + char data[bufferSize]; + WriterF m_writer; + + public: + StreamBufImpl() { + setp( data, data + sizeof(data) ); + } + + ~StreamBufImpl() CATCH_NOEXCEPT { + sync(); + } + + private: + int overflow( int c ) { + sync(); + + if( c != EOF ) { + if( pbase() == epptr() ) + m_writer( std::string( 1, static_cast( c ) ) ); + else + sputc( static_cast( c ) ); + } + return 0; + } + + int sync() { + if( pbase() != pptr() ) { + m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) ); + setp( pbase(), epptr() ); + } + return 0; + } + }; + + /////////////////////////////////////////////////////////////////////////// + + + FileStream::FileStream( std::string const& filename ) { + m_ofs.open( filename.c_str() ); + if( m_ofs.fail() ) { + std::ostringstream oss; + oss << "Unable to open file: '" << filename << '\''; + throw std::domain_error( oss.str() ); + } + } + + std::ostream& FileStream::stream() const { + return m_ofs; + } + + struct OutputDebugWriter { + + void operator()( std::string const&str ) { + writeToDebugConsole( str ); + } + }; + + DebugOutStream::DebugOutStream() + : m_streamBuf( new StreamBufImpl() ), + m_os( m_streamBuf.get() ) + {} + + std::ostream& DebugOutStream::stream() const { + return m_os; + } + + // Store the streambuf from cout up-front because + // cout may get redirected when running tests + CoutStream::CoutStream() + : m_os( Catch::cout().rdbuf() ) + {} + + std::ostream& CoutStream::stream() const { + return m_os; + } + +#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions + std::ostream& cout() { + return std::cout; + } + std::ostream& cerr() { + return std::cerr; + } +#endif +} + +#endif // TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_streambuf.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_streambuf.h new file mode 100644 index 0000000..4f5e238 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_streambuf.h @@ -0,0 +1,23 @@ +/* + * Created by Phil on 27/11/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED +#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED + +#include "catch_compiler_capabilities.h" + +#include + +namespace Catch { + + class StreamBufBase : public std::streambuf { + public: + virtual ~StreamBufBase() CATCH_NOEXCEPT; + }; +} + +#endif // TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_suppress_warnings.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_suppress_warnings.h new file mode 100644 index 0000000..ffaab69 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_suppress_warnings.h @@ -0,0 +1,35 @@ +/* + * Copyright 2014 Two Blue Cubes Ltd + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic ignored "-Wglobal-constructors" +# pragma clang diagnostic ignored "-Wvariadic-macros" +# pragma clang diagnostic ignored "-Wc99-extensions" +# pragma clang diagnostic ignored "-Wunused-variable" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wc++98-compat" +# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic ignored "-Wvariadic-macros" +# pragma GCC diagnostic ignored "-Wunused-variable" + + // For newer version we can use __Pragma to disable the warnings locally +# if __GNUC__ == 4 && __GNUC_MINOR__ >= 4 && __GNUC_MINOR__ <= 7 +# pragma GCC diagnostic ignored "-Wparentheses" +# endif + +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tag_alias.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tag_alias.h new file mode 100644 index 0000000..6dde74a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tag_alias.h @@ -0,0 +1,32 @@ +/* + * Created by Phil on 27/6/2014. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED +#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED + +#include "catch_common.h" + +#include + +namespace Catch { + + struct TagAlias { + TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} + + std::string tag; + SourceLineInfo lineInfo; + }; + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tag_alias_registry.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tag_alias_registry.h new file mode 100644 index 0000000..98c796e --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tag_alias_registry.h @@ -0,0 +1,31 @@ +/* + * Created by Phil on 27/6/2014. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED +#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED + +#include "catch_interfaces_tag_alias_registry.h" + +#include + +namespace Catch { + + class TagAliasRegistry : public ITagAliasRegistry { + public: + virtual ~TagAliasRegistry(); + virtual Option find( std::string const& alias ) const; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const; + void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + static TagAliasRegistry& get(); + + private: + std::map m_registry; + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tag_alias_registry.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tag_alias_registry.hpp new file mode 100644 index 0000000..cc04ea1 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tag_alias_registry.hpp @@ -0,0 +1,80 @@ +/* + * Created by Phil on 27/6/2014. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED + +#include "catch_tag_alias_registry.h" +#include "catch_console_colour.hpp" + +namespace Catch { + + TagAliasRegistry::~TagAliasRegistry() {} + + Option TagAliasRegistry::find( std::string const& alias ) const { + std::map::const_iterator it = m_registry.find( alias ); + if( it != m_registry.end() ) + return it->second; + else + return Option(); + } + + std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { + std::string expandedTestSpec = unexpandedTestSpec; + for( std::map::const_iterator it = m_registry.begin(), itEnd = m_registry.end(); + it != itEnd; + ++it ) { + std::size_t pos = expandedTestSpec.find( it->first ); + if( pos != std::string::npos ) { + expandedTestSpec = expandedTestSpec.substr( 0, pos ) + + it->second.tag + + expandedTestSpec.substr( pos + it->first.size() ); + } + } + return expandedTestSpec; + } + + void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { + + if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) { + std::ostringstream oss; + oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo; + throw std::domain_error( oss.str().c_str() ); + } + if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { + std::ostringstream oss; + oss << "error: tag alias, \"" << alias << "\" already registered.\n" + << "\tFirst seen at " << find(alias)->lineInfo << '\n' + << "\tRedefined at " << lineInfo; + throw std::domain_error( oss.str().c_str() ); + } + } + + TagAliasRegistry& TagAliasRegistry::get() { + static TagAliasRegistry instance; + return instance; + + } + + ITagAliasRegistry::~ITagAliasRegistry() {} + ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); } + + + RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { + try { + TagAliasRegistry::get().add( alias, tag, lineInfo ); + } + catch( std::exception& ex ) { + Colour colourGuard( Colour::Red ); + Catch::cerr() << ex.what() << std::endl; + exit(1); + } + } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_info.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_info.h new file mode 100644 index 0000000..b821abd --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_info.h @@ -0,0 +1,93 @@ +/* + * Created by Phil on 29/10/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED +#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED + +#include "catch_common.h" +#include "catch_ptr.hpp" + +#include +#include + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + struct ITestCase; + + struct TestCaseInfo { + enum SpecialProperties{ + None = 0, + IsHidden = 1 << 1, + ShouldFail = 1 << 2, + MayFail = 1 << 3, + Throws = 1 << 4, + NonPortable = 1 << 5 + }; + + TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::set const& _tags, + SourceLineInfo const& _lineInfo ); + + TestCaseInfo( TestCaseInfo const& other ); + + friend void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ); + + bool isHidden() const; + bool throws() const; + bool okToFail() const; + bool expectedToFail() const; + + std::string name; + std::string className; + std::string description; + std::set tags; + std::set lcaseTags; + std::string tagsAsString; + SourceLineInfo lineInfo; + SpecialProperties properties; + }; + + class TestCase : public TestCaseInfo { + public: + + TestCase( ITestCase* testCase, TestCaseInfo const& info ); + TestCase( TestCase const& other ); + + TestCase withName( std::string const& _newName ) const; + + void invoke() const; + + TestCaseInfo const& getTestCaseInfo() const; + + void swap( TestCase& other ); + bool operator == ( TestCase const& other ) const; + bool operator < ( TestCase const& other ) const; + TestCase& operator = ( TestCase const& other ); + + private: + Ptr test; + }; + + TestCase makeTestCase( ITestCase* testCase, + std::string const& className, + std::string const& name, + std::string const& description, + SourceLineInfo const& lineInfo ); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif // TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_info.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_info.hpp new file mode 100644 index 0000000..b4ca53a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_info.hpp @@ -0,0 +1,205 @@ +/* + * Created by Phil on 14/08/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED + +#include "catch_test_spec.hpp" +#include "catch_test_case_info.h" +#include "catch_interfaces_testcase.h" +#include "catch_common.h" + +#include + +namespace Catch { + + inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { + if( startsWith( tag, '.' ) || + tag == "hide" || + tag == "!hide" ) + return TestCaseInfo::IsHidden; + else if( tag == "!throws" ) + return TestCaseInfo::Throws; + else if( tag == "!shouldfail" ) + return TestCaseInfo::ShouldFail; + else if( tag == "!mayfail" ) + return TestCaseInfo::MayFail; + else if( tag == "!nonportable" ) + return TestCaseInfo::NonPortable; + else + return TestCaseInfo::None; + } + inline bool isReservedTag( std::string const& tag ) { + return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] ); + } + inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { + if( isReservedTag( tag ) ) { + { + Colour colourGuard( Colour::Red ); + Catch::cerr() + << "Tag name [" << tag << "] not allowed.\n" + << "Tag names starting with non alpha-numeric characters are reserved\n"; + } + { + Colour colourGuard( Colour::FileName ); + Catch::cerr() << _lineInfo << std::endl; + } + exit(1); + } + } + + TestCase makeTestCase( ITestCase* _testCase, + std::string const& _className, + std::string const& _name, + std::string const& _descOrTags, + SourceLineInfo const& _lineInfo ) + { + bool isHidden( startsWith( _name, "./" ) ); // Legacy support + + // Parse out tags + std::set tags; + std::string desc, tag; + bool inTag = false; + for( std::size_t i = 0; i < _descOrTags.size(); ++i ) { + char c = _descOrTags[i]; + if( !inTag ) { + if( c == '[' ) + inTag = true; + else + desc += c; + } + else { + if( c == ']' ) { + TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); + if( prop == TestCaseInfo::IsHidden ) + isHidden = true; + else if( prop == TestCaseInfo::None ) + enforceNotReservedTag( tag, _lineInfo ); + + tags.insert( tag ); + tag.clear(); + inTag = false; + } + else + tag += c; + } + } + if( isHidden ) { + tags.insert( "hide" ); + tags.insert( "." ); + } + + TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); + return TestCase( _testCase, info ); + } + + void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ) + { + testCaseInfo.tags = tags; + testCaseInfo.lcaseTags.clear(); + + std::ostringstream oss; + for( std::set::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) { + oss << '[' << *it << ']'; + std::string lcaseTag = toLower( *it ); + testCaseInfo.properties = static_cast( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); + testCaseInfo.lcaseTags.insert( lcaseTag ); + } + testCaseInfo.tagsAsString = oss.str(); + } + + TestCaseInfo::TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::set const& _tags, + SourceLineInfo const& _lineInfo ) + : name( _name ), + className( _className ), + description( _description ), + lineInfo( _lineInfo ), + properties( None ) + { + setTags( *this, _tags ); + } + + TestCaseInfo::TestCaseInfo( TestCaseInfo const& other ) + : name( other.name ), + className( other.className ), + description( other.description ), + tags( other.tags ), + lcaseTags( other.lcaseTags ), + tagsAsString( other.tagsAsString ), + lineInfo( other.lineInfo ), + properties( other.properties ) + {} + + bool TestCaseInfo::isHidden() const { + return ( properties & IsHidden ) != 0; + } + bool TestCaseInfo::throws() const { + return ( properties & Throws ) != 0; + } + bool TestCaseInfo::okToFail() const { + return ( properties & (ShouldFail | MayFail ) ) != 0; + } + bool TestCaseInfo::expectedToFail() const { + return ( properties & (ShouldFail ) ) != 0; + } + + + TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} + + TestCase::TestCase( TestCase const& other ) + : TestCaseInfo( other ), + test( other.test ) + {} + + TestCase TestCase::withName( std::string const& _newName ) const { + TestCase other( *this ); + other.name = _newName; + return other; + } + + void TestCase::swap( TestCase& other ) { + test.swap( other.test ); + name.swap( other.name ); + className.swap( other.className ); + description.swap( other.description ); + tags.swap( other.tags ); + lcaseTags.swap( other.lcaseTags ); + tagsAsString.swap( other.tagsAsString ); + std::swap( TestCaseInfo::properties, static_cast( other ).properties ); + std::swap( lineInfo, other.lineInfo ); + } + + void TestCase::invoke() const { + test->invoke(); + } + + bool TestCase::operator == ( TestCase const& other ) const { + return test.get() == other.test.get() && + name == other.name && + className == other.className; + } + + bool TestCase::operator < ( TestCase const& other ) const { + return name < other.name; + } + TestCase& TestCase::operator = ( TestCase const& other ) { + TestCase temp( other ); + swap( temp ); + return *this; + } + + TestCaseInfo const& TestCase::getTestCaseInfo() const + { + return *this; + } + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_registry_impl.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_registry_impl.hpp new file mode 100644 index 0000000..316c6c2 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_registry_impl.hpp @@ -0,0 +1,207 @@ +/* + * Created by Phil on 7/1/2011 + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED + +#include "catch_test_registry.hpp" +#include "catch_test_case_info.h" +#include "catch_test_spec.hpp" +#include "catch_context.h" + +#include +#include +#include +#include + + +namespace Catch { + + struct RandomNumberGenerator { + typedef std::ptrdiff_t result_type; + + result_type operator()( result_type n ) const { return std::rand() % n; } + +#ifdef CATCH_CONFIG_CPP11_SHUFFLE + static constexpr result_type min() { return 0; } + static constexpr result_type max() { return 1000000; } + result_type operator()() const { return std::rand() % max(); } +#endif + template + static void shuffle( V& vector ) { + RandomNumberGenerator rng; +#ifdef CATCH_CONFIG_CPP11_SHUFFLE + std::shuffle( vector.begin(), vector.end(), rng ); +#else + std::random_shuffle( vector.begin(), vector.end(), rng ); +#endif + } + }; + + inline std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) { + + std::vector sorted = unsortedTestCases; + + switch( config.runOrder() ) { + case RunTests::InLexicographicalOrder: + std::sort( sorted.begin(), sorted.end() ); + break; + case RunTests::InRandomOrder: + { + seedRng( config ); + RandomNumberGenerator::shuffle( sorted ); + } + break; + case RunTests::InDeclarationOrder: + // already in declaration order + break; + } + return sorted; + } + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { + return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); + } + + void enforceNoDuplicateTestCases( std::vector const& functions ) { + std::set seenFunctions; + for( std::vector::const_iterator it = functions.begin(), itEnd = functions.end(); + it != itEnd; + ++it ) { + std::pair::const_iterator, bool> prev = seenFunctions.insert( *it ); + if( !prev.second ) { + std::ostringstream ss; + + ss << Colour( Colour::Red ) + << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n" + << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n' + << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl; + + throw std::runtime_error(ss.str()); + } + } + } + + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) { + std::vector filtered; + filtered.reserve( testCases.size() ); + for( std::vector::const_iterator it = testCases.begin(), itEnd = testCases.end(); + it != itEnd; + ++it ) + if( matchTest( *it, testSpec, config ) ) + filtered.push_back( *it ); + return filtered; + } + std::vector const& getAllTestCasesSorted( IConfig const& config ) { + return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); + } + + class TestRegistry : public ITestCaseRegistry { + public: + TestRegistry() + : m_currentSortOrder( RunTests::InDeclarationOrder ), + m_unnamedCount( 0 ) + {} + virtual ~TestRegistry(); + + virtual void registerTest( TestCase const& testCase ) { + std::string name = testCase.getTestCaseInfo().name; + if( name.empty() ) { + std::ostringstream oss; + oss << "Anonymous test case " << ++m_unnamedCount; + return registerTest( testCase.withName( oss.str() ) ); + } + m_functions.push_back( testCase ); + } + + virtual std::vector const& getAllTests() const { + return m_functions; + } + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const { + if( m_sortedFunctions.empty() ) + enforceNoDuplicateTestCases( m_functions ); + + if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { + m_sortedFunctions = sortTests( config, m_functions ); + m_currentSortOrder = config.runOrder(); + } + return m_sortedFunctions; + } + + private: + std::vector m_functions; + mutable RunTests::InWhatOrder m_currentSortOrder; + mutable std::vector m_sortedFunctions; + size_t m_unnamedCount; + std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised + }; + + /////////////////////////////////////////////////////////////////////////// + + class FreeFunctionTestCase : public SharedImpl { + public: + + FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} + + virtual void invoke() const { + m_fun(); + } + + private: + virtual ~FreeFunctionTestCase(); + + TestFunction m_fun; + }; + + inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { + std::string className = classOrQualifiedMethodName; + if( startsWith( className, '&' ) ) + { + std::size_t lastColons = className.rfind( "::" ); + std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); + if( penultimateColons == std::string::npos ) + penultimateColons = 1; + className = className.substr( penultimateColons, lastColons-penultimateColons ); + } + return className; + } + + void registerTestCase + ( ITestCase* testCase, + char const* classOrQualifiedMethodName, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ) { + + getMutableRegistryHub().registerTest + ( makeTestCase + ( testCase, + extractClassName( classOrQualifiedMethodName ), + nameAndDesc.name, + nameAndDesc.description, + lineInfo ) ); + } + void registerTestCaseFunction + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ) { + registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); + } + + /////////////////////////////////////////////////////////////////////////// + + AutoReg::AutoReg + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ) { + registerTestCaseFunction( function, lineInfo, nameAndDesc ); + } + + AutoReg::~AutoReg() {} + +} // end namespace Catch + + +#endif // TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_tracker.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_tracker.hpp new file mode 100644 index 0000000..9526e28 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_case_tracker.hpp @@ -0,0 +1,368 @@ +/* + * Created by Phil Nash on 23/7/2013 + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED + +#include "catch_compiler_capabilities.h" +#include "catch_ptr.hpp" + +#include +#include +#include +#include +#include +#include + +namespace Catch { +namespace TestCaseTracking { + + struct NameAndLocation { + std::string name; + SourceLineInfo location; + + NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) + : name( _name ), + location( _location ) + {} + }; + + struct ITracker : SharedImpl<> { + virtual ~ITracker(); + + // static queries + virtual NameAndLocation const& nameAndLocation() const = 0; + + // dynamic queries + virtual bool isComplete() const = 0; // Successfully completed or failed + virtual bool isSuccessfullyCompleted() const = 0; + virtual bool isOpen() const = 0; // Started but not complete + virtual bool hasChildren() const = 0; + + virtual ITracker& parent() = 0; + + // actions + virtual void close() = 0; // Successfully complete + virtual void fail() = 0; + virtual void markAsNeedingAnotherRun() = 0; + + virtual void addChild( Ptr const& child ) = 0; + virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0; + virtual void openChild() = 0; + + // Debug/ checking + virtual bool isSectionTracker() const = 0; + virtual bool isIndexTracker() const = 0; + }; + + class TrackerContext { + + enum RunState { + NotStarted, + Executing, + CompletedCycle + }; + + Ptr m_rootTracker; + ITracker* m_currentTracker; + RunState m_runState; + + public: + + static TrackerContext& instance() { + static TrackerContext s_instance; + return s_instance; + } + + TrackerContext() + : m_currentTracker( CATCH_NULL ), + m_runState( NotStarted ) + {} + + + ITracker& startRun(); + + void endRun() { + m_rootTracker.reset(); + m_currentTracker = CATCH_NULL; + m_runState = NotStarted; + } + + void startCycle() { + m_currentTracker = m_rootTracker.get(); + m_runState = Executing; + } + void completeCycle() { + m_runState = CompletedCycle; + } + + bool completedCycle() const { + return m_runState == CompletedCycle; + } + ITracker& currentTracker() { + return *m_currentTracker; + } + void setCurrentTracker( ITracker* tracker ) { + m_currentTracker = tracker; + } + }; + + class TrackerBase : public ITracker { + protected: + enum CycleState { + NotStarted, + Executing, + ExecutingChildren, + NeedsAnotherRun, + CompletedSuccessfully, + Failed + }; + class TrackerHasName { + NameAndLocation m_nameAndLocation; + public: + TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {} + bool operator ()( Ptr const& tracker ) { + return + tracker->nameAndLocation().name == m_nameAndLocation.name && + tracker->nameAndLocation().location == m_nameAndLocation.location; + } + }; + typedef std::vector > Children; + NameAndLocation m_nameAndLocation; + TrackerContext& m_ctx; + ITracker* m_parent; + Children m_children; + CycleState m_runState; + public: + TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : m_nameAndLocation( nameAndLocation ), + m_ctx( ctx ), + m_parent( parent ), + m_runState( NotStarted ) + {} + virtual ~TrackerBase(); + + virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE { + return m_nameAndLocation; + } + virtual bool isComplete() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully || m_runState == Failed; + } + virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully; + } + virtual bool isOpen() const CATCH_OVERRIDE { + return m_runState != NotStarted && !isComplete(); + } + virtual bool hasChildren() const CATCH_OVERRIDE { + return !m_children.empty(); + } + + + virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { + m_children.push_back( child ); + } + + virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE { + Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) ); + return( it != m_children.end() ) + ? it->get() + : CATCH_NULL; + } + virtual ITracker& parent() CATCH_OVERRIDE { + assert( m_parent ); // Should always be non-null except for root + return *m_parent; + } + + virtual void openChild() CATCH_OVERRIDE { + if( m_runState != ExecutingChildren ) { + m_runState = ExecutingChildren; + if( m_parent ) + m_parent->openChild(); + } + } + + virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; } + virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; } + + void open() { + m_runState = Executing; + moveToThis(); + if( m_parent ) + m_parent->openChild(); + } + + virtual void close() CATCH_OVERRIDE { + + // Close any still open children (e.g. generators) + while( &m_ctx.currentTracker() != this ) + m_ctx.currentTracker().close(); + + switch( m_runState ) { + case NotStarted: + case CompletedSuccessfully: + case Failed: + throw std::logic_error( "Illogical state" ); + + case NeedsAnotherRun: + break;; + + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if( m_children.empty() || m_children.back()->isComplete() ) + m_runState = CompletedSuccessfully; + break; + + default: + throw std::logic_error( "Unexpected state" ); + } + moveToParent(); + m_ctx.completeCycle(); + } + virtual void fail() CATCH_OVERRIDE { + m_runState = Failed; + if( m_parent ) + m_parent->markAsNeedingAnotherRun(); + moveToParent(); + m_ctx.completeCycle(); + } + virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { + m_runState = NeedsAnotherRun; + } + private: + void moveToParent() { + assert( m_parent ); + m_ctx.setCurrentTracker( m_parent ); + } + void moveToThis() { + m_ctx.setCurrentTracker( this ); + } + }; + + class SectionTracker : public TrackerBase { + std::vector m_filters; + public: + SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( nameAndLocation, ctx, parent ) + { + if( parent ) { + while( !parent->isSectionTracker() ) + parent = &parent->parent(); + + SectionTracker& parentSection = static_cast( *parent ); + addNextFilters( parentSection.m_filters ); + } + } + virtual ~SectionTracker(); + + virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; } + + static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { + SectionTracker* section = CATCH_NULL; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isSectionTracker() ); + section = static_cast( childTracker ); + } + else { + section = new SectionTracker( nameAndLocation, ctx, ¤tTracker ); + currentTracker.addChild( section ); + } + if( !ctx.completedCycle() ) + section->tryOpen(); + return *section; + } + + void tryOpen() { + if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) ) + open(); + } + + void addInitialFilters( std::vector const& filters ) { + if( !filters.empty() ) { + m_filters.push_back(""); // Root - should never be consulted + m_filters.push_back(""); // Test Case - not a section filter + std::copy( filters.begin(), filters.end(), std::back_inserter( m_filters ) ); + } + } + void addNextFilters( std::vector const& filters ) { + if( filters.size() > 1 ) + std::copy( filters.begin()+1, filters.end(), std::back_inserter( m_filters ) ); + } + }; + + class IndexTracker : public TrackerBase { + int m_size; + int m_index; + public: + IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ) + : TrackerBase( nameAndLocation, ctx, parent ), + m_size( size ), + m_index( -1 ) + {} + virtual ~IndexTracker(); + + virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; } + + static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) { + IndexTracker* tracker = CATCH_NULL; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isIndexTracker() ); + tracker = static_cast( childTracker ); + } + else { + tracker = new IndexTracker( nameAndLocation, ctx, ¤tTracker, size ); + currentTracker.addChild( tracker ); + } + + if( !ctx.completedCycle() && !tracker->isComplete() ) { + if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) + tracker->moveNext(); + tracker->open(); + } + + return *tracker; + } + + int index() const { return m_index; } + + void moveNext() { + m_index++; + m_children.clear(); + } + + virtual void close() CATCH_OVERRIDE { + TrackerBase::close(); + if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) + m_runState = Executing; + } + }; + + inline ITracker& TrackerContext::startRun() { + m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL ); + m_currentTracker = CATCH_NULL; + m_runState = Executing; + return *m_rootTracker; + } + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +} // namespace Catch + +#endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_registry.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_registry.hpp new file mode 100644 index 0000000..a35c35d --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_registry.hpp @@ -0,0 +1,145 @@ +/* + * Created by Phil on 18/10/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED + +#include "catch_common.h" +#include "catch_interfaces_testcase.h" +#include "catch_compiler_capabilities.h" + +namespace Catch { + +template +class MethodTestCase : public SharedImpl { + +public: + MethodTestCase( void (C::*method)() ) : m_method( method ) {} + + virtual void invoke() const { + C obj; + (obj.*m_method)(); + } + +private: + virtual ~MethodTestCase() {} + + void (C::*m_method)(); +}; + +typedef void(*TestFunction)(); + +struct NameAndDesc { + NameAndDesc( const char* _name = "", const char* _description= "" ) + : name( _name ), description( _description ) + {} + + const char* name; + const char* description; +}; + +void registerTestCase + ( ITestCase* testCase, + char const* className, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ); + +struct AutoReg { + + AutoReg + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ); + + template + AutoReg + ( void (C::*method)(), + char const* className, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ) { + + registerTestCase + ( new MethodTestCase( method ), + className, + nameAndDesc, + lineInfo ); + } + + ~AutoReg(); + +private: + AutoReg( AutoReg const& ); + void operator= ( AutoReg const& ); +}; + +void registerTestCaseFunction + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ); + +} // end namespace Catch + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ + static void TestName(); \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( ... ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ + namespace{ \ + struct TestName : ClassName{ \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \ + } \ + void TestName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ + Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); + +#else + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \ + static void TestName(); \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\ + namespace{ \ + struct TestCaseName : ClassName{ \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \ + } \ + void TestCaseName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \ + Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); +#endif + +#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_spec.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_spec.hpp new file mode 100644 index 0000000..3ec59b5 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_spec.hpp @@ -0,0 +1,98 @@ +/* + * Created by Phil on 14/8/2012. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +#include "catch_wildcard_pattern.hpp" +#include "catch_test_case_info.h" + +#include +#include + +namespace Catch { + + class TestSpec { + struct Pattern : SharedImpl<> { + virtual ~Pattern(); + virtual bool matches( TestCaseInfo const& testCase ) const = 0; + }; + class NamePattern : public Pattern { + public: + NamePattern( std::string const& name ) + : m_wildcardPattern( toLower( name ), CaseSensitive::No ) + {} + virtual ~NamePattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { + return m_wildcardPattern.matches( toLower( testCase.name ) ); + } + private: + WildcardPattern m_wildcardPattern; + }; + + class TagPattern : public Pattern { + public: + TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} + virtual ~TagPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { + return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); + } + private: + std::string m_tag; + }; + + class ExcludedPattern : public Pattern { + public: + ExcludedPattern( Ptr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} + virtual ~ExcludedPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } + private: + Ptr m_underlyingPattern; + }; + + struct Filter { + std::vector > m_patterns; + + bool matches( TestCaseInfo const& testCase ) const { + // All patterns in a filter must match for the filter to be a match + for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) { + if( !(*it)->matches( testCase ) ) + return false; + } + return true; + } + }; + + public: + bool hasFilters() const { + return !m_filters.empty(); + } + bool matches( TestCaseInfo const& testCase ) const { + // A TestSpec matches if any filter matches + for( std::vector::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) + if( it->matches( testCase ) ) + return true; + return false; + } + + private: + std::vector m_filters; + + friend class TestSpecParser; + }; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif // TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_spec_parser.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_spec_parser.hpp new file mode 100644 index 0000000..05bdcf4 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_test_spec_parser.hpp @@ -0,0 +1,132 @@ +/* + * Created by Phil on 15/5/2013. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +#include "catch_test_spec.hpp" +#include "catch_interfaces_tag_alias_registry.h" + +namespace Catch { + + class TestSpecParser { + enum Mode{ None, Name, QuotedName, Tag, EscapedName }; + Mode m_mode; + bool m_exclusion; + std::size_t m_start, m_pos; + std::string m_arg; + std::vector m_escapeChars; + TestSpec::Filter m_currentFilter; + TestSpec m_testSpec; + ITagAliasRegistry const* m_tagAliases; + + public: + TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} + + TestSpecParser& parse( std::string const& arg ) { + m_mode = None; + m_exclusion = false; + m_start = std::string::npos; + m_arg = m_tagAliases->expandAliases( arg ); + m_escapeChars.clear(); + for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) + visitChar( m_arg[m_pos] ); + if( m_mode == Name ) + addPattern(); + return *this; + } + TestSpec testSpec() { + addFilter(); + return m_testSpec; + } + private: + void visitChar( char c ) { + if( m_mode == None ) { + switch( c ) { + case ' ': return; + case '~': m_exclusion = true; return; + case '[': return startNewMode( Tag, ++m_pos ); + case '"': return startNewMode( QuotedName, ++m_pos ); + case '\\': return escape(); + default: startNewMode( Name, m_pos ); break; + } + } + if( m_mode == Name ) { + if( c == ',' ) { + addPattern(); + addFilter(); + } + else if( c == '[' ) { + if( subString() == "exclude:" ) + m_exclusion = true; + else + addPattern(); + startNewMode( Tag, ++m_pos ); + } + else if( c == '\\' ) + escape(); + } + else if( m_mode == EscapedName ) + m_mode = Name; + else if( m_mode == QuotedName && c == '"' ) + addPattern(); + else if( m_mode == Tag && c == ']' ) + addPattern(); + } + void startNewMode( Mode mode, std::size_t start ) { + m_mode = mode; + m_start = start; + } + void escape() { + if( m_mode == None ) + m_start = m_pos; + m_mode = EscapedName; + m_escapeChars.push_back( m_pos ); + } + std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } + template + void addPattern() { + std::string token = subString(); + for( size_t i = 0; i < m_escapeChars.size(); ++i ) + token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 ); + m_escapeChars.clear(); + if( startsWith( token, "exclude:" ) ) { + m_exclusion = true; + token = token.substr( 8 ); + } + if( !token.empty() ) { + Ptr pattern = new T( token ); + if( m_exclusion ) + pattern = new TestSpec::ExcludedPattern( pattern ); + m_currentFilter.m_patterns.push_back( pattern ); + } + m_exclusion = false; + m_mode = None; + } + void addFilter() { + if( !m_currentFilter.m_patterns.empty() ) { + m_testSpec.m_filters.push_back( m_currentFilter ); + m_currentFilter = TestSpec::Filter(); + } + } + }; + inline TestSpec parseTestSpec( std::string const& arg ) { + return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); + } + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif // TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_text.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_text.h new file mode 100644 index 0000000..b66751f --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_text.h @@ -0,0 +1,24 @@ +/* + * Created by Phil on 10/2/2014. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TEXT_H_INCLUDED +#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED + +#include "catch_config.hpp" + +#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH + +#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch +#include "../external/tbc_text_format.h" +#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE + +namespace Catch { + using Tbc::Text; + using Tbc::TextAttributes; +} + +#endif // TWOBLUECUBES_CATCH_TEXT_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_timer.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_timer.h new file mode 100644 index 0000000..22e9e63 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_timer.h @@ -0,0 +1,35 @@ +/* + * Created by Phil on 05/08/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TIMER_H_INCLUDED +#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED + +#include "catch_platform.h" + +#ifdef CATCH_PLATFORM_WINDOWS +typedef unsigned long long uint64_t; +#else +#include +#endif + +namespace Catch { + + class Timer { + public: + Timer() : m_ticks( 0 ) {} + void start(); + unsigned int getElapsedMicroseconds() const; + unsigned int getElapsedMilliseconds() const; + double getElapsedSeconds() const; + + private: + uint64_t m_ticks; + }; + +} // namespace Catch + +#endif // TWOBLUECUBES_CATCH_TIMER_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_timer.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_timer.hpp new file mode 100644 index 0000000..dfb7811 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_timer.hpp @@ -0,0 +1,67 @@ +/* + * Created by Phil on 05/08/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch_timer.h" +#include "catch_platform.h" + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++11-long-long" +#endif + +#ifdef CATCH_PLATFORM_WINDOWS + +# include "catch_windows_h_proxy.h" + +#else + +#include + +#endif + +namespace Catch { + + namespace { +#ifdef CATCH_PLATFORM_WINDOWS + uint64_t getCurrentTicks() { + static uint64_t hz=0, hzo=0; + if (!hz) { + QueryPerformanceFrequency( reinterpret_cast( &hz ) ); + QueryPerformanceCounter( reinterpret_cast( &hzo ) ); + } + uint64_t t; + QueryPerformanceCounter( reinterpret_cast( &t ) ); + return ((t-hzo)*1000000)/hz; + } +#else + uint64_t getCurrentTicks() { + timeval t; + gettimeofday(&t,CATCH_NULL); + return static_cast( t.tv_sec ) * 1000000ull + static_cast( t.tv_usec ); + } +#endif + } + + void Timer::start() { + m_ticks = getCurrentTicks(); + } + unsigned int Timer::getElapsedMicroseconds() const { + return static_cast(getCurrentTicks() - m_ticks); + } + unsigned int Timer::getElapsedMilliseconds() const { + return static_cast(getElapsedMicroseconds()/1000); + } + double Timer::getElapsedSeconds() const { + return getElapsedMicroseconds()/1000000.0; + } + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tostring.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tostring.h new file mode 100644 index 0000000..e6f7ec9 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tostring.h @@ -0,0 +1,269 @@ +/* + * Created by Phil on 8/5/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED +#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED + +#include "catch_common.h" + +#include +#include +#include +#include +#include + +#ifdef __OBJC__ +#include "catch_objc_arc.hpp" +#endif + +#ifdef CATCH_CONFIG_CPP11_TUPLE +#include +#endif + +#ifdef CATCH_CONFIG_CPP11_IS_ENUM +#include +#endif + +namespace Catch { + +// Why we're here. +template +std::string toString( T const& value ); + +// Built in overloads + +std::string toString( std::string const& value ); +std::string toString( std::wstring const& value ); +std::string toString( const char* const value ); +std::string toString( char* const value ); +std::string toString( const wchar_t* const value ); +std::string toString( wchar_t* const value ); +std::string toString( int value ); +std::string toString( unsigned long value ); +std::string toString( unsigned int value ); +std::string toString( const double value ); +std::string toString( const float value ); +std::string toString( bool value ); +std::string toString( char value ); +std::string toString( signed char value ); +std::string toString( unsigned char value ); + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG +std::string toString( long long value ); +std::string toString( unsigned long long value ); +#endif + +#ifdef CATCH_CONFIG_CPP11_NULLPTR +std::string toString( std::nullptr_t ); +#endif + +#ifdef __OBJC__ + std::string toString( NSString const * const& nsstring ); + std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ); + std::string toString( NSObject* const& nsObject ); +#endif + + +namespace Detail { + + extern const std::string unprintableString; + + struct BorgType { + template BorgType( T const& ); + }; + + struct TrueType { char sizer[1]; }; + struct FalseType { char sizer[2]; }; + + TrueType& testStreamable( std::ostream& ); + FalseType testStreamable( FalseType ); + + FalseType operator<<( std::ostream const&, BorgType const& ); + + template + struct IsStreamInsertable { + static std::ostream &s; + static T const&t; + enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; + }; + +#if defined(CATCH_CONFIG_CPP11_IS_ENUM) + template::value + > + struct EnumStringMaker + { + static std::string convert( T const& ) { return unprintableString; } + }; + + template + struct EnumStringMaker + { + static std::string convert( T const& v ) + { + return ::Catch::toString( + static_cast::type>(v) + ); + } + }; +#endif + template + struct StringMakerBase { +#if defined(CATCH_CONFIG_CPP11_IS_ENUM) + template + static std::string convert( T const& v ) + { + return EnumStringMaker::convert( v ); + } +#else + template + static std::string convert( T const& ) { return unprintableString; } +#endif + }; + + template<> + struct StringMakerBase { + template + static std::string convert( T const& _value ) { + std::ostringstream oss; + oss << _value; + return oss.str(); + } + }; + + std::string rawMemoryToString( const void *object, std::size_t size ); + + template + inline std::string rawMemoryToString( const T& object ) { + return rawMemoryToString( &object, sizeof(object) ); + } + +} // end namespace Detail + +template +struct StringMaker : + Detail::StringMakerBase::value> {}; + +template +struct StringMaker { + template + static std::string convert( U* p ) { + if( !p ) + return "NULL"; + else + return Detail::rawMemoryToString( p ); + } +}; + +template +struct StringMaker { + static std::string convert( R C::* p ) { + if( !p ) + return "NULL"; + else + return Detail::rawMemoryToString( p ); + } +}; + +namespace Detail { + template + std::string rangeToString( InputIterator first, InputIterator last ); +} + +//template +//struct StringMaker > { +// static std::string convert( std::vector const& v ) { +// return Detail::rangeToString( v.begin(), v.end() ); +// } +//}; + +template +std::string toString( std::vector const& v ) { + return Detail::rangeToString( v.begin(), v.end() ); +} + + +#ifdef CATCH_CONFIG_CPP11_TUPLE + +// toString for tuples +namespace TupleDetail { + template< + typename Tuple, + std::size_t N = 0, + bool = (N < std::tuple_size::value) + > + struct ElementPrinter { + static void print( const Tuple& tuple, std::ostream& os ) + { + os << ( N ? ", " : " " ) + << Catch::toString(std::get(tuple)); + ElementPrinter::print(tuple,os); + } + }; + + template< + typename Tuple, + std::size_t N + > + struct ElementPrinter { + static void print( const Tuple&, std::ostream& ) {} + }; + +} + +template +struct StringMaker> { + + static std::string convert( const std::tuple& tuple ) + { + std::ostringstream os; + os << '{'; + TupleDetail::ElementPrinter>::print( tuple, os ); + os << " }"; + return os.str(); + } +}; +#endif // CATCH_CONFIG_CPP11_TUPLE + +namespace Detail { + template + std::string makeString( T const& value ) { + return StringMaker::convert( value ); + } +} // end namespace Detail + +/// \brief converts any type to a string +/// +/// The default template forwards on to ostringstream - except when an +/// ostringstream overload does not exist - in which case it attempts to detect +/// that and writes {?}. +/// Overload (not specialise) this template for custom typs that you don't want +/// to provide an ostream overload for. +template +std::string toString( T const& value ) { + return StringMaker::convert( value ); +} + + + namespace Detail { + template + std::string rangeToString( InputIterator first, InputIterator last ) { + std::ostringstream oss; + oss << "{ "; + if( first != last ) { + oss << Catch::toString( *first ); + for( ++first ; first != last ; ++first ) + oss << ", " << Catch::toString( *first ); + } + oss << " }"; + return oss.str(); + } +} + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tostring.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tostring.hpp new file mode 100644 index 0000000..e61191b --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_tostring.hpp @@ -0,0 +1,213 @@ +/* + * Created by Phil on 23/4/2014. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED + +#include "catch_tostring.h" +#include "catch_interfaces_config.h" + +namespace Catch { + +namespace Detail { + + const std::string unprintableString = "{?}"; + + namespace { + const int hexThreshold = 255; + + struct Endianness { + enum Arch { Big, Little }; + + static Arch which() { + union _{ + int asInt; + char asChar[sizeof (int)]; + } u; + + u.asInt = 1; + return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; + } + }; + } + + std::string rawMemoryToString( const void *object, std::size_t size ) + { + // Reverse order for little endian architectures + int i = 0, end = static_cast( size ), inc = 1; + if( Endianness::which() == Endianness::Little ) { + i = end-1; + end = inc = -1; + } + + unsigned char const *bytes = static_cast(object); + std::ostringstream os; + os << "0x" << std::setfill('0') << std::hex; + for( ; i != end; i += inc ) + os << std::setw(2) << static_cast(bytes[i]); + return os.str(); + } +} + +std::string toString( std::string const& value ) { + std::string s = value; + if( getCurrentContext().getConfig()->showInvisibles() ) { + for(size_t i = 0; i < s.size(); ++i ) { + std::string subs; + switch( s[i] ) { + case '\n': subs = "\\n"; break; + case '\t': subs = "\\t"; break; + default: break; + } + if( !subs.empty() ) { + s = s.substr( 0, i ) + subs + s.substr( i+1 ); + ++i; + } + } + } + return '"' + s + '"'; +} +std::string toString( std::wstring const& value ) { + + std::string s; + s.reserve( value.size() ); + for(size_t i = 0; i < value.size(); ++i ) + s += value[i] <= 0xff ? static_cast( value[i] ) : '?'; + return Catch::toString( s ); +} + +std::string toString( const char* const value ) { + return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" ); +} + +std::string toString( char* const value ) { + return Catch::toString( static_cast( value ) ); +} + +std::string toString( const wchar_t* const value ) +{ + return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" ); +} + +std::string toString( wchar_t* const value ) +{ + return Catch::toString( static_cast( value ) ); +} + +std::string toString( int value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} + +std::string toString( unsigned long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} + +std::string toString( unsigned int value ) { + return Catch::toString( static_cast( value ) ); +} + +template +std::string fpToString( T value, int precision ) { + std::ostringstream oss; + oss << std::setprecision( precision ) + << std::fixed + << value; + std::string d = oss.str(); + std::size_t i = d.find_last_not_of( '0' ); + if( i != std::string::npos && i != d.size()-1 ) { + if( d[i] == '.' ) + i++; + d = d.substr( 0, i+1 ); + } + return d; +} + +std::string toString( const double value ) { + return fpToString( value, 10 ); +} +std::string toString( const float value ) { + return fpToString( value, 5 ) + 'f'; +} + +std::string toString( bool value ) { + return value ? "true" : "false"; +} + +std::string toString( char value ) { + if ( value == '\r' ) + return "'\\r'"; + if ( value == '\f' ) + return "'\\f'"; + if ( value == '\n' ) + return "'\\n'"; + if ( value == '\t' ) + return "'\\t'"; + if ( '\0' <= value && value < ' ' ) + return toString( static_cast( value ) ); + char chstr[] = "' '"; + chstr[1] = value; + return chstr; +} + +std::string toString( signed char value ) { + return toString( static_cast( value ) ); +} + +std::string toString( unsigned char value ) { + return toString( static_cast( value ) ); +} + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG +std::string toString( long long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} +std::string toString( unsigned long long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} +#endif + +#ifdef CATCH_CONFIG_CPP11_NULLPTR +std::string toString( std::nullptr_t ) { + return "nullptr"; +} +#endif + +#ifdef __OBJC__ + std::string toString( NSString const * const& nsstring ) { + if( !nsstring ) + return "nil"; + return "@" + toString([nsstring UTF8String]); + } + std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) { + if( !nsstring ) + return "nil"; + return "@" + toString([nsstring UTF8String]); + } + std::string toString( NSObject* const& nsObject ) { + return toString( [nsObject description] ); + } +#endif + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_totals.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_totals.hpp new file mode 100644 index 0000000..551e294 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_totals.hpp @@ -0,0 +1,78 @@ +/* + * Created by Phil Nash on 23/02/2012. + * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED + +#include + +namespace Catch { + + struct Counts { + Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} + + Counts operator - ( Counts const& other ) const { + Counts diff; + diff.passed = passed - other.passed; + diff.failed = failed - other.failed; + diff.failedButOk = failedButOk - other.failedButOk; + return diff; + } + Counts& operator += ( Counts const& other ) { + passed += other.passed; + failed += other.failed; + failedButOk += other.failedButOk; + return *this; + } + + std::size_t total() const { + return passed + failed + failedButOk; + } + bool allPassed() const { + return failed == 0 && failedButOk == 0; + } + bool allOk() const { + return failed == 0; + } + + std::size_t passed; + std::size_t failed; + std::size_t failedButOk; + }; + + struct Totals { + + Totals operator - ( Totals const& other ) const { + Totals diff; + diff.assertions = assertions - other.assertions; + diff.testCases = testCases - other.testCases; + return diff; + } + + Totals delta( Totals const& prevTotals ) const { + Totals diff = *this - prevTotals; + if( diff.assertions.failed > 0 ) + ++diff.testCases.failed; + else if( diff.assertions.failedButOk > 0 ) + ++diff.testCases.failedButOk; + else + ++diff.testCases.passed; + return diff; + } + + Totals& operator += ( Totals const& other ) { + assertions += other.assertions; + testCases += other.testCases; + return *this; + } + + Counts assertions; + Counts testCases; + }; +} + +#endif // TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_type_traits.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_type_traits.hpp new file mode 100644 index 0000000..9be8916 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_type_traits.hpp @@ -0,0 +1,47 @@ +/* + * Created by Martin on 08/02/2017. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) +#include +#endif + + +namespace Catch { + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) + + template + using add_lvalue_reference = std::add_lvalue_reference; + + template + using add_const = std::add_const; + +#else + + template + struct add_const { + typedef const T type; + }; + + template + struct add_lvalue_reference { + typedef T& type; + }; + template + struct add_lvalue_reference { + typedef T& type; + }; + // No && overload, because that is C++11, in which case we have + // proper type_traits implementation from the standard library + +#endif + +} + +#endif // TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_version.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_version.h new file mode 100644 index 0000000..1a79c5c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_version.h @@ -0,0 +1,38 @@ +/* + * Created by Phil on 13/11/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_VERSION_H_INCLUDED +#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED + +namespace Catch { + + // Versioning information + struct Version { + Version( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + std::string const& _branchName, + unsigned int _buildNumber ); + + unsigned int const majorVersion; + unsigned int const minorVersion; + unsigned int const patchNumber; + + // buildNumber is only used if branchName is not null + std::string const branchName; + unsigned int const buildNumber; + + friend std::ostream& operator << ( std::ostream& os, Version const& version ); + + private: + void operator=( Version const& ); + }; + + extern Version libraryVersion; +} + +#endif // TWOBLUECUBES_CATCH_VERSION_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_version.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_version.hpp new file mode 100644 index 0000000..c364d7d --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_version.hpp @@ -0,0 +1,44 @@ +/* + * Created by Phil on 14/11/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED + +#include "catch_version.h" + +namespace Catch { + + Version::Version + ( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + std::string const& _branchName, + unsigned int _buildNumber ) + : majorVersion( _majorVersion ), + minorVersion( _minorVersion ), + patchNumber( _patchNumber ), + branchName( _branchName ), + buildNumber( _buildNumber ) + {} + + std::ostream& operator << ( std::ostream& os, Version const& version ) { + os << version.majorVersion << '.' + << version.minorVersion << '.' + << version.patchNumber; + + if( !version.branchName.empty() ) { + os << '-' << version.branchName + << '.' << version.buildNumber; + } + return os; + } + + Version libraryVersion( 1, 8, 1, "", 0 ); + +} + +#endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_wildcard_pattern.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_wildcard_pattern.hpp new file mode 100644 index 0000000..a922912 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_wildcard_pattern.hpp @@ -0,0 +1,74 @@ +/* + * Created by Phil on 13/7/2015. + * Copyright 2015 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED + +#include "catch_common.h" + +#include + + +namespace Catch +{ + class WildcardPattern { + enum WildcardPosition { + NoWildcard = 0, + WildcardAtStart = 1, + WildcardAtEnd = 2, + WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd + }; + + public: + + WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_wildcard( NoWildcard ), + m_pattern( adjustCase( pattern ) ) + { + if( startsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 1 ); + m_wildcard = WildcardAtStart; + } + if( endsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); + m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); + } + } + virtual ~WildcardPattern(); + virtual bool matches( std::string const& str ) const { + switch( m_wildcard ) { + case NoWildcard: + return m_pattern == adjustCase( str ); + case WildcardAtStart: + return endsWith( adjustCase( str ), m_pattern ); + case WildcardAtEnd: + return startsWith( adjustCase( str ), m_pattern ); + case WildcardAtBothEnds: + return contains( adjustCase( str ), m_pattern ); + } + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" +#endif + throw std::logic_error( "Unknown enum" ); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + } + private: + std::string adjustCase( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; + } + CaseSensitive::Choice m_caseSensitivity; + WildcardPosition m_wildcard; + std::string m_pattern; + }; +} + +#endif // TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_windows_h_proxy.h b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_windows_h_proxy.h new file mode 100644 index 0000000..4f059b4 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_windows_h_proxy.h @@ -0,0 +1,32 @@ +/* + * Created by Martin on 16/01/2017. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifndef TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED +#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED + +#ifdef CATCH_DEFINES_NOMINMAX +# define NOMINMAX +#endif +#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#ifdef __AFXDLL +#include +#else +#include +#endif + +#ifdef CATCH_DEFINES_NOMINMAX +# undef NOMINMAX +#endif +#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN +# undef WIN32_LEAN_AND_MEAN +#endif + + +#endif // TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_xmlwriter.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_xmlwriter.hpp new file mode 100644 index 0000000..ae59627 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/internal/catch_xmlwriter.hpp @@ -0,0 +1,246 @@ +/* + * Created by Phil on 09/12/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED + +#include "catch_stream.h" +#include "catch_compiler_capabilities.h" +#include "catch_suppress_warnings.h" + +#include +#include +#include +#include + +namespace Catch { + + class XmlEncode { + public: + enum ForWhat { ForTextNodes, ForAttributes }; + + XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ) + : m_str( str ), + m_forWhat( forWhat ) + {} + + void encodeTo( std::ostream& os ) const { + + // Apostrophe escaping not necessary if we always use " to write attributes + // (see: http://www.w3.org/TR/xml/#syntax) + + for( std::size_t i = 0; i < m_str.size(); ++ i ) { + char c = m_str[i]; + switch( c ) { + case '<': os << "<"; break; + case '&': os << "&"; break; + + case '>': + // See: http://www.w3.org/TR/xml/#syntax + if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' ) + os << ">"; + else + os << c; + break; + + case '\"': + if( m_forWhat == ForAttributes ) + os << """; + else + os << c; + break; + + default: + // Escape control chars - based on contribution by @espenalb in PR #465 and + // by @mrpi PR #588 + if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) { + // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) + << static_cast( c ); + } + else + os << c; + } + } + } + + friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { + xmlEncode.encodeTo( os ); + return os; + } + + private: + std::string m_str; + ForWhat m_forWhat; + }; + + class XmlWriter { + public: + + class ScopedElement { + public: + ScopedElement( XmlWriter* writer ) + : m_writer( writer ) + {} + + ScopedElement( ScopedElement const& other ) + : m_writer( other.m_writer ){ + other.m_writer = CATCH_NULL; + } + + ~ScopedElement() { + if( m_writer ) + m_writer->endElement(); + } + + ScopedElement& writeText( std::string const& text, bool indent = true ) { + m_writer->writeText( text, indent ); + return *this; + } + + template + ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { + m_writer->writeAttribute( name, attribute ); + return *this; + } + + private: + mutable XmlWriter* m_writer; + }; + + XmlWriter() + : m_tagIsOpen( false ), + m_needsNewline( false ), + m_os( Catch::cout() ) + { + writeDeclaration(); + } + + XmlWriter( std::ostream& os ) + : m_tagIsOpen( false ), + m_needsNewline( false ), + m_os( os ) + { + writeDeclaration(); + } + + ~XmlWriter() { + while( !m_tags.empty() ) + endElement(); + } + + XmlWriter& startElement( std::string const& name ) { + ensureTagClosed(); + newlineIfNecessary(); + m_os << m_indent << '<' << name; + m_tags.push_back( name ); + m_indent += " "; + m_tagIsOpen = true; + return *this; + } + + ScopedElement scopedElement( std::string const& name ) { + ScopedElement scoped( this ); + startElement( name ); + return scoped; + } + + XmlWriter& endElement() { + newlineIfNecessary(); + m_indent = m_indent.substr( 0, m_indent.size()-2 ); + if( m_tagIsOpen ) { + m_os << "/>"; + m_tagIsOpen = false; + } + else { + m_os << m_indent << ""; + } + m_os << std::endl; + m_tags.pop_back(); + return *this; + } + + XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) { + if( !name.empty() && !attribute.empty() ) + m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; + return *this; + } + + XmlWriter& writeAttribute( std::string const& name, bool attribute ) { + m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; + return *this; + } + + template + XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { + std::ostringstream oss; + oss << attribute; + return writeAttribute( name, oss.str() ); + } + + XmlWriter& writeText( std::string const& text, bool indent = true ) { + if( !text.empty() ){ + bool tagWasOpen = m_tagIsOpen; + ensureTagClosed(); + if( tagWasOpen && indent ) + m_os << m_indent; + m_os << XmlEncode( text ); + m_needsNewline = true; + } + return *this; + } + + XmlWriter& writeComment( std::string const& text ) { + ensureTagClosed(); + m_os << m_indent << ""; + m_needsNewline = true; + return *this; + } + + void writeStylesheetRef( std::string const& url ) { + m_os << "\n"; + } + + XmlWriter& writeBlankLine() { + ensureTagClosed(); + m_os << '\n'; + return *this; + } + + void ensureTagClosed() { + if( m_tagIsOpen ) { + m_os << ">" << std::endl; + m_tagIsOpen = false; + } + } + + private: + XmlWriter( XmlWriter const& ); + void operator=( XmlWriter const& ); + + void writeDeclaration() { + m_os << "\n"; + } + + void newlineIfNecessary() { + if( m_needsNewline ) { + m_os << std::endl; + m_needsNewline = false; + } + } + + bool m_tagIsOpen; + bool m_needsNewline; + std::vector m_tags; + std::string m_indent; + std::ostream& m_os; + }; + +} +#include "catch_reenable_warnings.h" + +#endif // TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_automake.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_automake.hpp new file mode 100644 index 0000000..c267d8a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_automake.hpp @@ -0,0 +1,62 @@ +/* + * Created by Justin R. Wilson on 2/19/2017. + * Copyright 2017 Justin R. Wilson. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED + +// Don't #include any Catch headers here - we can assume they are already +// included before this header. +// This is not good practice in general but is necessary in this case so this +// file can be distributed as a single header that works with the main +// Catch single header. + +namespace Catch { + + struct AutomakeReporter : StreamingReporterBase { + AutomakeReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ) + {} + + virtual ~AutomakeReporter(); + + static std::string getDescription() { + return "Reports test results in the format of Automake .trs files"; + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} + + virtual bool assertionEnded( AssertionStats const& /*_assertionStats*/ ) CATCH_OVERRIDE { return true; } + + virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE { + // Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR. + stream << ":test-result: "; + if (_testCaseStats.totals.assertions.allPassed()) { + stream << "PASS"; + } else if (_testCaseStats.totals.assertions.allOk()) { + stream << "XFAIL"; + } else { + stream << "FAIL"; + } + stream << ' ' << _testCaseStats.testInfo.name << '\n'; + StreamingReporterBase::testCaseEnded( _testCaseStats ); + } + + virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + stream << ":test-result: SKIP " << testInfo.name << '\n'; + } + + }; + +#ifdef CATCH_IMPL + AutomakeReporter::~AutomakeReporter() {} +#endif + + INTERNAL_CATCH_REGISTER_REPORTER( "automake", AutomakeReporter) + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_bases.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_bases.hpp new file mode 100644 index 0000000..8fc8554 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_bases.hpp @@ -0,0 +1,283 @@ +/* + * Created by Phil on 27/11/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED + +#include "../internal/catch_interfaces_reporter.h" + +#include +#include +#include +#include + +namespace Catch { + + namespace { + // Because formatting using c++ streams is stateful, drop down to C is required + // Alternatively we could use stringstream, but its performance is... not good. + std::string getFormattedDuration( double duration ) { + // Max exponent + 1 is required to represent the whole part + // + 1 for decimal point + // + 3 for the 3 decimal places + // + 1 for null terminator + const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; + char buffer[maxDoubleSize]; +#ifdef _MSC_VER + sprintf_s(buffer, "%.3f", duration); +#else + sprintf(buffer, "%.3f", duration); +#endif + return std::string(buffer); + } + } + + + struct StreamingReporterBase : SharedImpl { + + StreamingReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + } + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporterPrefs; + } + + virtual ~StreamingReporterBase() CATCH_OVERRIDE; + + virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {} + + virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE { + currentTestRunInfo = _testRunInfo; + } + virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE { + currentGroupInfo = _groupInfo; + } + + virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE { + currentTestCaseInfo = _testInfo; + } + virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { + m_sectionStack.push_back( _sectionInfo ); + } + + virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE { + m_sectionStack.pop_back(); + } + virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE { + currentTestCaseInfo.reset(); + } + virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE { + currentGroupInfo.reset(); + } + virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE { + currentTestCaseInfo.reset(); + currentGroupInfo.reset(); + currentTestRunInfo.reset(); + } + + virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE { + // Don't do anything with this by default. + // It can optionally be overridden in the derived class. + } + + Ptr m_config; + std::ostream& stream; + + LazyStat currentTestRunInfo; + LazyStat currentGroupInfo; + LazyStat currentTestCaseInfo; + + std::vector m_sectionStack; + ReporterPreferences m_reporterPrefs; + }; + + struct CumulativeReporterBase : SharedImpl { + template + struct Node : SharedImpl<> { + explicit Node( T const& _value ) : value( _value ) {} + virtual ~Node() {} + + typedef std::vector > ChildNodes; + T value; + ChildNodes children; + }; + struct SectionNode : SharedImpl<> { + explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {} + virtual ~SectionNode(); + + bool operator == ( SectionNode const& other ) const { + return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; + } + bool operator == ( Ptr const& other ) const { + return operator==( *other ); + } + + SectionStats stats; + typedef std::vector > ChildSections; + typedef std::vector Assertions; + ChildSections childSections; + Assertions assertions; + std::string stdOut; + std::string stdErr; + }; + + struct BySectionInfo { + BySectionInfo( SectionInfo const& other ) : m_other( other ) {} + BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} + bool operator() ( Ptr const& node ) const { + return node->stats.sectionInfo.lineInfo == m_other.lineInfo; + } + private: + void operator=( BySectionInfo const& ); + SectionInfo const& m_other; + }; + + + typedef Node TestCaseNode; + typedef Node TestGroupNode; + typedef Node TestRunNode; + + CumulativeReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + } + ~CumulativeReporterBase(); + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporterPrefs; + } + + virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {} + virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {} + + virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {} + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); + Ptr node; + if( m_sectionStack.empty() ) { + if( !m_rootSection ) + m_rootSection = new SectionNode( incompleteStats ); + node = m_rootSection; + } + else { + SectionNode& parentNode = *m_sectionStack.back(); + SectionNode::ChildSections::const_iterator it = + std::find_if( parentNode.childSections.begin(), + parentNode.childSections.end(), + BySectionInfo( sectionInfo ) ); + if( it == parentNode.childSections.end() ) { + node = new SectionNode( incompleteStats ); + parentNode.childSections.push_back( node ); + } + else + node = *it; + } + m_sectionStack.push_back( node ); + m_deepestSection = node; + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + assert( !m_sectionStack.empty() ); + SectionNode& sectionNode = *m_sectionStack.back(); + sectionNode.assertions.push_back( assertionStats ); + // AssertionResult holds a pointer to a temporary DecomposedExpression, + // which getExpandedExpression() calls to build the expression string. + // Our section stack copy of the assertionResult will likely outlive the + // temporary, so it must be expanded or discarded now to avoid calling + // a destroyed object later. + prepareExpandedExpression( sectionNode.assertions.back().assertionResult ); + return true; + } + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + assert( !m_sectionStack.empty() ); + SectionNode& node = *m_sectionStack.back(); + node.stats = sectionStats; + m_sectionStack.pop_back(); + } + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + Ptr node = new TestCaseNode( testCaseStats ); + assert( m_sectionStack.size() == 0 ); + node->children.push_back( m_rootSection ); + m_testCases.push_back( node ); + m_rootSection.reset(); + + assert( m_deepestSection ); + m_deepestSection->stdOut = testCaseStats.stdOut; + m_deepestSection->stdErr = testCaseStats.stdErr; + } + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + Ptr node = new TestGroupNode( testGroupStats ); + node->children.swap( m_testCases ); + m_testGroups.push_back( node ); + } + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + Ptr node = new TestRunNode( testRunStats ); + node->children.swap( m_testGroups ); + m_testRuns.push_back( node ); + testRunEndedCumulative(); + } + virtual void testRunEndedCumulative() = 0; + + virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {} + + virtual void prepareExpandedExpression( AssertionResult& result ) const { + if( result.isOk() ) + result.discardDecomposedExpression(); + else + result.expandDecomposedExpression(); + } + + Ptr m_config; + std::ostream& stream; + std::vector m_assertions; + std::vector > > m_sections; + std::vector > m_testCases; + std::vector > m_testGroups; + + std::vector > m_testRuns; + + Ptr m_rootSection; + Ptr m_deepestSection; + std::vector > m_sectionStack; + ReporterPreferences m_reporterPrefs; + + }; + + template + char const* getLineOfChars() { + static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; + if( !*line ) { + std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); + line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; + } + return line; + } + + + struct TestEventListenerBase : StreamingReporterBase { + TestEventListenerBase( ReporterConfig const& _config ) + : StreamingReporterBase( _config ) + {} + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} + virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE { + return false; + } + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_compact.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_compact.hpp new file mode 100644 index 0000000..11e3b7c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_compact.hpp @@ -0,0 +1,306 @@ +/* + * Created by Martin Moene on 2013-12-05. + * Copyright 2012 Martin Moene. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED + +#include "catch_reporter_bases.hpp" + +#include "../internal/catch_reporter_registrars.hpp" +#include "../internal/catch_console_colour.hpp" + +namespace Catch { + + struct CompactReporter : StreamingReporterBase { + + CompactReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ) + {} + + virtual ~CompactReporter(); + + static std::string getDescription() { + return "Reports test results on a single line, suitable for IDEs"; + } + + virtual ReporterPreferences getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = false; + return prefs; + } + + virtual void noMatchingTestCases( std::string const& spec ) { + stream << "No test cases matched '" << spec << '\'' << std::endl; + } + + virtual void assertionStarting( AssertionInfo const& ) {} + + virtual bool assertionEnded( AssertionStats const& _assertionStats ) { + AssertionResult const& result = _assertionStats.assertionResult; + + bool printInfoMessages = true; + + // Drop out if result was successful and we're not printing those + if( !m_config->includeSuccessfulResults() && result.isOk() ) { + if( result.getResultType() != ResultWas::Warning ) + return false; + printInfoMessages = false; + } + + AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); + printer.print(); + + stream << std::endl; + return true; + } + + virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE { + if (m_config->showDurations() == ShowDurations::Always) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + } + + virtual void testRunEnded( TestRunStats const& _testRunStats ) { + printTotals( _testRunStats.totals ); + stream << '\n' << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + private: + class AssertionPrinter { + void operator= ( AssertionPrinter const& ); + public: + AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) + : stream( _stream ) + , stats( _stats ) + , result( _stats.assertionResult ) + , messages( _stats.infoMessages ) + , itMessage( _stats.infoMessages.begin() ) + , printInfoMessages( _printInfoMessages ) + {} + + void print() { + printSourceInfo(); + + itMessage = messages.begin(); + + switch( result.getResultType() ) { + case ResultWas::Ok: + printResultType( Colour::ResultSuccess, passedString() ); + printOriginalExpression(); + printReconstructedExpression(); + if ( ! result.hasExpression() ) + printRemainingMessages( Colour::None ); + else + printRemainingMessages(); + break; + case ResultWas::ExpressionFailed: + if( result.isOk() ) + printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) ); + else + printResultType( Colour::Error, failedString() ); + printOriginalExpression(); + printReconstructedExpression(); + printRemainingMessages(); + break; + case ResultWas::ThrewException: + printResultType( Colour::Error, failedString() ); + printIssue( "unexpected exception with message:" ); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::FatalErrorCondition: + printResultType( Colour::Error, failedString() ); + printIssue( "fatal error condition with message:" ); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::DidntThrowException: + printResultType( Colour::Error, failedString() ); + printIssue( "expected exception, got none" ); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::Info: + printResultType( Colour::None, "info" ); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::Warning: + printResultType( Colour::None, "warning" ); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::ExplicitFailure: + printResultType( Colour::Error, failedString() ); + printIssue( "explicitly" ); + printRemainingMessages( Colour::None ); + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + printResultType( Colour::Error, "** internal error **" ); + break; + } + } + + private: + // Colour::LightGrey + + static Colour::Code dimColour() { return Colour::FileName; } + +#ifdef CATCH_PLATFORM_MAC + static const char* failedString() { return "FAILED"; } + static const char* passedString() { return "PASSED"; } +#else + static const char* failedString() { return "failed"; } + static const char* passedString() { return "passed"; } +#endif + + void printSourceInfo() const { + Colour colourGuard( Colour::FileName ); + stream << result.getSourceInfo() << ':'; + } + + void printResultType( Colour::Code colour, std::string passOrFail ) const { + if( !passOrFail.empty() ) { + { + Colour colourGuard( colour ); + stream << ' ' << passOrFail; + } + stream << ':'; + } + } + + void printIssue( std::string issue ) const { + stream << ' ' << issue; + } + + void printExpressionWas() { + if( result.hasExpression() ) { + stream << ';'; + { + Colour colour( dimColour() ); + stream << " expression was:"; + } + printOriginalExpression(); + } + } + + void printOriginalExpression() const { + if( result.hasExpression() ) { + stream << ' ' << result.getExpression(); + } + } + + void printReconstructedExpression() const { + if( result.hasExpandedExpression() ) { + { + Colour colour( dimColour() ); + stream << " for: "; + } + stream << result.getExpandedExpression(); + } + } + + void printMessage() { + if ( itMessage != messages.end() ) { + stream << " '" << itMessage->message << '\''; + ++itMessage; + } + } + + void printRemainingMessages( Colour::Code colour = dimColour() ) { + if ( itMessage == messages.end() ) + return; + + // using messages.end() directly yields compilation error: + std::vector::const_iterator itEnd = messages.end(); + const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); + + { + Colour colourGuard( colour ); + stream << " with " << pluralise( N, "message" ) << ':'; + } + + for(; itMessage != itEnd; ) { + // If this assertion is a warning ignore any INFO messages + if( printInfoMessages || itMessage->type != ResultWas::Info ) { + stream << " '" << itMessage->message << '\''; + if ( ++itMessage != itEnd ) { + Colour colourGuard( dimColour() ); + stream << " and"; + } + } + } + } + + private: + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + std::vector messages; + std::vector::const_iterator itMessage; + bool printInfoMessages; + }; + + // Colour, message variants: + // - white: No tests ran. + // - red: Failed [both/all] N test cases, failed [both/all] M assertions. + // - white: Passed [both/all] N test cases (no assertions). + // - red: Failed N tests cases, failed M assertions. + // - green: Passed [both/all] N tests cases with M assertions. + + std::string bothOrAll( std::size_t count ) const { + return count == 1 ? std::string() : count == 2 ? "both " : "all " ; + } + + void printTotals( const Totals& totals ) const { + if( totals.testCases.total() == 0 ) { + stream << "No tests ran."; + } + else if( totals.testCases.failed == totals.testCases.total() ) { + Colour colour( Colour::ResultError ); + const std::string qualify_assertions_failed = + totals.assertions.failed == totals.assertions.total() ? + bothOrAll( totals.assertions.failed ) : std::string(); + stream << + "Failed " << bothOrAll( totals.testCases.failed ) + << pluralise( totals.testCases.failed, "test case" ) << ", " + "failed " << qualify_assertions_failed << + pluralise( totals.assertions.failed, "assertion" ) << '.'; + } + else if( totals.assertions.total() == 0 ) { + stream << + "Passed " << bothOrAll( totals.testCases.total() ) + << pluralise( totals.testCases.total(), "test case" ) + << " (no assertions)."; + } + else if( totals.assertions.failed ) { + Colour colour( Colour::ResultError ); + stream << + "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", " + "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.'; + } + else { + Colour colour( Colour::ResultSuccess ); + stream << + "Passed " << bothOrAll( totals.testCases.passed ) + << pluralise( totals.testCases.passed, "test case" ) << + " with " << pluralise( totals.assertions.passed, "assertion" ) << '.'; + } + } + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter ) + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_console.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_console.hpp new file mode 100644 index 0000000..711d7fb --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_console.hpp @@ -0,0 +1,443 @@ +/* + * Created by Phil on 5/12/2012. + * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED + +#include "catch_reporter_bases.hpp" + +#include "../internal/catch_reporter_registrars.hpp" +#include "../internal/catch_console_colour.hpp" + +#include +#include + +namespace Catch { + + + struct ConsoleReporter : StreamingReporterBase { + ConsoleReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_headerPrinted( false ) + {} + + virtual ~ConsoleReporter() CATCH_OVERRIDE; + static std::string getDescription() { + return "Reports test results as plain lines of text"; + } + + virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { + stream << "No test cases matched '" << spec << '\'' << std::endl; + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { + } + + virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE { + AssertionResult const& result = _assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + // Drop out if result was successful but we're not printing them. + if( !includeResults && result.getResultType() != ResultWas::Warning ) + return false; + + lazyPrint(); + + AssertionPrinter printer( stream, _assertionStats, includeResults ); + printer.print(); + stream << std::endl; + return true; + } + + virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { + m_headerPrinted = false; + StreamingReporterBase::sectionStarting( _sectionInfo ); + } + virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE { + if( _sectionStats.missingAssertions ) { + lazyPrint(); + Colour colour( Colour::ResultError ); + if( m_sectionStack.size() > 1 ) + stream << "\nNo assertions in section"; + else + stream << "\nNo assertions in test case"; + stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; + } + if( m_config->showDurations() == ShowDurations::Always ) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + if( m_headerPrinted ) { + m_headerPrinted = false; + } + StreamingReporterBase::sectionEnded( _sectionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseEnded( _testCaseStats ); + m_headerPrinted = false; + } + virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE { + if( currentGroupInfo.used ) { + printSummaryDivider(); + stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; + printTotals( _testGroupStats.totals ); + stream << '\n' << std::endl; + } + StreamingReporterBase::testGroupEnded( _testGroupStats ); + } + virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE { + printTotalsDivider( _testRunStats.totals ); + printTotals( _testRunStats.totals ); + stream << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + private: + + class AssertionPrinter { + void operator= ( AssertionPrinter const& ); + public: + AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) + : stream( _stream ), + stats( _stats ), + result( _stats.assertionResult ), + colour( Colour::None ), + message( result.getMessage() ), + messages( _stats.infoMessages ), + printInfoMessages( _printInfoMessages ) + { + switch( result.getResultType() ) { + case ResultWas::Ok: + colour = Colour::Success; + passOrFail = "PASSED"; + //if( result.hasMessage() ) + if( _stats.infoMessages.size() == 1 ) + messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; + break; + case ResultWas::ExpressionFailed: + if( result.isOk() ) { + colour = Colour::Success; + passOrFail = "FAILED - but was ok"; + } + else { + colour = Colour::Error; + passOrFail = "FAILED"; + } + if( _stats.infoMessages.size() == 1 ) + messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; + break; + case ResultWas::ThrewException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to unexpected exception with message"; + break; + case ResultWas::FatalErrorCondition: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to a fatal error condition"; + break; + case ResultWas::DidntThrowException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "because no exception was thrown where one was expected"; + break; + case ResultWas::Info: + messageLabel = "info"; + break; + case ResultWas::Warning: + messageLabel = "warning"; + break; + case ResultWas::ExplicitFailure: + passOrFail = "FAILED"; + colour = Colour::Error; + if( _stats.infoMessages.size() == 1 ) + messageLabel = "explicitly with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "explicitly with messages"; + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + passOrFail = "** internal error **"; + colour = Colour::Error; + break; + } + } + + void print() const { + printSourceInfo(); + if( stats.totals.assertions.total() > 0 ) { + if( result.isOk() ) + stream << '\n'; + printResultType(); + printOriginalExpression(); + printReconstructedExpression(); + } + else { + stream << '\n'; + } + printMessage(); + } + + private: + void printResultType() const { + if( !passOrFail.empty() ) { + Colour colourGuard( colour ); + stream << passOrFail << ":\n"; + } + } + void printOriginalExpression() const { + if( result.hasExpression() ) { + Colour colourGuard( Colour::OriginalExpression ); + stream << " "; + stream << result.getExpressionInMacro(); + stream << '\n'; + } + } + void printReconstructedExpression() const { + if( result.hasExpandedExpression() ) { + stream << "with expansion:\n"; + Colour colourGuard( Colour::ReconstructedExpression ); + stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n'; + } + } + void printMessage() const { + if( !messageLabel.empty() ) + stream << messageLabel << ':' << '\n'; + for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); + it != itEnd; + ++it ) { + // If this assertion is a warning ignore any INFO messages + if( printInfoMessages || it->type != ResultWas::Info ) + stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n'; + } + } + void printSourceInfo() const { + Colour colourGuard( Colour::FileName ); + stream << result.getSourceInfo() << ": "; + } + + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + Colour::Code colour; + std::string passOrFail; + std::string messageLabel; + std::string message; + std::vector messages; + bool printInfoMessages; + }; + + void lazyPrint() { + + if( !currentTestRunInfo.used ) + lazyPrintRunInfo(); + if( !currentGroupInfo.used ) + lazyPrintGroupInfo(); + + if( !m_headerPrinted ) { + printTestCaseAndSectionHeader(); + m_headerPrinted = true; + } + } + void lazyPrintRunInfo() { + stream << '\n' << getLineOfChars<'~'>() << '\n'; + Colour colour( Colour::SecondaryText ); + stream << currentTestRunInfo->name + << " is a Catch v" << libraryVersion << " host application.\n" + << "Run with -? for options\n\n"; + + if( m_config->rngSeed() != 0 ) + stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; + + currentTestRunInfo.used = true; + } + void lazyPrintGroupInfo() { + if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) { + printClosedHeader( "Group: " + currentGroupInfo->name ); + currentGroupInfo.used = true; + } + } + void printTestCaseAndSectionHeader() { + assert( !m_sectionStack.empty() ); + printOpenHeader( currentTestCaseInfo->name ); + + if( m_sectionStack.size() > 1 ) { + Colour colourGuard( Colour::Headers ); + + std::vector::const_iterator + it = m_sectionStack.begin()+1, // Skip first section (test case) + itEnd = m_sectionStack.end(); + for( ; it != itEnd; ++it ) + printHeaderString( it->name, 2 ); + } + + SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; + + if( !lineInfo.empty() ){ + stream << getLineOfChars<'-'>() << '\n'; + Colour colourGuard( Colour::FileName ); + stream << lineInfo << '\n'; + } + stream << getLineOfChars<'.'>() << '\n' << std::endl; + } + + void printClosedHeader( std::string const& _name ) { + printOpenHeader( _name ); + stream << getLineOfChars<'.'>() << '\n'; + } + void printOpenHeader( std::string const& _name ) { + stream << getLineOfChars<'-'>() << '\n'; + { + Colour colourGuard( Colour::Headers ); + printHeaderString( _name ); + } + } + + // if string has a : in first line will set indent to follow it on + // subsequent lines + void printHeaderString( std::string const& _string, std::size_t indent = 0 ) { + std::size_t i = _string.find( ": " ); + if( i != std::string::npos ) + i+=2; + else + i = 0; + stream << Text( _string, TextAttributes() + .setIndent( indent+i) + .setInitialIndent( indent ) ) << '\n'; + } + + struct SummaryColumn { + + SummaryColumn( std::string const& _label, Colour::Code _colour ) + : label( _label ), + colour( _colour ) + {} + SummaryColumn addRow( std::size_t count ) { + std::ostringstream oss; + oss << count; + std::string row = oss.str(); + for( std::vector::iterator it = rows.begin(); it != rows.end(); ++it ) { + while( it->size() < row.size() ) + *it = ' ' + *it; + while( it->size() > row.size() ) + row = ' ' + row; + } + rows.push_back( row ); + return *this; + } + + std::string label; + Colour::Code colour; + std::vector rows; + + }; + + void printTotals( Totals const& totals ) { + if( totals.testCases.total() == 0 ) { + stream << Colour( Colour::Warning ) << "No tests ran\n"; + } + else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) { + stream << Colour( Colour::ResultSuccess ) << "All tests passed"; + stream << " (" + << pluralise( totals.assertions.passed, "assertion" ) << " in " + << pluralise( totals.testCases.passed, "test case" ) << ')' + << '\n'; + } + else { + + std::vector columns; + columns.push_back( SummaryColumn( "", Colour::None ) + .addRow( totals.testCases.total() ) + .addRow( totals.assertions.total() ) ); + columns.push_back( SummaryColumn( "passed", Colour::Success ) + .addRow( totals.testCases.passed ) + .addRow( totals.assertions.passed ) ); + columns.push_back( SummaryColumn( "failed", Colour::ResultError ) + .addRow( totals.testCases.failed ) + .addRow( totals.assertions.failed ) ); + columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure ) + .addRow( totals.testCases.failedButOk ) + .addRow( totals.assertions.failedButOk ) ); + + printSummaryRow( "test cases", columns, 0 ); + printSummaryRow( "assertions", columns, 1 ); + } + } + void printSummaryRow( std::string const& label, std::vector const& cols, std::size_t row ) { + for( std::vector::const_iterator it = cols.begin(); it != cols.end(); ++it ) { + std::string value = it->rows[row]; + if( it->label.empty() ) { + stream << label << ": "; + if( value != "0" ) + stream << value; + else + stream << Colour( Colour::Warning ) << "- none -"; + } + else if( value != "0" ) { + stream << Colour( Colour::LightGrey ) << " | "; + stream << Colour( it->colour ) + << value << ' ' << it->label; + } + } + stream << '\n'; + } + + static std::size_t makeRatio( std::size_t number, std::size_t total ) { + std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0; + return ( ratio == 0 && number > 0 ) ? 1 : ratio; + } + static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) { + if( i > j && i > k ) + return i; + else if( j > k ) + return j; + else + return k; + } + + void printTotalsDivider( Totals const& totals ) { + if( totals.testCases.total() > 0 ) { + std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() ); + std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() ); + std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() ); + while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 ) + findMax( failedRatio, failedButOkRatio, passedRatio )++; + while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 ) + findMax( failedRatio, failedButOkRatio, passedRatio )--; + + stream << Colour( Colour::Error ) << std::string( failedRatio, '=' ); + stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' ); + if( totals.testCases.allPassed() ) + stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' ); + else + stream << Colour( Colour::Success ) << std::string( passedRatio, '=' ); + } + else { + stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' ); + } + stream << '\n'; + } + void printSummaryDivider() { + stream << getLineOfChars<'-'>() << '\n'; + } + + private: + bool m_headerPrinted; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter ) + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_junit.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_junit.hpp new file mode 100644 index 0000000..7ae9984 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_junit.hpp @@ -0,0 +1,252 @@ +/* + * Created by Phil on 26/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED + +#include "catch_reporter_bases.hpp" + +#include "../internal/catch_tostring.h" +#include "../internal/catch_reporter_registrars.hpp" +#include "../internal/catch_xmlwriter.hpp" + +#include + +namespace Catch { + + namespace { + std::string getCurrentTimestamp() { + // Beware, this is not reentrant because of backward compatibility issues + // Also, UTC only, again because of backward compatibility (%z is C++11) + time_t rawtime; + std::time(&rawtime); + const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z"); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &rawtime); +#else + std::tm* timeInfo; + timeInfo = std::gmtime(&rawtime); +#endif + + char timeStamp[timeStampSize]; + const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp); + } + + } + + class JunitReporter : public CumulativeReporterBase { + public: + JunitReporter( ReporterConfig const& _config ) + : CumulativeReporterBase( _config ), + xml( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + virtual ~JunitReporter() CATCH_OVERRIDE; + + static std::string getDescription() { + return "Reports test results in an XML format that looks like Ant's junitreport target"; + } + + virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {} + + virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE { + CumulativeReporterBase::testRunStarting( runInfo ); + xml.startElement( "testsuites" ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + suiteTimer.start(); + stdOutForSuite.str(""); + stdErrForSuite.str(""); + unexpectedExceptions = 0; + CumulativeReporterBase::testGroupStarting( groupInfo ); + } + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException ) + unexpectedExceptions++; + return CumulativeReporterBase::assertionEnded( assertionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + stdOutForSuite << testCaseStats.stdOut; + stdErrForSuite << testCaseStats.stdErr; + CumulativeReporterBase::testCaseEnded( testCaseStats ); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + double suiteTime = suiteTimer.getElapsedSeconds(); + CumulativeReporterBase::testGroupEnded( testGroupStats ); + writeGroup( *m_testGroups.back(), suiteTime ); + } + + virtual void testRunEndedCumulative() CATCH_OVERRIDE { + xml.endElement(); + } + + void writeGroup( TestGroupNode const& groupNode, double suiteTime ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); + TestGroupStats const& stats = groupNode.value; + xml.writeAttribute( "name", stats.groupInfo.name ); + xml.writeAttribute( "errors", unexpectedExceptions ); + xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); + xml.writeAttribute( "tests", stats.totals.assertions.total() ); + xml.writeAttribute( "hostname", "tbd" ); // !TBD + if( m_config->showDurations() == ShowDurations::Never ) + xml.writeAttribute( "time", "" ); + else + xml.writeAttribute( "time", suiteTime ); + xml.writeAttribute( "timestamp", getCurrentTimestamp() ); + + // Write test cases + for( TestGroupNode::ChildNodes::const_iterator + it = groupNode.children.begin(), itEnd = groupNode.children.end(); + it != itEnd; + ++it ) + writeTestCase( **it ); + + xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false ); + xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false ); + } + + void writeTestCase( TestCaseNode const& testCaseNode ) { + TestCaseStats const& stats = testCaseNode.value; + + // All test cases have exactly one section - which represents the + // test case itself. That section may have 0-n nested sections + assert( testCaseNode.children.size() == 1 ); + SectionNode const& rootSection = *testCaseNode.children.front(); + + std::string className = stats.testInfo.className; + + if( className.empty() ) { + if( rootSection.childSections.empty() ) + className = "global"; + } + writeSection( className, "", rootSection ); + } + + void writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode ) { + std::string name = trim( sectionNode.stats.sectionInfo.name ); + if( !rootName.empty() ) + name = rootName + '/' + name; + + if( !sectionNode.assertions.empty() || + !sectionNode.stdOut.empty() || + !sectionNode.stdErr.empty() ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); + if( className.empty() ) { + xml.writeAttribute( "classname", name ); + xml.writeAttribute( "name", "root" ); + } + else { + xml.writeAttribute( "classname", className ); + xml.writeAttribute( "name", name ); + } + xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) ); + + writeAssertions( sectionNode ); + + if( !sectionNode.stdOut.empty() ) + xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); + if( !sectionNode.stdErr.empty() ) + xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); + } + for( SectionNode::ChildSections::const_iterator + it = sectionNode.childSections.begin(), + itEnd = sectionNode.childSections.end(); + it != itEnd; + ++it ) + if( className.empty() ) + writeSection( name, "", **it ); + else + writeSection( className, name, **it ); + } + + void writeAssertions( SectionNode const& sectionNode ) { + for( SectionNode::Assertions::const_iterator + it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end(); + it != itEnd; + ++it ) + writeAssertion( *it ); + } + void writeAssertion( AssertionStats const& stats ) { + AssertionResult const& result = stats.assertionResult; + if( !result.isOk() ) { + std::string elementName; + switch( result.getResultType() ) { + case ResultWas::ThrewException: + case ResultWas::FatalErrorCondition: + elementName = "error"; + break; + case ResultWas::ExplicitFailure: + elementName = "failure"; + break; + case ResultWas::ExpressionFailed: + elementName = "failure"; + break; + case ResultWas::DidntThrowException: + elementName = "failure"; + break; + + // We should never see these here: + case ResultWas::Info: + case ResultWas::Warning: + case ResultWas::Ok: + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + elementName = "internalError"; + break; + } + + XmlWriter::ScopedElement e = xml.scopedElement( elementName ); + + xml.writeAttribute( "message", result.getExpandedExpression() ); + xml.writeAttribute( "type", result.getTestMacroName() ); + + std::ostringstream oss; + if( !result.getMessage().empty() ) + oss << result.getMessage() << '\n'; + for( std::vector::const_iterator + it = stats.infoMessages.begin(), + itEnd = stats.infoMessages.end(); + it != itEnd; + ++it ) + if( it->type == ResultWas::Info ) + oss << it->message << '\n'; + + oss << "at " << result.getSourceInfo(); + xml.writeText( oss.str(), false ); + } + } + + XmlWriter xml; + Timer suiteTimer; + std::ostringstream stdOutForSuite; + std::ostringstream stdErrForSuite; + unsigned int unexpectedExceptions; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter ) + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_multi.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_multi.hpp new file mode 100644 index 0000000..0e06892 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_multi.hpp @@ -0,0 +1,152 @@ +/* + * Created by Phil on 5/08/2015. + * Copyright 2015 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED + +#include "../internal/catch_interfaces_reporter.h" + +namespace Catch { + +class MultipleReporters : public SharedImpl { + typedef std::vector > Reporters; + Reporters m_reporters; + +public: + void add( Ptr const& reporter ) { + m_reporters.push_back( reporter ); + } + +public: // IStreamingReporter + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporters[0]->getPreferences(); + } + + virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->noMatchingTestCases( spec ); + } + + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testRunStarting( testRunInfo ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testGroupStarting( groupInfo ); + } + + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testCaseStarting( testInfo ); + } + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->sectionStarting( sectionInfo ); + } + + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->assertionStarting( assertionInfo ); + } + + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + bool clearBuffer = false; + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + clearBuffer |= (*it)->assertionEnded( assertionStats ); + return clearBuffer; + } + + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->sectionEnded( sectionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testCaseEnded( testCaseStats ); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testGroupEnded( testGroupStats ); + } + + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testRunEnded( testRunStats ); + } + + + virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->skipTest( testInfo ); + } + + virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE { + return this; + } + +}; + +Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ) { + Ptr resultingReporter; + + if( existingReporter ) { + MultipleReporters* multi = existingReporter->tryAsMulti(); + if( !multi ) { + multi = new MultipleReporters; + resultingReporter = Ptr( multi ); + if( existingReporter ) + multi->add( existingReporter ); + } + else + resultingReporter = existingReporter; + multi->add( additionalReporter ); + } + else + resultingReporter = additionalReporter; + + return resultingReporter; +} + + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_tap.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_tap.hpp new file mode 100644 index 0000000..d2eeb3c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_tap.hpp @@ -0,0 +1,259 @@ +/* + * Created by Colton Wolkins on 2015-08-15. + * Copyright 2015 Martin Moene. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED + + +// Don't #include any Catch headers here - we can assume they are already +// included before this header. +// This is not good practice in general but is necessary in this case so this +// file can be distributed as a single header that works with the main +// Catch single header. + +#include + +namespace Catch { + + struct TAPReporter : StreamingReporterBase { + + TAPReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + counter(0) + {} + + virtual ~TAPReporter(); + + static std::string getDescription() { + return "Reports test results in TAP format, suitable for test harneses"; + } + + virtual ReporterPreferences getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = false; + return prefs; + } + + virtual void noMatchingTestCases( std::string const& spec ) { + stream << "# No test cases matched '" << spec << "'" << std::endl; + } + + virtual void assertionStarting( AssertionInfo const& ) {} + + virtual bool assertionEnded( AssertionStats const& _assertionStats ) { + ++counter; + + AssertionPrinter printer( stream, _assertionStats, counter ); + printer.print(); + stream << " # " << currentTestCaseInfo->name ; + + stream << std::endl; + return true; + } + + virtual void testRunEnded( TestRunStats const& _testRunStats ) { + printTotals( _testRunStats.totals ); + stream << "\n" << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + private: + size_t counter; + class AssertionPrinter { + void operator= ( AssertionPrinter const& ); + public: + AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, size_t counter ) + : stream( _stream ) + , stats( _stats ) + , result( _stats.assertionResult ) + , messages( _stats.infoMessages ) + , itMessage( _stats.infoMessages.begin() ) + , printInfoMessages( true ) + , counter(counter) + {} + + void print() { + itMessage = messages.begin(); + + switch( result.getResultType() ) { + case ResultWas::Ok: + printResultType( passedString() ); + printOriginalExpression(); + printReconstructedExpression(); + if ( ! result.hasExpression() ) + printRemainingMessages( Colour::None ); + else + printRemainingMessages(); + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) { + printResultType(passedString()); + } else { + printResultType(failedString()); + } + printOriginalExpression(); + printReconstructedExpression(); + if (result.isOk()) { + printIssue(" # TODO"); + } + printRemainingMessages(); + break; + case ResultWas::ThrewException: + printResultType( failedString() ); + printIssue( "unexpected exception with message:" ); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::FatalErrorCondition: + printResultType( failedString() ); + printIssue( "fatal error condition with message:" ); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::DidntThrowException: + printResultType( failedString() ); + printIssue( "expected exception, got none" ); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::Info: + printResultType( "info" ); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::Warning: + printResultType( "warning" ); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::ExplicitFailure: + printResultType( failedString() ); + printIssue( "explicitly" ); + printRemainingMessages( Colour::None ); + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + printResultType( "** internal error **" ); + break; + } + } + + private: + static Colour::Code dimColour() { return Colour::FileName; } + + static const char* failedString() { return "not ok"; } + static const char* passedString() { return "ok"; } + + void printSourceInfo() const { + Colour colourGuard( dimColour() ); + stream << result.getSourceInfo() << ":"; + } + + void printResultType( std::string passOrFail ) const { + if( !passOrFail.empty() ) { + stream << passOrFail << ' ' << counter << " -"; + } + } + + void printIssue( std::string issue ) const { + stream << " " << issue; + } + + void printExpressionWas() { + if( result.hasExpression() ) { + stream << ";"; + { + Colour colour( dimColour() ); + stream << " expression was:"; + } + printOriginalExpression(); + } + } + + void printOriginalExpression() const { + if( result.hasExpression() ) { + stream << " " << result.getExpression(); + } + } + + void printReconstructedExpression() const { + if( result.hasExpandedExpression() ) { + { + Colour colour( dimColour() ); + stream << " for: "; + } + std::string expr = result.getExpandedExpression(); + std::replace( expr.begin(), expr.end(), '\n', ' '); + stream << expr; + } + } + + void printMessage() { + if ( itMessage != messages.end() ) { + stream << " '" << itMessage->message << "'"; + ++itMessage; + } + } + + void printRemainingMessages( Colour::Code colour = dimColour() ) { + if (itMessage == messages.end()) { + return; + } + + // using messages.end() directly yields compilation error: + std::vector::const_iterator itEnd = messages.end(); + const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); + + { + Colour colourGuard( colour ); + stream << " with " << pluralise( N, "message" ) << ":"; + } + + for(; itMessage != itEnd; ) { + // If this assertion is a warning ignore any INFO messages + if( printInfoMessages || itMessage->type != ResultWas::Info ) { + stream << " '" << itMessage->message << "'"; + if ( ++itMessage != itEnd ) { + Colour colourGuard( dimColour() ); + stream << " and"; + } + } + } + } + + private: + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + std::vector messages; + std::vector::const_iterator itMessage; + bool printInfoMessages; + size_t counter; + }; + + void printTotals( const Totals& totals ) const { + if( totals.testCases.total() == 0 ) { + stream << "1..0 # Skipped: No tests ran."; + } else { + stream << "1.." << counter; + } + } + }; + +#ifdef CATCH_IMPL + TAPReporter::~TAPReporter() {} +#endif + + INTERNAL_CATCH_REGISTER_REPORTER( "tap", TAPReporter ) + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_teamcity.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_teamcity.hpp new file mode 100644 index 0000000..1e633f1 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_teamcity.hpp @@ -0,0 +1,221 @@ +/* + * Created by Phil Nash on 19th December 2014 + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED + +// Don't #include any Catch headers here - we can assume they are already +// included before this header. +// This is not good practice in general but is necessary in this case so this +// file can be distributed as a single header that works with the main +// Catch single header. + +#include + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wc++98-compat" +# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +namespace Catch { + + struct TeamCityReporter : StreamingReporterBase { + TeamCityReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_headerPrintedForThisSection( false ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + static std::string escape( std::string const& str ) { + std::string escaped = str; + replaceInPlace( escaped, "|", "||" ); + replaceInPlace( escaped, "'", "|'" ); + replaceInPlace( escaped, "\n", "|n" ); + replaceInPlace( escaped, "\r", "|r" ); + replaceInPlace( escaped, "[", "|[" ); + replaceInPlace( escaped, "]", "|]" ); + return escaped; + } + virtual ~TeamCityReporter() CATCH_OVERRIDE; + + static std::string getDescription() { + return "Reports test results as TeamCity service messages"; + } + + virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + stream << "##teamcity[testIgnored name='" + << escape( testInfo.name ) << "'"; + if( testInfo.isHidden() ) + stream << " message='hidden test'"; + else + stream << " message='test skipped because it didn|'t match the test spec'"; + stream << "]\n"; + } + + virtual void noMatchingTestCases( std::string const& /* spec */ ) CATCH_OVERRIDE {} + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testGroupStarting( groupInfo ); + stream << "##teamcity[testSuiteStarted name='" + << escape( groupInfo.name ) << "']\n"; + } + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + StreamingReporterBase::testGroupEnded( testGroupStats ); + stream << "##teamcity[testSuiteFinished name='" + << escape( testGroupStats.groupInfo.name ) << "']\n"; + } + + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { + } + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + AssertionResult const& result = assertionStats.assertionResult; + if( !result.isOk() ) { + + std::ostringstream msg; + if( !m_headerPrintedForThisSection ) + printSectionHeader( msg ); + m_headerPrintedForThisSection = true; + + msg << result.getSourceInfo() << "\n"; + + switch( result.getResultType() ) { + case ResultWas::ExpressionFailed: + msg << "expression failed"; + break; + case ResultWas::ThrewException: + msg << "unexpected exception"; + break; + case ResultWas::FatalErrorCondition: + msg << "fatal error condition"; + break; + case ResultWas::DidntThrowException: + msg << "no exception was thrown where one was expected"; + break; + case ResultWas::ExplicitFailure: + msg << "explicit failure"; + break; + + // We shouldn't get here because of the isOk() test + case ResultWas::Ok: + case ResultWas::Info: + case ResultWas::Warning: + + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + CATCH_NOT_IMPLEMENTED; + } + if( assertionStats.infoMessages.size() == 1 ) + msg << " with message:"; + if( assertionStats.infoMessages.size() > 1 ) + msg << " with messages:"; + for( std::vector::const_iterator + it = assertionStats.infoMessages.begin(), + itEnd = assertionStats.infoMessages.end(); + it != itEnd; + ++it ) + msg << "\n \"" << it->message << "\""; + + + if( result.hasExpression() ) { + msg << + "\n " << result.getExpressionInMacro() << "\n" + "with expansion:\n" << + " " << result.getExpandedExpression() << "\n"; + } + + stream << "##teamcity[testFailed" + << " name='" << escape( currentTestCaseInfo->name )<< "'" + << " message='" << escape( msg.str() ) << "'" + << "]\n"; + } + return true; + } + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + m_headerPrintedForThisSection = false; + StreamingReporterBase::sectionStarting( sectionInfo ); + } + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseStarting( testInfo ); + stream << "##teamcity[testStarted name='" + << escape( testInfo.name ) << "']\n"; + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseEnded( testCaseStats ); + if( !testCaseStats.stdOut.empty() ) + stream << "##teamcity[testStdOut name='" + << escape( testCaseStats.testInfo.name ) + << "' out='" << escape( testCaseStats.stdOut ) << "']\n"; + if( !testCaseStats.stdErr.empty() ) + stream << "##teamcity[testStdErr name='" + << escape( testCaseStats.testInfo.name ) + << "' out='" << escape( testCaseStats.stdErr ) << "']\n"; + stream << "##teamcity[testFinished name='" + << escape( testCaseStats.testInfo.name ) << "']\n"; + } + + private: + void printSectionHeader( std::ostream& os ) { + assert( !m_sectionStack.empty() ); + + if( m_sectionStack.size() > 1 ) { + os << getLineOfChars<'-'>() << "\n"; + + std::vector::const_iterator + it = m_sectionStack.begin()+1, // Skip first section (test case) + itEnd = m_sectionStack.end(); + for( ; it != itEnd; ++it ) + printHeaderString( os, it->name ); + os << getLineOfChars<'-'>() << "\n"; + } + + SourceLineInfo lineInfo = m_sectionStack.front().lineInfo; + + if( !lineInfo.empty() ) + os << lineInfo << "\n"; + os << getLineOfChars<'.'>() << "\n\n"; + } + + // if string has a : in first line will set indent to follow it on + // subsequent lines + void printHeaderString( std::ostream& os, std::string const& _string, std::size_t indent = 0 ) { + std::size_t i = _string.find( ": " ); + if( i != std::string::npos ) + i+=2; + else + i = 0; + os << Text( _string, TextAttributes() + .setIndent( indent+i) + .setInitialIndent( indent ) ) << "\n"; + } + private: + bool m_headerPrintedForThisSection; + + }; + +#ifdef CATCH_IMPL + TeamCityReporter::~TeamCityReporter() {} +#endif + + INTERNAL_CATCH_REGISTER_REPORTER( "teamcity", TeamCityReporter ) + +} // end namespace Catch + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +#endif // TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_xml.hpp b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_xml.hpp new file mode 100644 index 0000000..55c1956 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/include/reporters/catch_reporter_xml.hpp @@ -0,0 +1,231 @@ +/* + * Created by Phil on 28/10/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED + +#include "catch_reporter_bases.hpp" + +#include "../internal/catch_capture.hpp" +#include "../internal/catch_reporter_registrars.hpp" +#include "../internal/catch_xmlwriter.hpp" +#include "../internal/catch_timer.h" + +namespace Catch { + class XmlReporter : public StreamingReporterBase { + public: + XmlReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_xml(_config.stream()), + m_sectionDepth( 0 ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + virtual ~XmlReporter() CATCH_OVERRIDE; + + static std::string getDescription() { + return "Reports test results as an XML document"; + } + + virtual std::string getStylesheetRef() const { + return std::string(); + } + + void writeSourceInfo( SourceLineInfo const& sourceInfo ) { + m_xml + .writeAttribute( "filename", sourceInfo.file ) + .writeAttribute( "line", sourceInfo.line ); + } + + public: // StreamingReporterBase + + virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE { + StreamingReporterBase::noMatchingTestCases( s ); + } + + virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testRunStarting( testInfo ); + std::string stylesheetRef = getStylesheetRef(); + if( !stylesheetRef.empty() ) + m_xml.writeStylesheetRef( stylesheetRef ); + m_xml.startElement( "Catch" ); + if( !m_config->name().empty() ) + m_xml.writeAttribute( "name", m_config->name() ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testGroupStarting( groupInfo ); + m_xml.startElement( "Group" ) + .writeAttribute( "name", groupInfo.name ); + } + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseStarting(testInfo); + m_xml.startElement( "TestCase" ) + .writeAttribute( "name", trim( testInfo.name ) ) + .writeAttribute( "description", testInfo.description ) + .writeAttribute( "tags", testInfo.tagsAsString ); + + writeSourceInfo( testInfo.lineInfo ); + + if ( m_config->showDurations() == ShowDurations::Always ) + m_testCaseTimer.start(); + m_xml.ensureTagClosed(); + } + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + StreamingReporterBase::sectionStarting( sectionInfo ); + if( m_sectionDepth++ > 0 ) { + m_xml.startElement( "Section" ) + .writeAttribute( "name", trim( sectionInfo.name ) ) + .writeAttribute( "description", sectionInfo.description ); + writeSourceInfo( sectionInfo.lineInfo ); + m_xml.ensureTagClosed(); + } + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + + AssertionResult const& result = assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + if( includeResults ) { + // Print any info messages in tags. + for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); + it != itEnd; + ++it ) { + if( it->type == ResultWas::Info ) { + m_xml.scopedElement( "Info" ) + .writeText( it->message ); + } else if ( it->type == ResultWas::Warning ) { + m_xml.scopedElement( "Warning" ) + .writeText( it->message ); + } + } + } + + // Drop out if result was successful but we're not printing them. + if( !includeResults && result.getResultType() != ResultWas::Warning ) + return true; + + + // Print the expression if there is one. + if( result.hasExpression() ) { + m_xml.startElement( "Expression" ) + .writeAttribute( "success", result.succeeded() ) + .writeAttribute( "type", result.getTestMacroName() ); + + writeSourceInfo( result.getSourceInfo() ); + + m_xml.scopedElement( "Original" ) + .writeText( result.getExpression() ); + m_xml.scopedElement( "Expanded" ) + .writeText( result.getExpandedExpression() ); + } + + // And... Print a result applicable to each result type. + switch( result.getResultType() ) { + case ResultWas::ThrewException: + m_xml.startElement( "Exception" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::FatalErrorCondition: + m_xml.startElement( "FatalErrorCondition" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::Info: + m_xml.scopedElement( "Info" ) + .writeText( result.getMessage() ); + break; + case ResultWas::Warning: + // Warning will already have been written + break; + case ResultWas::ExplicitFailure: + m_xml.startElement( "Failure" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + default: + break; + } + + if( result.hasExpression() ) + m_xml.endElement(); + + return true; + } + + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + StreamingReporterBase::sectionEnded( sectionStats ); + if( --m_sectionDepth > 0 ) { + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); + e.writeAttribute( "successes", sectionStats.assertions.passed ); + e.writeAttribute( "failures", sectionStats.assertions.failed ); + e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); + + m_xml.endElement(); + } + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseEnded( testCaseStats ); + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); + e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); + + if( !testCaseStats.stdOut.empty() ) + m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false ); + if( !testCaseStats.stdErr.empty() ) + m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false ); + + m_xml.endElement(); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + StreamingReporterBase::testGroupEnded( testGroupStats ); + // TODO: Check testGroupStats.aborting and act accordingly. + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) + .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + StreamingReporterBase::testRunEnded( testRunStats ); + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testRunStats.totals.assertions.passed ) + .writeAttribute( "failures", testRunStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + private: + Timer m_testCaseTimer; + XmlWriter m_xml; + int m_sectionDepth; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter ) + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/BenchMain.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/BenchMain.cpp new file mode 100644 index 0000000..32ef4ed --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/BenchMain.cpp @@ -0,0 +1,9 @@ +/* + * Created by Martin on 16/01/2017. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define CATCH_CONFIG_MAIN +#include "catch.hpp" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/StringificationBench.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/StringificationBench.cpp new file mode 100644 index 0000000..1c14939 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/StringificationBench.cpp @@ -0,0 +1,46 @@ +/* + * Created by Martin on 16/01/2017. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + +#include + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE("Successful tests -- REQUIRE", "[Success]") { + const size_t sz = 1 * 1024 * 1024; + + + std::vector vec; vec.reserve(sz); + for (size_t i = 0; i < sz; ++i){ + vec.push_back(i); + REQUIRE(vec.back() == i); + } +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE("Successful tests -- CHECK", "[Success]") { + const size_t sz = 1 * 1024 * 1024; + + + std::vector vec; vec.reserve(sz); + for (size_t i = 0; i < sz; ++i){ + vec.push_back(i); + CHECK(vec.back() == i); + } +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE("Unsuccessful tests -- CHECK", "[Failure]") { + const size_t sz = 1024 * 1024; + + + std::vector vec; vec.reserve(sz); + for (size_t i = 0; i < sz; ++i){ + vec.push_back(i); + CHECK(vec.size() == i); + } +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/readme.txt b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/readme.txt new file mode 100644 index 0000000..c4d2fab --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/readme.txt @@ -0,0 +1,4 @@ +This is very much a work in progress. +The past results are standardized to a developer's machine, +the benchmarking script is basic and there are only 3 benchmarks, +but this should get better in time. For now, at least there is something to go by. diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result new file mode 100644 index 0000000..4b6fc65 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result @@ -0,0 +1,3 @@ +Successful tests -- CHECK: median: 3.38116 (s), stddev: 0.11567366292001534 (s) +Successful tests -- REQUIRE: median: 3.479955 (s), stddev: 0.16295972890734556 (s) +Unsuccessful tests -- CHECK: median: 1.966895 (s), stddev: 0.06323488524716572 (s) diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result new file mode 100644 index 0000000..98c8460 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result @@ -0,0 +1,3 @@ +Successful tests -- CHECK: median: 1.30312 (s), stddev: 0.08759818557862176 (s) +Successful tests -- REQUIRE: median: 1.341535 (s), stddev: 0.1479193390143576 (s) +Unsuccessful tests -- CHECK: median: 1.967755 (s), stddev: 0.07921104121269959 (s) diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result new file mode 100644 index 0000000..fe6366b --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result @@ -0,0 +1,3 @@ +Successful tests -- CHECK: median: 1.2982 (s), stddev: 0.019540648829214084 (s) +Successful tests -- REQUIRE: median: 1.30102 (s), stddev: 0.014758430547392974 (s) +Unsuccessful tests -- CHECK: median: 15.520199999999999 (s), stddev: 0.09536359426485094 (s) diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result new file mode 100644 index 0000000..c9b4d64 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result @@ -0,0 +1,3 @@ +Successful tests -- CHECK: median: 0.7689014999999999 (s), stddev: 0.02127512078801068 (s) +Successful tests -- REQUIRE: median: 0.772845 (s), stddev: 0.03011638381365052 (s) +Unsuccessful tests -- CHECK: median: 15.49 (s), stddev: 0.536088571143903 (s) diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result new file mode 100644 index 0000000..5b82330 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/Benchmark/results/2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result @@ -0,0 +1,3 @@ +Successful tests -- CHECK: median: 0.775769 (s), stddev: 0.014802129132136525 (s) +Successful tests -- REQUIRE: median: 0.785235 (s), stddev: 0.03532672836834896 (s) +Unsuccessful tests -- CHECK: median: 15.156600000000001 (s), stddev: 0.2832375673450742 (s) diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ApproxTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ApproxTests.cpp new file mode 100644 index 0000000..14a8234 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ApproxTests.cpp @@ -0,0 +1,197 @@ +/* + * Created by Phil on 28/04/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Some simple comparisons between doubles", + "[Approx]" +) +{ + double d = 1.23; + + REQUIRE( d == Approx( 1.23 ) ); + REQUIRE( d != Approx( 1.22 ) ); + REQUIRE( d != Approx( 1.24 ) ); + + REQUIRE( Approx( d ) == 1.23 ); + REQUIRE( Approx( d ) != 1.22 ); + REQUIRE( Approx( d ) != 1.24 ); +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Approximate comparisons with different epsilons", + "[Approx]" + ) +{ + double d = 1.23; + + REQUIRE( d != Approx( 1.231 ) ); + REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) ); +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Less-than inequalities with different epsilons", + "[Approx]" +) +{ + double d = 1.23; + + REQUIRE( d <= Approx( 1.24 ) ); + REQUIRE( d <= Approx( 1.23 ) ); + REQUIRE_FALSE( d <= Approx( 1.22 ) ); + REQUIRE( d <= Approx( 1.22 ).epsilon(0.1) ); +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Greater-than inequalities with different epsilons", + "[Approx]" +) +{ + double d = 1.23; + + REQUIRE( d >= Approx( 1.22 ) ); + REQUIRE( d >= Approx( 1.23 ) ); + REQUIRE_FALSE( d >= Approx( 1.24 ) ); + REQUIRE( d >= Approx( 1.24 ).epsilon(0.1) ); +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Approximate comparisons with floats", + "[Approx]" +) +{ + REQUIRE( 1.23f == Approx( 1.23f ) ); + REQUIRE( 0.0f == Approx( 0.0f ) ); +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Approximate comparisons with ints", + "[Approx]" +) +{ + REQUIRE( 1 == Approx( 1 ) ); + REQUIRE( 0 == Approx( 0 ) ); +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Approximate comparisons with mixed numeric types", + "[Approx]" +) +{ + const double dZero = 0; + const double dSmall = 0.00001; + const double dMedium = 1.234; + + REQUIRE( 1.0f == Approx( 1 ) ); + REQUIRE( 0 == Approx( dZero) ); + REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) ); + REQUIRE( 1.234f == Approx( dMedium ) ); + REQUIRE( dMedium == Approx( 1.234f ) ); +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Use a custom approx", + "[Approx][custom]" +) +{ + double d = 1.23; + + Approx approx = Approx::custom().epsilon( 0.005 ); + + REQUIRE( d == approx( 1.23 ) ); + REQUIRE( d == approx( 1.22 ) ); + REQUIRE( d == approx( 1.24 ) ); + REQUIRE( d != approx( 1.25 ) ); + + REQUIRE( approx( d ) == 1.23 ); + REQUIRE( approx( d ) == 1.22 ); + REQUIRE( approx( d ) == 1.24 ); + REQUIRE( approx( d ) != 1.25 ); +} + +inline double divide( double a, double b ) { + return a/b; +} + +TEST_CASE( "Approximate PI", "[Approx][PI]" ) +{ + REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) ); + REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +TEST_CASE( "Absolute margin", "[Approx]" ) { + REQUIRE( 104.0 != Approx(100.0) ); + REQUIRE( 104.0 == Approx(100.0).margin(5) ); + REQUIRE( 104.0 != Approx(100.0).margin(3) ); + REQUIRE( 100.3 != Approx(100.0) ); + REQUIRE( 100.3 == Approx(100.0).margin(0.5) ); +} + +//////////////////////////////////////////////////////////////////////////////// + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) +class StrongDoubleTypedef +{ + double d_ = 0.0; + + public: + explicit StrongDoubleTypedef(double d) : d_(d) {} + explicit operator double() const { return d_; } +}; + +inline std::ostream& operator<<( std::ostream& os, StrongDoubleTypedef td ) { + return os << "StrongDoubleTypedef(" << static_cast(td) << ")"; +} + +TEST_CASE +( + "Comparison with explicitly convertible types", + "[Approx][c++11]" +) +{ + StrongDoubleTypedef td(10.0); + + REQUIRE(td == Approx(10.0)); + REQUIRE(Approx(10.0) == td); + + REQUIRE(td != Approx(11.0)); + REQUIRE(Approx(11.0) != td); + + REQUIRE(td <= Approx(10.0)); + REQUIRE(td <= Approx(11.0)); + REQUIRE(Approx(10.0) <= td); + REQUIRE(Approx(9.0) <= td); + + REQUIRE(td >= Approx(9.0)); + REQUIRE(td >= Approx(10.0)); + REQUIRE(Approx(10.0) >= td); + REQUIRE(Approx(11.0) >= td); + +} +#endif + +//////////////////////////////////////////////////////////////////////////////// diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/BDDTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/BDDTests.cpp new file mode 100644 index 0000000..ed89bfb --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/BDDTests.cpp @@ -0,0 +1,103 @@ +/* + * Created by Phil on 29/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + +inline bool itDoesThis(){ return true; } +inline bool itDoesThat(){ return true; } + +SCENARIO( "Do that thing with the thing", "[Tags]" ) { + GIVEN( "This stuff exists" ) { + // make stuff exist + WHEN( "I do this" ) { + // do this + THEN( "it should do this") + { + REQUIRE( itDoesThis() ); + AND_THEN( "do that") + REQUIRE( itDoesThat() ); + } + } + } +} + +SCENARIO( "Vector resizing affects size and capacity", "[vector][bdd][size][capacity]" ) { + GIVEN( "an empty vector" ) { + std::vector v; + REQUIRE( v.size() == 0 ); + + WHEN( "it is made larger" ) { + v.resize( 10 ); + THEN( "the size and capacity go up" ) { + REQUIRE( v.size() == 10 ); + REQUIRE( v.capacity() >= 10 ); + + AND_WHEN( "it is made smaller again" ) { + v.resize( 5 ); + THEN( "the size goes down but the capacity stays the same" ) { + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 10 ); + } + } + } + } + + WHEN( "we reserve more space" ) { + v.reserve( 10 ); + THEN( "The capacity is increased but the size remains the same" ) { + REQUIRE( v.capacity() >= 10 ); + REQUIRE( v.size() == 0 ); + } + } + } +} + +SCENARIO( "This is a really long scenario name to see how the list command deals with wrapping", + "[very long tags][lots][long][tags][verbose]" + "[one very long tag name that should cause line wrapping writing out using the list command]" + "[anotherReallyLongTagNameButThisOneHasNoObviousWrapPointsSoShouldSplitWithinAWordUsingADashCharacter]" ) { + GIVEN( "A section name that is so long that it cannot fit in a single console width" ) + WHEN( "The test headers are printed as part of the normal running of the scenario" ) + THEN( "The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent" ) + SUCCEED("boo!"); +} + +namespace { + +// a trivial fixture example to support SCENARIO_METHOD tests +struct Fixture +{ + Fixture() + : d_counter(0) + { + } + + int counter() + { + return d_counter++; + } + + int d_counter; +}; + +} + +SCENARIO_METHOD(Fixture, + "BDD tests requiring Fixtures to provide commonly-accessed data or methods", + "[bdd][fixtures]") { + const int before(counter()); + GIVEN("No operations precede me") { + REQUIRE(before == 0); + WHEN("We get the count") { + const int after(counter()); + THEN("Subsequently values are higher") { + REQUIRE(after > before); + } + } + } +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/automake.std.approved.txt b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/automake.std.approved.txt new file mode 100644 index 0000000..85299f7 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/automake.std.approved.txt @@ -0,0 +1,168 @@ +:test-result: PASS # A test name that starts with a # +:test-result: PASS #542 +:test-result: PASS #809 +:test-result: FAIL 'Not' checks that should fail +:test-result: PASS 'Not' checks that should succeed +:test-result: PASS (unimplemented) static bools can be evaluated +:test-result: FAIL A METHOD_AS_TEST_CASE based test run that fails +:test-result: PASS A METHOD_AS_TEST_CASE based test run that succeeds +:test-result: FAIL A TEST_CASE_METHOD based test run that fails +:test-result: PASS A TEST_CASE_METHOD based test run that succeeds +:test-result: FAIL A couple of nested sections followed by a failure +:test-result: FAIL A failing expression with a non streamable type is still captured +:test-result: PASS AllOf matcher +:test-result: PASS An empty test with no assertions +:test-result: PASS An expression with side-effects should only be evaluated once +:test-result: FAIL An unchecked exception reports the line of the last assertion +:test-result: PASS Anonymous test case 1 +:test-result: PASS AnyOf matcher +:test-result: PASS Approximate PI +:test-result: PASS Approximate comparisons with different epsilons +:test-result: PASS Approximate comparisons with floats +:test-result: PASS Approximate comparisons with ints +:test-result: PASS Approximate comparisons with mixed numeric types +:test-result: PASS Assertions then sections +:test-result: PASS Character pretty printing +:test-result: PASS Comparing function pointers +:test-result: PASS Comparing member function pointers +:test-result: PASS Comparisons between ints where one side is computed +:test-result: PASS Comparisons between unsigned ints and negative signed ints match c++ standard behaviour +:test-result: PASS Comparisons with int literals don't warn when mixing signed/ unsigned +:test-result: FAIL Contains string matcher +:test-result: FAIL Custom exceptions can be translated when testing for nothrow +:test-result: FAIL Custom exceptions can be translated when testing for throwing as something else +:test-result: FAIL Custom std-exceptions can be custom translated +:test-result: PASS Demonstrate that a non-const == is not used +:test-result: FAIL EndsWith string matcher +:test-result: XFAIL Equality checks that should fail +:test-result: PASS Equality checks that should succeed +:test-result: PASS Equals +:test-result: FAIL Equals string matcher +:test-result: PASS Exception messages can be tested for +:test-result: FAIL Expected exceptions that don't throw or unexpected exceptions fail the test +:test-result: FAIL FAIL aborts the test +:test-result: FAIL FAIL does not require an argument +:test-result: PASS Factorials are computed +:test-result: PASS Generator over a range of pairs +:test-result: PASS Generators over two ranges +:test-result: PASS Greater-than inequalities with different epsilons +:test-result: PASS INFO and WARN do not abort tests +:test-result: FAIL INFO gets logged on failure +:test-result: FAIL INFO gets logged on failure, even if captured before successful assertions +:test-result: XFAIL Inequality checks that should fail +:test-result: PASS Inequality checks that should succeed +:test-result: PASS Less-than inequalities with different epsilons +:test-result: PASS Long strings can be wrapped +:test-result: PASS Long text is truncted +:test-result: PASS ManuallyRegistered +:test-result: PASS Matchers can be (AllOf) composed with the && operator +:test-result: PASS Matchers can be (AnyOf) composed with the || operator +:test-result: PASS Matchers can be composed with both && and || +:test-result: FAIL Matchers can be composed with both && and || - failing +:test-result: PASS Matchers can be negated (Not) with the ! operator +:test-result: FAIL Matchers can be negated (Not) with the ! operator - failing +:test-result: FAIL Mismatching exception messages failing the test +:test-result: PASS Nice descriptive name +:test-result: FAIL Non-std exceptions can be translated +:test-result: PASS NotImplemented exception +:test-result: PASS Objects that evaluated in boolean contexts can be checked +:test-result: PASS Operators at different namespace levels not hijacked by Koenig lookup +:test-result: FAIL Ordering comparison checks that should fail +:test-result: PASS Ordering comparison checks that should succeed +:test-result: FAIL Output from all sections is reported +:test-result: PASS Parse test names and tags +:test-result: PASS Parsing a std::pair +:test-result: PASS Pointers can be compared to null +:test-result: PASS Pointers can be converted to strings +:test-result: PASS Process can be configured on command line +:test-result: FAIL SCOPED_INFO is reset for each loop +:test-result: PASS SUCCEED counts as a test pass +:test-result: PASS SUCCESS does not require an argument +:test-result: PASS Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods +:test-result: PASS Scenario: Do that thing with the thing +:test-result: PASS Scenario: This is a really long scenario name to see how the list command deals with wrapping +:test-result: PASS Scenario: Vector resizing affects size and capacity +A string sent directly to stdout +A string sent directly to stderr +:test-result: PASS Sends stuff to stdout and stderr +:test-result: PASS Some simple comparisons between doubles +Message from section one +Message from section two +:test-result: PASS Standard output from all sections is reported +:test-result: FAIL StartsWith string matcher +:test-result: PASS String matchers +hello +hello +:test-result: PASS Strings can be rendered with colour +:test-result: FAIL Tabs and newlines show in output +:test-result: PASS Tag alias can be registered against tag patterns +:test-result: PASS Test case with one argument +:test-result: PASS Test enum bit values +:test-result: PASS Text can be formatted using the Text class +:test-result: PASS The NO_FAIL macro reports a failure but does not fail the test +:test-result: FAIL This test 'should' fail but doesn't +:test-result: PASS Tracker +:test-result: FAIL Unexpected exceptions can be translated +:test-result: PASS Use a custom approx +:test-result: PASS Variadic macros +:test-result: PASS When checked exceptions are thrown they can be expected or unexpected +:test-result: FAIL When unchecked exceptions are thrown directly they are always failures +:test-result: FAIL When unchecked exceptions are thrown during a CHECK the test should continue +:test-result: FAIL When unchecked exceptions are thrown during a REQUIRE the test should abort fail +:test-result: FAIL When unchecked exceptions are thrown from functions they are always failures +:test-result: FAIL When unchecked exceptions are thrown from sections they are always failures +:test-result: PASS When unchecked exceptions are thrown, but caught, they do not affect the test +:test-result: PASS Where the LHS is not a simple value +:test-result: PASS Where there is more to the expression after the RHS +:test-result: PASS X/level/0/a +:test-result: PASS X/level/0/b +:test-result: PASS X/level/1/a +:test-result: PASS X/level/1/b +:test-result: PASS XmlEncode +:test-result: PASS atomic if +:test-result: PASS boolean member +:test-result: PASS checkedElse +:test-result: FAIL checkedElse, failing +:test-result: PASS checkedIf +:test-result: FAIL checkedIf, failing +:test-result: PASS comparisons between const int variables +:test-result: PASS comparisons between int variables +:test-result: PASS even more nested SECTION tests +:test-result: PASS first tag +spanner:test-result: PASS has printf +:test-result: FAIL just failure +:test-result: PASS just info +:test-result: FAIL looped SECTION tests +:test-result: FAIL looped tests +:test-result: FAIL more nested SECTION tests +:test-result: PASS nested SECTION tests +:test-result: PASS non streamable - with conv. op +:test-result: PASS not allowed +:test-result: PASS null strings +:test-result: PASS pair > -> toString +:test-result: PASS pointer to class +:test-result: PASS random SECTION tests +:test-result: PASS replaceInPlace +:test-result: PASS second tag +:test-result: FAIL send a single char to INFO +:test-result: FAIL sends information to INFO +:test-result: PASS std::pair -> toString +:test-result: PASS std::pair -> toString +:test-result: PASS std::vector > -> toString +:test-result: FAIL string literals of different sizes can be compared +:test-result: PASS toString on const wchar_t const pointer returns the string contents +:test-result: PASS toString on const wchar_t pointer returns the string contents +:test-result: PASS toString on wchar_t const pointer returns the string contents +:test-result: PASS toString on wchar_t returns the string contents +:test-result: PASS toString( has_maker ) +:test-result: PASS toString( has_maker_and_toString ) +:test-result: PASS toString( has_toString ) +:test-result: PASS toString( vectors -> toString +:test-result: PASS vector -> toString +:test-result: PASS vectors can be sized and resized +:test-result: PASS xmlentitycheck diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/console.std.approved.txt b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/console.std.approved.txt new file mode 100644 index 0000000..e5dd3d3 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/console.std.approved.txt @@ -0,0 +1,895 @@ + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + is a host application. +Run with -? for options + +------------------------------------------------------------------------------- +'Not' checks that should fail +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: FAILED: + CHECK( false != false ) + +ConditionTests.cpp:: FAILED: + CHECK( true != true ) + +ConditionTests.cpp:: FAILED: + CHECK( !true ) +with expansion: + false + +ConditionTests.cpp:: FAILED: + CHECK_FALSE( true ) + +ConditionTests.cpp:: FAILED: + CHECK( !trueValue ) +with expansion: + false + +ConditionTests.cpp:: FAILED: + CHECK_FALSE( trueValue ) +with expansion: + !true + +ConditionTests.cpp:: FAILED: + CHECK( !(1 == 1) ) +with expansion: + false + +ConditionTests.cpp:: FAILED: + CHECK_FALSE( 1 == 1 ) +with expansion: + !(1 == 1) + +------------------------------------------------------------------------------- +A METHOD_AS_TEST_CASE based test run that fails +------------------------------------------------------------------------------- +ClassTests.cpp: +............................................................................... + +ClassTests.cpp:: FAILED: + REQUIRE( s == "world" ) +with expansion: + "hello" == "world" + +------------------------------------------------------------------------------- +A TEST_CASE_METHOD based test run that fails +------------------------------------------------------------------------------- +ClassTests.cpp: +............................................................................... + +ClassTests.cpp:: FAILED: + REQUIRE( m_a == 2 ) +with expansion: + 1 == 2 + +------------------------------------------------------------------------------- +A couple of nested sections followed by a failure +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: +explicitly with message: + to infinity and beyond + +------------------------------------------------------------------------------- +A failing expression with a non streamable type is still captured +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: FAILED: + CHECK( &o1 == &o2 ) +with expansion: + 0x == 0x + +TrickyTests.cpp:: FAILED: + CHECK( o1 == o2 ) +with expansion: + {?} == {?} + +------------------------------------------------------------------------------- +An unchecked exception reports the line of the last assertion +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + {Unknown expression after the reported line} +due to unexpected exception with message: + unexpected exception + +------------------------------------------------------------------------------- +Contains string matcher +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), Contains( "not there" ) ) +with expansion: + "this string contains 'abc' as a substring" contains: "not there" + +------------------------------------------------------------------------------- +Custom exceptions can be translated when testing for nothrow +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + REQUIRE_NOTHROW( throwCustom() ) +due to unexpected exception with message: + custom exception - not std + +------------------------------------------------------------------------------- +Custom exceptions can be translated when testing for throwing as something else +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + REQUIRE_THROWS_AS( throwCustom(), std::exception ) +due to unexpected exception with message: + custom exception - not std + +------------------------------------------------------------------------------- +Custom std-exceptions can be custom translated +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: +due to unexpected exception with message: + custom std exception + +------------------------------------------------------------------------------- +EndsWith string matcher +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), EndsWith( "this" ) ) +with expansion: + "this string contains 'abc' as a substring" ends with: "this" + +------------------------------------------------------------------------------- +Equality checks that should fail +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven == 6 ) +with expansion: + 7 == 6 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven == 8 ) +with expansion: + 7 == 8 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven == 0 ) +with expansion: + 7 == 0 + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one == Approx( 9.11f ) ) +with expansion: + 9.1f == Approx( 9.1099996567 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one == Approx( 9.0f ) ) +with expansion: + 9.1f == Approx( 9.0 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one == Approx( 1 ) ) +with expansion: + 9.1f == Approx( 1.0 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one == Approx( 0 ) ) +with expansion: + 9.1f == Approx( 0.0 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.double_pi == Approx( 3.1415 ) ) +with expansion: + 3.1415926535 == Approx( 3.1415 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello == "goodbye" ) +with expansion: + "hello" == "goodbye" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello == "hell" ) +with expansion: + "hello" == "hell" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello == "hello1" ) +with expansion: + "hello" == "hello1" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello.size() == 6 ) +with expansion: + 5 == 6 + +ConditionTests.cpp:: FAILED: + CHECK( x == Approx( 1.301 ) ) +with expansion: + 1.3 == Approx( 1.301 ) + +------------------------------------------------------------------------------- +Equals string matcher +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), Equals( "something else" ) ) +with expansion: + "this string contains 'abc' as a substring" equals: "something else" + +------------------------------------------------------------------------------- +Expected exceptions that don't throw or unexpected exceptions fail the test +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + CHECK_THROWS_AS( thisThrows(), std::string ) +due to unexpected exception with message: + expected exception + +ExceptionTests.cpp:: FAILED: + CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error ) +because no exception was thrown where one was expected: + +ExceptionTests.cpp:: FAILED: + CHECK_NOTHROW( thisThrows() ) +due to unexpected exception with message: + expected exception + +------------------------------------------------------------------------------- +FAIL aborts the test +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: +explicitly with message: + This is a failure + +------------------------------------------------------------------------------- +FAIL does not require an argument +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: + +------------------------------------------------------------------------------- +INFO and WARN do not abort tests +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: +warning: + this is a warning + +------------------------------------------------------------------------------- +INFO gets logged on failure +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: + REQUIRE( a == 1 ) +with expansion: + 2 == 1 +with messages: + this message should be logged + so should this + +------------------------------------------------------------------------------- +INFO gets logged on failure, even if captured before successful assertions +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: + CHECK( a == 1 ) +with expansion: + 2 == 1 +with messages: + this message may be logged later + this message should be logged + +MessageTests.cpp:: FAILED: + CHECK( a == 0 ) +with expansion: + 2 == 0 +with message: + and this, but later + +------------------------------------------------------------------------------- +Inequality checks that should fail +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven != 7 ) +with expansion: + 7 != 7 + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one != Approx( 9.1f ) ) +with expansion: + 9.1f != Approx( 9.1000003815 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.double_pi != Approx( 3.1415926535 ) ) +with expansion: + 3.1415926535 != Approx( 3.1415926535 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello != "hello" ) +with expansion: + "hello" != "hello" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello.size() != 5 ) +with expansion: + 5 != 5 + +------------------------------------------------------------------------------- +Matchers can be composed with both && and || - failing +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) ) +with expansion: + "this string contains 'abc' as a substring" ( ( contains: "string" or + contains: "different" ) and contains: "random" ) + +------------------------------------------------------------------------------- +Matchers can be negated (Not) with the ! operator - failing +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), !Contains( "substring" ) ) +with expansion: + "this string contains 'abc' as a substring" not contains: "substring" + +------------------------------------------------------------------------------- +Mismatching exception messages failing the test +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + REQUIRE_THROWS_WITH( thisThrows(), "should fail" ) +with expansion: + expected exception + +------------------------------------------------------------------------------- +Nice descriptive name +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +warning: + This one ran + +------------------------------------------------------------------------------- +Non-std exceptions can be translated +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: +due to unexpected exception with message: + custom exception + +------------------------------------------------------------------------------- +Ordering comparison checks that should fail +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven > 7 ) +with expansion: + 7 > 7 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven < 7 ) +with expansion: + 7 < 7 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven > 8 ) +with expansion: + 7 > 8 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven < 6 ) +with expansion: + 7 < 6 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven < 0 ) +with expansion: + 7 < 0 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven < -1 ) +with expansion: + 7 < -1 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven >= 8 ) +with expansion: + 7 >= 8 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven <= 6 ) +with expansion: + 7 <= 6 + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one < 9 ) +with expansion: + 9.1f < 9 + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one > 10 ) +with expansion: + 9.1f > 10 + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one > 9.2 ) +with expansion: + 9.1f > 9.2 + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello > "hello" ) +with expansion: + "hello" > "hello" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello < "hello" ) +with expansion: + "hello" < "hello" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello > "hellp" ) +with expansion: + "hello" > "hellp" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello > "z" ) +with expansion: + "hello" > "z" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello < "hellm" ) +with expansion: + "hello" < "hellm" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello < "a" ) +with expansion: + "hello" < "a" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello >= "z" ) +with expansion: + "hello" >= "z" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello <= "a" ) +with expansion: + "hello" <= "a" + +------------------------------------------------------------------------------- +Output from all sections is reported + one +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: +explicitly with message: + Message from section one + +------------------------------------------------------------------------------- +Output from all sections is reported + two +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: +explicitly with message: + Message from section two + +------------------------------------------------------------------------------- +Pointers can be converted to strings +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: +warning: + actual address of p: 0x + +MessageTests.cpp:: +warning: + toString(p): 0x + +------------------------------------------------------------------------------- +SCOPED_INFO is reset for each loop +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: + REQUIRE( i < 10 ) +with expansion: + 10 < 10 +with messages: + current counter 10 + i := 10 + +A string sent directly to stdout +A string sent directly to stderr +Message from section one +Message from section two +------------------------------------------------------------------------------- +StartsWith string matcher +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), StartsWith( "string" ) ) +with expansion: + "this string contains 'abc' as a substring" starts with: "string" + +hello +hello +------------------------------------------------------------------------------- +Tabs and newlines show in output +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + CHECK( s1 == s2 ) +with expansion: + "if ($b == 10) { + $a = 20; + }" + == + "if ($b == 10) { + $a = 20; + } + " + +------------------------------------------------------------------------------- +Unexpected exceptions can be translated +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: +due to unexpected exception with message: + 3.14 + +------------------------------------------------------------------------------- +Vector matchers that fail + Contains (element) +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( v, VectorContains( -1 ) ) +with expansion: + { 1, 2, 3 } Contains: -1 + +MatchersTests.cpp:: FAILED: + CHECK_THAT( empty, VectorContains( 1 ) ) +with expansion: + { } Contains: 1 + +------------------------------------------------------------------------------- +Vector matchers that fail + Contains (vector) +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( empty, Contains( v) ) +with expansion: + { } Contains: { 1, 2, 3 } + +MatchersTests.cpp:: FAILED: + CHECK_THAT( v, Contains( v2 ) ) +with expansion: + { 1, 2, 3 } Contains: { 1, 2, 4 } + +------------------------------------------------------------------------------- +Vector matchers that fail + Equals +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( v, Equals( v2 ) ) +with expansion: + { 1, 2, 3 } Equals: { 1, 2 } + +MatchersTests.cpp:: FAILED: + CHECK_THAT( v2, Equals( v ) ) +with expansion: + { 1, 2 } Equals: { 1, 2, 3 } + +MatchersTests.cpp:: FAILED: + CHECK_THAT( empty, Equals( v ) ) +with expansion: + { } Equals: { 1, 2, 3 } + +MatchersTests.cpp:: FAILED: + CHECK_THAT( v, Equals( empty ) ) +with expansion: + { 1, 2, 3 } Equals: { } + +------------------------------------------------------------------------------- +When unchecked exceptions are thrown directly they are always failures +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: +due to unexpected exception with message: + unexpected exception + +------------------------------------------------------------------------------- +When unchecked exceptions are thrown during a CHECK the test should continue +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + CHECK( thisThrows() == 0 ) +due to unexpected exception with message: + expected exception + +------------------------------------------------------------------------------- +When unchecked exceptions are thrown during a REQUIRE the test should abort +fail +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + REQUIRE( thisThrows() == 0 ) +due to unexpected exception with message: + expected exception + +------------------------------------------------------------------------------- +When unchecked exceptions are thrown from functions they are always failures +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + CHECK( thisThrows() == 0 ) +due to unexpected exception with message: + expected exception + +------------------------------------------------------------------------------- +When unchecked exceptions are thrown from sections they are always failures + section name +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: +due to unexpected exception with message: + unexpected exception + +------------------------------------------------------------------------------- +Where the LHS is not a simple value +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +warning: + Uncomment the code in this test to check that it gives a sensible compiler + error + +------------------------------------------------------------------------------- +Where there is more to the expression after the RHS +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +warning: + Uncomment the code in this test to check that it gives a sensible compiler + error + +------------------------------------------------------------------------------- +checkedElse, failing +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + CHECKED_ELSE( flag ) +with expansion: + false + +MiscTests.cpp:: FAILED: + REQUIRE( testCheckedElse( false ) ) +with expansion: + false + +------------------------------------------------------------------------------- +checkedIf, failing +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + CHECKED_IF( flag ) +with expansion: + false + +MiscTests.cpp:: FAILED: + REQUIRE( testCheckedIf( false ) ) +with expansion: + false + +spanner------------------------------------------------------------------------------- +just failure +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: +explicitly with message: + Previous info should not be seen + +------------------------------------------------------------------------------- +looped SECTION tests + s1 +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + CHECK( b > a ) +with expansion: + 0 > 1 + +------------------------------------------------------------------------------- +looped tests +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[0] (1) is even + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[1] (1) is even + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[3] (3) is even + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[4] (5) is even + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[6] (13) is even + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[7] (21) is even + +------------------------------------------------------------------------------- +more nested SECTION tests + s1 + s2 +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + REQUIRE( a == b ) +with expansion: + 1 == 2 + +------------------------------------------------------------------------------- +send a single char to INFO +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + REQUIRE( false ) +with message: + 3 + +------------------------------------------------------------------------------- +sends information to INFO +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: + REQUIRE( false ) +with messages: + hi + i := 7 + +------------------------------------------------------------------------------- +string literals of different sizes can be compared +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: FAILED: + REQUIRE( std::string( "first" ) == "second" ) +with expansion: + "first" == "second" + +=============================================================================== +test cases: 164 | 119 passed | 43 failed | 2 failed as expected +assertions: 955 | 851 passed | 86 failed | 18 failed as expected + diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/console.sw.approved.txt b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/console.sw.approved.txt new file mode 100644 index 0000000..72d5dc0 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/console.sw.approved.txt @@ -0,0 +1,9355 @@ + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + is a host application. +Run with -? for options + +------------------------------------------------------------------------------- +# A test name that starts with a # +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: +with message: + yay + +------------------------------------------------------------------------------- +#542 +------------------------------------------------------------------------------- +CompilationTests.cpp: +............................................................................... + +CompilationTests.cpp:: +PASSED: + CHECK_THROWS_AS( throws_int(true), int ) + +CompilationTests.cpp:: +PASSED: + CHECK_THROWS_AS( throws_int(true), int& ) + +CompilationTests.cpp:: +PASSED: + CHECK_THROWS_AS( throws_int(true), const int ) + +CompilationTests.cpp:: +PASSED: + CHECK_THROWS_AS( throws_int(true), const int& ) + +------------------------------------------------------------------------------- +#809 +------------------------------------------------------------------------------- +CompilationTests.cpp: +............................................................................... + +CompilationTests.cpp:: +PASSED: + REQUIRE( 42 == f ) +with expansion: + 42 == {?} + +------------------------------------------------------------------------------- +'Not' checks that should fail +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: FAILED: + CHECK( false != false ) + +ConditionTests.cpp:: FAILED: + CHECK( true != true ) + +ConditionTests.cpp:: FAILED: + CHECK( !true ) +with expansion: + false + +ConditionTests.cpp:: FAILED: + CHECK_FALSE( true ) + +ConditionTests.cpp:: FAILED: + CHECK( !trueValue ) +with expansion: + false + +ConditionTests.cpp:: FAILED: + CHECK_FALSE( trueValue ) +with expansion: + !true + +ConditionTests.cpp:: FAILED: + CHECK( !(1 == 1) ) +with expansion: + false + +ConditionTests.cpp:: FAILED: + CHECK_FALSE( 1 == 1 ) +with expansion: + !(1 == 1) + +------------------------------------------------------------------------------- +'Not' checks that should succeed +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: +PASSED: + REQUIRE( false == false ) + +ConditionTests.cpp:: +PASSED: + REQUIRE( true == true ) + +ConditionTests.cpp:: +PASSED: + REQUIRE( !false ) +with expansion: + true + +ConditionTests.cpp:: +PASSED: + REQUIRE_FALSE( false ) + +ConditionTests.cpp:: +PASSED: + REQUIRE( !falseValue ) +with expansion: + true + +ConditionTests.cpp:: +PASSED: + REQUIRE_FALSE( falseValue ) +with expansion: + !false + +ConditionTests.cpp:: +PASSED: + REQUIRE( !(1 == 2) ) +with expansion: + true + +ConditionTests.cpp:: +PASSED: + REQUIRE_FALSE( 1 == 2 ) +with expansion: + !(1 == 2) + +------------------------------------------------------------------------------- +(unimplemented) static bools can be evaluated + compare to true +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( is_true::value == true ) +with expansion: + true == true + +TrickyTests.cpp:: +PASSED: + REQUIRE( true == is_true::value ) +with expansion: + true == true + +------------------------------------------------------------------------------- +(unimplemented) static bools can be evaluated + compare to false +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( is_true::value == false ) +with expansion: + false == false + +TrickyTests.cpp:: +PASSED: + REQUIRE( false == is_true::value ) +with expansion: + false == false + +------------------------------------------------------------------------------- +(unimplemented) static bools can be evaluated + negation +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( !is_true::value ) +with expansion: + true + +------------------------------------------------------------------------------- +(unimplemented) static bools can be evaluated + double negation +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( !!is_true::value ) +with expansion: + true + +------------------------------------------------------------------------------- +(unimplemented) static bools can be evaluated + direct +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( is_true::value ) +with expansion: + true + +TrickyTests.cpp:: +PASSED: + REQUIRE_FALSE( is_true::value ) +with expansion: + !false + +------------------------------------------------------------------------------- +A METHOD_AS_TEST_CASE based test run that fails +------------------------------------------------------------------------------- +ClassTests.cpp: +............................................................................... + +ClassTests.cpp:: FAILED: + REQUIRE( s == "world" ) +with expansion: + "hello" == "world" + +------------------------------------------------------------------------------- +A METHOD_AS_TEST_CASE based test run that succeeds +------------------------------------------------------------------------------- +ClassTests.cpp: +............................................................................... + +ClassTests.cpp:: +PASSED: + REQUIRE( s == "hello" ) +with expansion: + "hello" == "hello" + +------------------------------------------------------------------------------- +A TEST_CASE_METHOD based test run that fails +------------------------------------------------------------------------------- +ClassTests.cpp: +............................................................................... + +ClassTests.cpp:: FAILED: + REQUIRE( m_a == 2 ) +with expansion: + 1 == 2 + +------------------------------------------------------------------------------- +A TEST_CASE_METHOD based test run that succeeds +------------------------------------------------------------------------------- +ClassTests.cpp: +............................................................................... + +ClassTests.cpp:: +PASSED: + REQUIRE( m_a == 1 ) +with expansion: + 1 == 1 + +------------------------------------------------------------------------------- +A couple of nested sections followed by a failure + Outer + Inner +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: +with message: + that's not flying - that's failing in style + +------------------------------------------------------------------------------- +A couple of nested sections followed by a failure +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: +explicitly with message: + to infinity and beyond + +------------------------------------------------------------------------------- +A failing expression with a non streamable type is still captured +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: FAILED: + CHECK( &o1 == &o2 ) +with expansion: + 0x == 0x + +TrickyTests.cpp:: FAILED: + CHECK( o1 == o2 ) +with expansion: + {?} == {?} + +------------------------------------------------------------------------------- +Absolute margin +------------------------------------------------------------------------------- +ApproxTests.cpp: +............................................................................... + +ApproxTests.cpp:: +PASSED: + REQUIRE( 104.0 != Approx(100.0) ) +with expansion: + 104.0 != Approx( 100.0 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( 104.0 == Approx(100.0).margin(5) ) +with expansion: + 104.0 == Approx( 100.0 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( 104.0 != Approx(100.0).margin(3) ) +with expansion: + 104.0 != Approx( 100.0 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( 100.3 != Approx(100.0) ) +with expansion: + 100.3 != Approx( 100.0 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( 100.3 == Approx(100.0).margin(0.5) ) +with expansion: + 100.3 == Approx( 100.0 ) + +------------------------------------------------------------------------------- +AllOf matcher +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) ) +with expansion: + "this string contains 'abc' as a substring" ( contains: "string" and + contains: "abc" ) + +------------------------------------------------------------------------------- +An expression with side-effects should only be evaluated once +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( i++ == 7 ) +with expansion: + 7 == 7 + +TrickyTests.cpp:: +PASSED: + REQUIRE( i++ == 8 ) +with expansion: + 8 == 8 + +------------------------------------------------------------------------------- +An unchecked exception reports the line of the last assertion +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: +PASSED: + CHECK( 1 == 1 ) + +ExceptionTests.cpp:: FAILED: + {Unknown expression after the reported line} +due to unexpected exception with message: + unexpected exception + +------------------------------------------------------------------------------- +Anonymous test case 1 +------------------------------------------------------------------------------- +VariadicMacrosTests.cpp: +............................................................................... + +VariadicMacrosTests.cpp:: +PASSED: +with message: + anonymous test case + +------------------------------------------------------------------------------- +AnyOf matcher +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) ) +with expansion: + "this string contains 'abc' as a substring" ( contains: "string" or contains: + "not there" ) + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) ) +with expansion: + "this string contains 'abc' as a substring" ( contains: "not there" or + contains: "string" ) + +------------------------------------------------------------------------------- +Approximate PI +------------------------------------------------------------------------------- +ApproxTests.cpp: +............................................................................... + +ApproxTests.cpp:: +PASSED: + REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) ) +with expansion: + 3.1428571429 == Approx( 3.141 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) ) +with expansion: + 3.1428571429 != Approx( 3.141 ) + +------------------------------------------------------------------------------- +Approximate comparisons with different epsilons +------------------------------------------------------------------------------- +ApproxTests.cpp: +............................................................................... + +ApproxTests.cpp:: +PASSED: + REQUIRE( d != Approx( 1.231 ) ) +with expansion: + 1.23 != Approx( 1.231 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) ) +with expansion: + 1.23 == Approx( 1.231 ) + +------------------------------------------------------------------------------- +Approximate comparisons with floats +------------------------------------------------------------------------------- +ApproxTests.cpp: +............................................................................... + +ApproxTests.cpp:: +PASSED: + REQUIRE( 1.23f == Approx( 1.23f ) ) +with expansion: + 1.23f == Approx( 1.2300000191 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( 0.0f == Approx( 0.0f ) ) +with expansion: + 0.0f == Approx( 0.0 ) + +------------------------------------------------------------------------------- +Approximate comparisons with ints +------------------------------------------------------------------------------- +ApproxTests.cpp: +............................................................................... + +ApproxTests.cpp:: +PASSED: + REQUIRE( 1 == Approx( 1 ) ) +with expansion: + 1 == Approx( 1.0 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( 0 == Approx( 0 ) ) +with expansion: + 0 == Approx( 0.0 ) + +------------------------------------------------------------------------------- +Approximate comparisons with mixed numeric types +------------------------------------------------------------------------------- +ApproxTests.cpp: +............................................................................... + +ApproxTests.cpp:: +PASSED: + REQUIRE( 1.0f == Approx( 1 ) ) +with expansion: + 1.0f == Approx( 1.0 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( 0 == Approx( dZero) ) +with expansion: + 0 == Approx( 0.0 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) ) +with expansion: + 0 == Approx( 0.00001 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( 1.234f == Approx( dMedium ) ) +with expansion: + 1.234f == Approx( 1.234 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( dMedium == Approx( 1.234f ) ) +with expansion: + 1.234 == Approx( 1.2339999676 ) + +------------------------------------------------------------------------------- +Assertions then sections +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( Catch::alwaysTrue() ) +with expansion: + true + +------------------------------------------------------------------------------- +Assertions then sections + A section +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( Catch::alwaysTrue() ) +with expansion: + true + +------------------------------------------------------------------------------- +Assertions then sections + A section + Another section +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( Catch::alwaysTrue() ) +with expansion: + true + +------------------------------------------------------------------------------- +Assertions then sections +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( Catch::alwaysTrue() ) +with expansion: + true + +------------------------------------------------------------------------------- +Assertions then sections + A section +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( Catch::alwaysTrue() ) +with expansion: + true + +------------------------------------------------------------------------------- +Assertions then sections + A section + Another other section +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( Catch::alwaysTrue() ) +with expansion: + true + +------------------------------------------------------------------------------- +Capture and info messages + Capture should stringify like assertions +------------------------------------------------------------------------------- +ToStringGeneralTests.cpp: +............................................................................... + +ToStringGeneralTests.cpp:: +PASSED: + REQUIRE( true ) +with message: + i := 2 + +------------------------------------------------------------------------------- +Capture and info messages + Info should NOT stringify the way assertions do +------------------------------------------------------------------------------- +ToStringGeneralTests.cpp: +............................................................................... + +ToStringGeneralTests.cpp:: +PASSED: + REQUIRE( true ) +with message: + 3 + +------------------------------------------------------------------------------- +Character pretty printing + Specifically escaped +------------------------------------------------------------------------------- +ToStringGeneralTests.cpp: +............................................................................... + +ToStringGeneralTests.cpp:: +PASSED: + CHECK( tab == '\t' ) +with expansion: + '\t' == '\t' + +ToStringGeneralTests.cpp:: +PASSED: + CHECK( newline == '\n' ) +with expansion: + '\n' == '\n' + +ToStringGeneralTests.cpp:: +PASSED: + CHECK( carr_return == '\r' ) +with expansion: + '\r' == '\r' + +ToStringGeneralTests.cpp:: +PASSED: + CHECK( form_feed == '\f' ) +with expansion: + '\f' == '\f' + +------------------------------------------------------------------------------- +Character pretty printing + General chars +------------------------------------------------------------------------------- +ToStringGeneralTests.cpp: +............................................................................... + +ToStringGeneralTests.cpp:: +PASSED: + CHECK( space == ' ' ) +with expansion: + ' ' == ' ' + +ToStringGeneralTests.cpp:: +PASSED: + REQUIRE( c == chars[i] ) +with expansion: + 'a' == 'a' + +ToStringGeneralTests.cpp:: +PASSED: + REQUIRE( c == chars[i] ) +with expansion: + 'z' == 'z' + +ToStringGeneralTests.cpp:: +PASSED: + REQUIRE( c == chars[i] ) +with expansion: + 'A' == 'A' + +ToStringGeneralTests.cpp:: +PASSED: + REQUIRE( c == chars[i] ) +with expansion: + 'Z' == 'Z' + +------------------------------------------------------------------------------- +Character pretty printing + Low ASCII +------------------------------------------------------------------------------- +ToStringGeneralTests.cpp: +............................................................................... + +ToStringGeneralTests.cpp:: +PASSED: + CHECK( null_terminator == '\0' ) +with expansion: + 0 == 0 + +ToStringGeneralTests.cpp:: +PASSED: + REQUIRE( c == i ) +with expansion: + 2 == 2 + +ToStringGeneralTests.cpp:: +PASSED: + REQUIRE( c == i ) +with expansion: + 3 == 3 + +ToStringGeneralTests.cpp:: +PASSED: + REQUIRE( c == i ) +with expansion: + 4 == 4 + +ToStringGeneralTests.cpp:: +PASSED: + REQUIRE( c == i ) +with expansion: + 5 == 5 + +------------------------------------------------------------------------------- +Comparing function pointers +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( a ) +with expansion: + true + +TrickyTests.cpp:: +PASSED: + REQUIRE( a == &foo ) +with expansion: + 0x == 0x + +------------------------------------------------------------------------------- +Comparing member function pointers +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + CHECK( m == &S::f ) +with expansion: + 0x + == + 0x + +------------------------------------------------------------------------------- +Comparisons between ints where one side is computed +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: +PASSED: + CHECK( 54 == 6*9 ) +with expansion: + 54 == 54 + +------------------------------------------------------------------------------- +Comparisons between unsigned ints and negative signed ints match c++ standard +behaviour +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: +PASSED: + CHECK( ( -1 > 2u ) ) +with expansion: + true + +ConditionTests.cpp:: +PASSED: + CHECK( -1 > 2u ) +with expansion: + -1 > 2 + +ConditionTests.cpp:: +PASSED: + CHECK( ( 2u < -1 ) ) +with expansion: + true + +ConditionTests.cpp:: +PASSED: + CHECK( 2u < -1 ) +with expansion: + 2 < -1 + +ConditionTests.cpp:: +PASSED: + CHECK( ( minInt > 2u ) ) +with expansion: + true + +ConditionTests.cpp:: +PASSED: + CHECK( minInt > 2u ) +with expansion: + -2147483648 > 2 + +------------------------------------------------------------------------------- +Comparisons with int literals don't warn when mixing signed/ unsigned +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: +PASSED: + REQUIRE( i == 1 ) +with expansion: + 1 == 1 + +ConditionTests.cpp:: +PASSED: + REQUIRE( ui == 2 ) +with expansion: + 2 == 2 + +ConditionTests.cpp:: +PASSED: + REQUIRE( l == 3 ) +with expansion: + 3 == 3 + +ConditionTests.cpp:: +PASSED: + REQUIRE( ul == 4 ) +with expansion: + 4 == 4 + +ConditionTests.cpp:: +PASSED: + REQUIRE( c == 5 ) +with expansion: + 5 == 5 + +ConditionTests.cpp:: +PASSED: + REQUIRE( uc == 6 ) +with expansion: + 6 == 6 + +ConditionTests.cpp:: +PASSED: + REQUIRE( 1 == i ) +with expansion: + 1 == 1 + +ConditionTests.cpp:: +PASSED: + REQUIRE( 2 == ui ) +with expansion: + 2 == 2 + +ConditionTests.cpp:: +PASSED: + REQUIRE( 3 == l ) +with expansion: + 3 == 3 + +ConditionTests.cpp:: +PASSED: + REQUIRE( 4 == ul ) +with expansion: + 4 == 4 + +ConditionTests.cpp:: +PASSED: + REQUIRE( 5 == c ) +with expansion: + 5 == 5 + +ConditionTests.cpp:: +PASSED: + REQUIRE( 6 == uc ) +with expansion: + 6 == 6 + +ConditionTests.cpp:: +PASSED: + REQUIRE( (std::numeric_limits::max)() > ul ) +with expansion: + 18446744073709551615 (0x) + > + 4 + +------------------------------------------------------------------------------- +Contains string matcher +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), Contains( "not there" ) ) +with expansion: + "this string contains 'abc' as a substring" contains: "not there" + +------------------------------------------------------------------------------- +Custom exceptions can be translated when testing for nothrow +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + REQUIRE_NOTHROW( throwCustom() ) +due to unexpected exception with message: + custom exception - not std + +------------------------------------------------------------------------------- +Custom exceptions can be translated when testing for throwing as something else +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + REQUIRE_THROWS_AS( throwCustom(), std::exception ) +due to unexpected exception with message: + custom exception - not std + +------------------------------------------------------------------------------- +Custom std-exceptions can be custom translated +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: +due to unexpected exception with message: + custom std exception + +------------------------------------------------------------------------------- +Demonstrate that a non-const == is not used +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( t == 1u ) +with expansion: + {?} == 1 + +------------------------------------------------------------------------------- +EndsWith string matcher +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), EndsWith( "this" ) ) +with expansion: + "this string contains 'abc' as a substring" ends with: "this" + +------------------------------------------------------------------------------- +Equality checks that should fail +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven == 6 ) +with expansion: + 7 == 6 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven == 8 ) +with expansion: + 7 == 8 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven == 0 ) +with expansion: + 7 == 0 + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one == Approx( 9.11f ) ) +with expansion: + 9.1f == Approx( 9.1099996567 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one == Approx( 9.0f ) ) +with expansion: + 9.1f == Approx( 9.0 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one == Approx( 1 ) ) +with expansion: + 9.1f == Approx( 1.0 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one == Approx( 0 ) ) +with expansion: + 9.1f == Approx( 0.0 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.double_pi == Approx( 3.1415 ) ) +with expansion: + 3.1415926535 == Approx( 3.1415 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello == "goodbye" ) +with expansion: + "hello" == "goodbye" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello == "hell" ) +with expansion: + "hello" == "hell" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello == "hello1" ) +with expansion: + "hello" == "hello1" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello.size() == 6 ) +with expansion: + 5 == 6 + +ConditionTests.cpp:: FAILED: + CHECK( x == Approx( 1.301 ) ) +with expansion: + 1.3 == Approx( 1.301 ) + +------------------------------------------------------------------------------- +Equality checks that should succeed +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven == 7 ) +with expansion: + 7 == 7 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.float_nine_point_one == Approx( 9.1f ) ) +with expansion: + 9.1f == Approx( 9.1000003815 ) + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.double_pi == Approx( 3.1415926535 ) ) +with expansion: + 3.1415926535 == Approx( 3.1415926535 ) + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello == "hello" ) +with expansion: + "hello" == "hello" + +ConditionTests.cpp:: +PASSED: + REQUIRE( "hello" == data.str_hello ) +with expansion: + "hello" == "hello" + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello.size() == 5 ) +with expansion: + 5 == 5 + +ConditionTests.cpp:: +PASSED: + REQUIRE( x == Approx( 1.3 ) ) +with expansion: + 1.3 == Approx( 1.3 ) + +------------------------------------------------------------------------------- +Equals +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) ) +with expansion: + "this string contains 'abc' as a substring" equals: "this string contains + 'abc' as a substring" + +------------------------------------------------------------------------------- +Equals string matcher +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), Equals( "something else" ) ) +with expansion: + "this string contains 'abc' as a substring" equals: "something else" + +------------------------------------------------------------------------------- +Exception messages can be tested for + exact match +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: +PASSED: + REQUIRE_THROWS_WITH( thisThrows(), "expected exception" ) + +------------------------------------------------------------------------------- +Exception messages can be tested for + different case +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: +PASSED: + REQUIRE_THROWS_WITH( thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) ) + +------------------------------------------------------------------------------- +Exception messages can be tested for + wildcarded +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: +PASSED: + REQUIRE_THROWS_WITH( thisThrows(), StartsWith( "expected" ) ) + +ExceptionTests.cpp:: +PASSED: + REQUIRE_THROWS_WITH( thisThrows(), EndsWith( "exception" ) ) + +ExceptionTests.cpp:: +PASSED: + REQUIRE_THROWS_WITH( thisThrows(), Contains( "except" ) ) + +ExceptionTests.cpp:: +PASSED: + REQUIRE_THROWS_WITH( thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) ) + +------------------------------------------------------------------------------- +Expected exceptions that don't throw or unexpected exceptions fail the test +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + CHECK_THROWS_AS( thisThrows(), std::string ) +due to unexpected exception with message: + expected exception + +ExceptionTests.cpp:: FAILED: + CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error ) +because no exception was thrown where one was expected: + +ExceptionTests.cpp:: FAILED: + CHECK_NOTHROW( thisThrows() ) +due to unexpected exception with message: + expected exception + +------------------------------------------------------------------------------- +FAIL aborts the test +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: +explicitly with message: + This is a failure + +------------------------------------------------------------------------------- +FAIL does not require an argument +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: + +------------------------------------------------------------------------------- +Factorials are computed +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( Factorial(0) == 1 ) +with expansion: + 1 == 1 + +MiscTests.cpp:: +PASSED: + REQUIRE( Factorial(1) == 1 ) +with expansion: + 1 == 1 + +MiscTests.cpp:: +PASSED: + REQUIRE( Factorial(2) == 2 ) +with expansion: + 2 == 2 + +MiscTests.cpp:: +PASSED: + REQUIRE( Factorial(3) == 6 ) +with expansion: + 6 == 6 + +MiscTests.cpp:: +PASSED: + REQUIRE( Factorial(10) == 3628800 ) +with expansion: + 3628800 (0x) == 3628800 (0x) + +------------------------------------------------------------------------------- +Generator over a range of pairs +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( i->first == i->second-1 ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +Generator over a range of pairs +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( i->first == i->second-1 ) +with expansion: + 2 == 2 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 2 == 2 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 200 == 200 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 4 == 4 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 200 == 200 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 6 == 6 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 200 == 200 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 8 == 8 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 200 == 200 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 10 == 10 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 200 == 200 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 30 == 30 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 200 == 200 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 40 == 40 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 200 == 200 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 42 == 42 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 200 == 200 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 72 == 72 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 200 == 200 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 2 == 2 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 202 == 202 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 4 == 4 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 202 == 202 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 6 == 6 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 202 == 202 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 8 == 8 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 202 == 202 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 10 == 10 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 202 == 202 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 30 == 30 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 202 == 202 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 40 == 40 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 202 == 202 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 42 == 42 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 202 == 202 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 72 == 72 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 202 == 202 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 2 == 2 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 204 == 204 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 4 == 4 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 204 == 204 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 6 == 6 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 204 == 204 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 8 == 8 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 204 == 204 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 10 == 10 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 204 == 204 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 30 == 30 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 204 == 204 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 40 == 40 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 204 == 204 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 42 == 42 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 204 == 204 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 72 == 72 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 204 == 204 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 2 == 2 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 206 == 206 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 4 == 4 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 206 == 206 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 6 == 6 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 206 == 206 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 8 == 8 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 206 == 206 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 10 == 10 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 206 == 206 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 30 == 30 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 206 == 206 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 40 == 40 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 206 == 206 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 42 == 42 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 206 == 206 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 72 == 72 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 206 == 206 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 2 == 2 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 208 == 208 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 4 == 4 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 208 == 208 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 6 == 6 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 208 == 208 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 8 == 8 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 208 == 208 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 10 == 10 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 208 == 208 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 30 == 30 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 208 == 208 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 40 == 40 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 208 == 208 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 42 == 42 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 208 == 208 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 72 == 72 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 208 == 208 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 2 == 2 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 210 == 210 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 4 == 4 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 210 == 210 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 6 == 6 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 210 == 210 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 8 == 8 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 210 == 210 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 10 == 10 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 210 == 210 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 30 == 30 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 210 == 210 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 40 == 40 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 210 == 210 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 42 == 42 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 210 == 210 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 72 == 72 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 210 == 210 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 2 == 2 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 212 == 212 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 4 == 4 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 212 == 212 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 6 == 6 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 212 == 212 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 8 == 8 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 212 == 212 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 10 == 10 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 212 == 212 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 30 == 30 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 212 == 212 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 40 == 40 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 212 == 212 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 42 == 42 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 212 == 212 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 72 == 72 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 212 == 212 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 2 == 2 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 214 == 214 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 4 == 4 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 214 == 214 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 6 == 6 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 214 == 214 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 8 == 8 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 214 == 214 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 10 == 10 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 214 == 214 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 30 == 30 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 214 == 214 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 40 == 40 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 214 == 214 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 42 == 42 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 214 == 214 + +------------------------------------------------------------------------------- +Generators over two ranges +------------------------------------------------------------------------------- +GeneratorTests.cpp: +............................................................................... + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) +with expansion: + 72 == 72 + +GeneratorTests.cpp:: +PASSED: + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) +with expansion: + 214 == 214 + +------------------------------------------------------------------------------- +Greater-than inequalities with different epsilons +------------------------------------------------------------------------------- +ApproxTests.cpp: +............................................................................... + +ApproxTests.cpp:: +PASSED: + REQUIRE( d >= Approx( 1.22 ) ) +with expansion: + 1.23 >= Approx( 1.22 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( d >= Approx( 1.23 ) ) +with expansion: + 1.23 >= Approx( 1.23 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE_FALSE( d >= Approx( 1.24 ) ) +with expansion: + !(1.23 >= Approx( 1.24 )) + +ApproxTests.cpp:: +PASSED: + REQUIRE( d >= Approx( 1.24 ).epsilon(0.1) ) +with expansion: + 1.23 >= Approx( 1.24 ) + +------------------------------------------------------------------------------- +INFO and WARN do not abort tests +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: +warning: + this is a message + this is a warning + +------------------------------------------------------------------------------- +INFO gets logged on failure +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: + REQUIRE( a == 1 ) +with expansion: + 2 == 1 +with messages: + this message should be logged + so should this + +------------------------------------------------------------------------------- +INFO gets logged on failure, even if captured before successful assertions +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: +PASSED: + CHECK( a == 2 ) +with expansion: + 2 == 2 +with message: + this message may be logged later + +MessageTests.cpp:: FAILED: + CHECK( a == 1 ) +with expansion: + 2 == 1 +with message: + this message should be logged + +MessageTests.cpp:: FAILED: + CHECK( a == 0 ) +with expansion: + 2 == 0 +with message: + and this, but later + +MessageTests.cpp:: +PASSED: + CHECK( a == 2 ) +with expansion: + 2 == 2 +with message: + but not this + +------------------------------------------------------------------------------- +Inequality checks that should fail +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven != 7 ) +with expansion: + 7 != 7 + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one != Approx( 9.1f ) ) +with expansion: + 9.1f != Approx( 9.1000003815 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.double_pi != Approx( 3.1415926535 ) ) +with expansion: + 3.1415926535 != Approx( 3.1415926535 ) + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello != "hello" ) +with expansion: + "hello" != "hello" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello.size() != 5 ) +with expansion: + 5 != 5 + +------------------------------------------------------------------------------- +Inequality checks that should succeed +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven != 6 ) +with expansion: + 7 != 6 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven != 8 ) +with expansion: + 7 != 8 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.float_nine_point_one != Approx( 9.11f ) ) +with expansion: + 9.1f != Approx( 9.1099996567 ) + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.float_nine_point_one != Approx( 9.0f ) ) +with expansion: + 9.1f != Approx( 9.0 ) + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.float_nine_point_one != Approx( 1 ) ) +with expansion: + 9.1f != Approx( 1.0 ) + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.float_nine_point_one != Approx( 0 ) ) +with expansion: + 9.1f != Approx( 0.0 ) + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.double_pi != Approx( 3.1415 ) ) +with expansion: + 3.1415926535 != Approx( 3.1415 ) + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello != "goodbye" ) +with expansion: + "hello" != "goodbye" + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello != "hell" ) +with expansion: + "hello" != "hell" + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello != "hello1" ) +with expansion: + "hello" != "hello1" + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello.size() != 6 ) +with expansion: + 5 != 6 + +------------------------------------------------------------------------------- +Less-than inequalities with different epsilons +------------------------------------------------------------------------------- +ApproxTests.cpp: +............................................................................... + +ApproxTests.cpp:: +PASSED: + REQUIRE( d <= Approx( 1.24 ) ) +with expansion: + 1.23 <= Approx( 1.24 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( d <= Approx( 1.23 ) ) +with expansion: + 1.23 <= Approx( 1.23 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE_FALSE( d <= Approx( 1.22 ) ) +with expansion: + !(1.23 <= Approx( 1.22 )) + +ApproxTests.cpp:: +PASSED: + REQUIRE( d <= Approx( 1.22 ).epsilon(0.1) ) +with expansion: + 1.23 <= Approx( 1.22 ) + +------------------------------------------------------------------------------- +Long strings can be wrapped + plain string + No wrapping +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ) +with expansion: + "one two three four" + == + "one two three four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString ) +with expansion: + "one two three four" + == + "one two three four" + +------------------------------------------------------------------------------- +Long strings can be wrapped + plain string + Wrapped once +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" ) +with expansion: + "one two three + four" + == + "one two three + four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" ) +with expansion: + "one two three + four" + == + "one two three + four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" ) +with expansion: + "one two three + four" + == + "one two three + four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" ) +with expansion: + "one two three + four" + == + "one two three + four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" ) +with expansion: + "one two + three four" + == + "one two + three four" + +------------------------------------------------------------------------------- +Long strings can be wrapped + plain string + Wrapped twice +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" ) +with expansion: + "one two + three + four" + == + "one two + three + four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" ) +with expansion: + "one two + three + four" + == + "one two + three + four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" ) +with expansion: + "one two + three + four" + == + "one two + three + four" + +------------------------------------------------------------------------------- +Long strings can be wrapped + plain string + Wrapped three times +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" ) +with expansion: + "one + two + three + four" + == + "one + two + three + four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" ) +with expansion: + "one + two + three + four" + == + "one + two + three + four" + +------------------------------------------------------------------------------- +Long strings can be wrapped + plain string + Short wrap +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" ) +with expansion: + "abc- + def" + == + "abc- + def" + +TestMain.cpp:: +PASSED: + CHECK( Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" ) +with expansion: + "abc- + defg" + == + "abc- + defg" + +TestMain.cpp:: +PASSED: + CHECK( Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" ) +with expansion: + "abc- + def- + gh" + == + "abc- + def- + gh" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" ) +with expansion: + "one + two + thr- + ee + four" + == + "one + two + thr- + ee + four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" ) +with expansion: + "one + two + th- + ree + fo- + ur" + == + "one + two + th- + ree + fo- + ur" + +------------------------------------------------------------------------------- +Long strings can be wrapped + plain string + As container +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + REQUIRE( text.size() == 4 ) +with expansion: + 4 == 4 + +TestMain.cpp:: +PASSED: + CHECK( text[0] == "one" ) +with expansion: + "one" == "one" + +TestMain.cpp:: +PASSED: + CHECK( text[1] == "two" ) +with expansion: + "two" == "two" + +TestMain.cpp:: +PASSED: + CHECK( text[2] == "three" ) +with expansion: + "three" == "three" + +TestMain.cpp:: +PASSED: + CHECK( text[3] == "four" ) +with expansion: + "four" == "four" + +------------------------------------------------------------------------------- +Long strings can be wrapped + plain string + Indent first line differently +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( text.toString() == " one two\n three\n four" ) +with expansion: + " one two + three + four" + == + " one two + three + four" + +------------------------------------------------------------------------------- +Long strings can be wrapped + With newlines + No wrapping +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ) +with expansion: + "one two + three four" + == + "one two + three four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString ) +with expansion: + "one two + three four" + == + "one two + three four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString ) +with expansion: + "one two + three four" + == + "one two + three four" + +------------------------------------------------------------------------------- +Long strings can be wrapped + With newlines + Trailing newline +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef" ) +with expansion: + "abcdef" == "abcdef" + +TestMain.cpp:: +PASSED: + CHECK( Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" ) +with expansion: + "abcdef" == "abcdef" + +TestMain.cpp:: +PASSED: + CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" ) +with expansion: + "abcdef" == "abcdef" + +TestMain.cpp:: +PASSED: + CHECK( Text( "abcdef\n", TextAttributes().setWidth( 5 ) ).toString() == "abcd-\nef" ) +with expansion: + "abcd- + ef" + == + "abcd- + ef" + +------------------------------------------------------------------------------- +Long strings can be wrapped + With newlines + Wrapped once +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" ) +with expansion: + "one two + three + four" + == + "one two + three + four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" ) +with expansion: + "one two + three + four" + == + "one two + three + four" + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" ) +with expansion: + "one two + three + four" + == + "one two + three + four" + +------------------------------------------------------------------------------- +Long strings can be wrapped + With newlines + Wrapped twice +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" ) +with expansion: + "one + two + three + four" + == + "one + two + three + four" + +------------------------------------------------------------------------------- +Long strings can be wrapped + With wrap-before/ after characters + No wrapping +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ) +with expansion: + "one,two(three) " + == + "one,two(three) " + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 24 ) ).toString() == testString ) +with expansion: + "one,two(three) " + == + "one,two(three) " + +------------------------------------------------------------------------------- +Long strings can be wrapped + With wrap-before/ after characters + Wrap before +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 11 ) ).toString() == "one,two\n(three)\n" ) +with expansion: + "one,two + (three) + " + == + "one,two + (three) + " + +------------------------------------------------------------------------------- +Long strings can be wrapped + With wrap-before/ after characters + Wrap after +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one,\ntwo\n(thre-\ne)\n" ) +with expansion: + "one, + two + (thre- + e) + " + == + "one, + two + (thre- + e) + " + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one,\ntwo\n(thr-\nee)\n" ) +with expansion: + "one, + two + (thr- + ee) + " + == + "one, + two + (thr- + ee) + " + +TestMain.cpp:: +PASSED: + CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one,\ntwo\n(th-\nree)\n" ) +with expansion: + "one, + two + (th- + ree) + " + == + "one, + two + (th- + ree) + " + +------------------------------------------------------------------------------- +Long text is truncated +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) ) +with expansion: + "***************************************************************************- + ***- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ + ****************************************************************************- + **- + ****************************************************************************- + **- + ************************ +... message truncated due to excessive size + +------------------------------------------------------------------------------- +ManuallyRegistered +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: +with message: + was called + +------------------------------------------------------------------------------- +Matchers can be (AllOf) composed with the && operator +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), Contains( "string" ) && Contains( "abc" ) && Contains( "substring" ) && Contains( "contains" ) ) +with expansion: + "this string contains 'abc' as a substring" ( contains: "string" and + contains: "abc" and contains: "substring" and contains: "contains" ) + +------------------------------------------------------------------------------- +Matchers can be (AnyOf) composed with the || operator +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) ) +with expansion: + "this string contains 'abc' as a substring" ( contains: "string" or contains: + "different" or contains: "random" ) + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) ) +with expansion: + "some completely different text that contains one common word" ( contains: + "string" or contains: "different" or contains: "random" ) + +------------------------------------------------------------------------------- +Matchers can be composed with both && and || +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) ) +with expansion: + "this string contains 'abc' as a substring" ( ( contains: "string" or + contains: "different" ) and contains: "substring" ) + +------------------------------------------------------------------------------- +Matchers can be composed with both && and || - failing +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) ) +with expansion: + "this string contains 'abc' as a substring" ( ( contains: "string" or + contains: "different" ) and contains: "random" ) + +------------------------------------------------------------------------------- +Matchers can be negated (Not) with the ! operator +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), !Contains( "different" ) ) +with expansion: + "this string contains 'abc' as a substring" not contains: "different" + +------------------------------------------------------------------------------- +Matchers can be negated (Not) with the ! operator - failing +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), !Contains( "substring" ) ) +with expansion: + "this string contains 'abc' as a substring" not contains: "substring" + +------------------------------------------------------------------------------- +Mismatching exception messages failing the test +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: +PASSED: + REQUIRE_THROWS_WITH( thisThrows(), "expected exception" ) + +ExceptionTests.cpp:: FAILED: + REQUIRE_THROWS_WITH( thisThrows(), "should fail" ) +with expansion: + expected exception + +------------------------------------------------------------------------------- +Nice descriptive name +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +warning: + This one ran + +------------------------------------------------------------------------------- +Non-std exceptions can be translated +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: +due to unexpected exception with message: + custom exception + +------------------------------------------------------------------------------- +NotImplemented exception +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: +PASSED: + REQUIRE_THROWS( thisFunctionNotImplemented( 7 ) ) + +------------------------------------------------------------------------------- +Objects that evaluated in boolean contexts can be checked +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + CHECK( True ) +with expansion: + true + +TrickyTests.cpp:: +PASSED: + CHECK( !False ) +with expansion: + true + +TrickyTests.cpp:: +PASSED: + CHECK_FALSE( False ) +with expansion: + !false + +------------------------------------------------------------------------------- +Operators at different namespace levels not hijacked by Koenig lookup +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( 0x == o ) +with expansion: + 3221225472 (0x) == {?} + +------------------------------------------------------------------------------- +Ordering comparison checks that should fail +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven > 7 ) +with expansion: + 7 > 7 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven < 7 ) +with expansion: + 7 < 7 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven > 8 ) +with expansion: + 7 > 8 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven < 6 ) +with expansion: + 7 < 6 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven < 0 ) +with expansion: + 7 < 0 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven < -1 ) +with expansion: + 7 < -1 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven >= 8 ) +with expansion: + 7 >= 8 + +ConditionTests.cpp:: FAILED: + CHECK( data.int_seven <= 6 ) +with expansion: + 7 <= 6 + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one < 9 ) +with expansion: + 9.1f < 9 + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one > 10 ) +with expansion: + 9.1f > 10 + +ConditionTests.cpp:: FAILED: + CHECK( data.float_nine_point_one > 9.2 ) +with expansion: + 9.1f > 9.2 + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello > "hello" ) +with expansion: + "hello" > "hello" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello < "hello" ) +with expansion: + "hello" < "hello" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello > "hellp" ) +with expansion: + "hello" > "hellp" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello > "z" ) +with expansion: + "hello" > "z" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello < "hellm" ) +with expansion: + "hello" < "hellm" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello < "a" ) +with expansion: + "hello" < "a" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello >= "z" ) +with expansion: + "hello" >= "z" + +ConditionTests.cpp:: FAILED: + CHECK( data.str_hello <= "a" ) +with expansion: + "hello" <= "a" + +------------------------------------------------------------------------------- +Ordering comparison checks that should succeed +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven < 8 ) +with expansion: + 7 < 8 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven > 6 ) +with expansion: + 7 > 6 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven > 0 ) +with expansion: + 7 > 0 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven > -1 ) +with expansion: + 7 > -1 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven >= 7 ) +with expansion: + 7 >= 7 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven >= 6 ) +with expansion: + 7 >= 6 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven <= 7 ) +with expansion: + 7 <= 7 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.int_seven <= 8 ) +with expansion: + 7 <= 8 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.float_nine_point_one > 9 ) +with expansion: + 9.1f > 9 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.float_nine_point_one < 10 ) +with expansion: + 9.1f < 10 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.float_nine_point_one < 9.2 ) +with expansion: + 9.1f < 9.2 + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello <= "hello" ) +with expansion: + "hello" <= "hello" + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello >= "hello" ) +with expansion: + "hello" >= "hello" + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello < "hellp" ) +with expansion: + "hello" < "hellp" + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello < "zebra" ) +with expansion: + "hello" < "zebra" + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello > "hellm" ) +with expansion: + "hello" > "hellm" + +ConditionTests.cpp:: +PASSED: + REQUIRE( data.str_hello > "a" ) +with expansion: + "hello" > "a" + +------------------------------------------------------------------------------- +Output from all sections is reported + one +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: +explicitly with message: + Message from section one + +------------------------------------------------------------------------------- +Output from all sections is reported + two +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: +explicitly with message: + Message from section two + +------------------------------------------------------------------------------- +Parse test names and tags + Empty test spec should have no filters +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + Test spec from empty string should have no filters +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches(tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + Test spec from just a comma should have no filters +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + Test spec from name should have one filter +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + Test spec from quoted name should have one filter +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + Test spec from name should have one filter +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + Wildcard at the start +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( parseTestSpec( "*a" ).matches( tcA ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + Wildcard at the end +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( parseTestSpec( "a*" ).matches( tcA ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + Wildcard at both ends +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( parseTestSpec( "*a*" ).matches( tcA ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + Redundant wildcard at the start +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + Redundant wildcard at the end +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + Redundant wildcard at both ends +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + Wildcard at both ends, redundant at start +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + Just wildcard +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + Single tag +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + Single tag, two matches +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + Two tags +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + Two tags, spare separated +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + Wildcarded name and tag +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + Single tag exclusion +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + One tag exclusion and one tag inclusion +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + One tag exclusion and one wldcarded name inclusion +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + One tag exclusion, using exclude:, and one wldcarded name inclusion +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + name exclusion +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parse test names and tags + wildcarded name exclusion +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + wildcarded name exclusion with tag inclusion +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + wildcarded name exclusion, using exclude:, with tag inclusion +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + two wildcarded names +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + empty tag +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + empty quoted name +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Parse test names and tags + quoted string followed by tag exclusion +------------------------------------------------------------------------------- +CmdLineTests.cpp: +............................................................................... + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.hasFilters() == true ) +with expansion: + true == true + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcA ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcB ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcC ) == false ) +with expansion: + false == false + +CmdLineTests.cpp:: +PASSED: + CHECK( spec.matches( tcD ) == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Parsing a std::pair +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( (std::pair( 1, 2 )) == aNicePair ) +with expansion: + std::pair( 1, 2 ) == std::pair( 1, 2 ) + +------------------------------------------------------------------------------- +Pointers can be compared to null +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: +PASSED: + REQUIRE( p == 0 ) +with expansion: + NULL == 0 + +ConditionTests.cpp:: +PASSED: + REQUIRE( p == pNULL ) +with expansion: + NULL == NULL + +ConditionTests.cpp:: +PASSED: + REQUIRE( p != 0 ) +with expansion: + 0x != 0 + +ConditionTests.cpp:: +PASSED: + REQUIRE( cp != 0 ) +with expansion: + 0x != 0 + +ConditionTests.cpp:: +PASSED: + REQUIRE( cpc != 0 ) +with expansion: + 0x != 0 + +ConditionTests.cpp:: +PASSED: + REQUIRE( returnsNull() == 0 ) +with expansion: + {null string} == 0 + +ConditionTests.cpp:: +PASSED: + REQUIRE( returnsConstNull() == 0 ) +with expansion: + {null string} == 0 + +ConditionTests.cpp:: +PASSED: + REQUIRE( 0 != p ) +with expansion: + 0 != 0x + +------------------------------------------------------------------------------- +Pointers can be converted to strings +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: +warning: + actual address of p: 0x + +MessageTests.cpp:: +warning: + toString(p): 0x + +------------------------------------------------------------------------------- +Process can be configured on command line + default - no arguments +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + CHECK( config.shouldDebugBreak == false ) +with expansion: + false == false + +TestMain.cpp:: +PASSED: + CHECK( config.abortAfter == -1 ) +with expansion: + -1 == -1 + +TestMain.cpp:: +PASSED: + CHECK( config.noThrow == false ) +with expansion: + false == false + +TestMain.cpp:: +PASSED: + CHECK( config.reporterNames.empty() ) +with expansion: + true + +------------------------------------------------------------------------------- +Process can be configured on command line + test lists + 1 test +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false ) +with expansion: + false == false + +TestMain.cpp:: +PASSED: + REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) ) +with expansion: + true + +------------------------------------------------------------------------------- +Process can be configured on command line + test lists + Specify one test case exclusion using exclude: +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ) +with expansion: + false == false + +TestMain.cpp:: +PASSED: + REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ) +with expansion: + true + +------------------------------------------------------------------------------- +Process can be configured on command line + test lists + Specify one test case exclusion using ~ +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ) +with expansion: + false == false + +TestMain.cpp:: +PASSED: + REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ) +with expansion: + true + +------------------------------------------------------------------------------- +Process can be configured on command line + reporter + -r/console +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.reporterNames[0] == "console" ) +with expansion: + "console" == "console" + +------------------------------------------------------------------------------- +Process can be configured on command line + reporter + -r/xml +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.reporterNames[0] == "xml" ) +with expansion: + "xml" == "xml" + +------------------------------------------------------------------------------- +Process can be configured on command line + reporter + -r xml and junit +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.reporterNames.size() == 2 ) +with expansion: + 2 == 2 + +TestMain.cpp:: +PASSED: + REQUIRE( config.reporterNames[0] == "xml" ) +with expansion: + "xml" == "xml" + +TestMain.cpp:: +PASSED: + REQUIRE( config.reporterNames[1] == "junit" ) +with expansion: + "junit" == "junit" + +------------------------------------------------------------------------------- +Process can be configured on command line + reporter + --reporter/junit +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.reporterNames[0] == "junit" ) +with expansion: + "junit" == "junit" + +------------------------------------------------------------------------------- +Process can be configured on command line + debugger + -b +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.shouldDebugBreak == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Process can be configured on command line + debugger + --break +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.shouldDebugBreak ) +with expansion: + true + +------------------------------------------------------------------------------- +Process can be configured on command line + abort + -a aborts after first failure +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.abortAfter == 1 ) +with expansion: + 1 == 1 + +------------------------------------------------------------------------------- +Process can be configured on command line + abort + -x 2 aborts after two failures +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.abortAfter == 2 ) +with expansion: + 2 == 2 + +------------------------------------------------------------------------------- +Process can be configured on command line + abort + -x must be greater than zero +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "greater than zero" ) ) +with expansion: + "Value after -x or --abortAfter must be greater than zero + - while parsing: (-x, --abortx )" contains: "greater than zero" + +------------------------------------------------------------------------------- +Process can be configured on command line + abort + -x must be numeric +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) ) +with expansion: + "Unable to convert oops to destination type + - while parsing: (-x, --abortx )" contains: "-x" + +------------------------------------------------------------------------------- +Process can be configured on command line + nothrow + -e +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.noThrow == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Process can be configured on command line + nothrow + --nothrow +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.noThrow == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Process can be configured on command line + output filename + -o filename +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.outputFilename == "filename.ext" ) +with expansion: + "filename.ext" == "filename.ext" + +------------------------------------------------------------------------------- +Process can be configured on command line + output filename + --out +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.outputFilename == "filename.ext" ) +with expansion: + "filename.ext" == "filename.ext" + +------------------------------------------------------------------------------- +Process can be configured on command line + combinations + Single character flags can be combined +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + CHECK( config.abortAfter == 1 ) +with expansion: + 1 == 1 + +TestMain.cpp:: +PASSED: + CHECK( config.shouldDebugBreak ) +with expansion: + true + +TestMain.cpp:: +PASSED: + CHECK( config.noThrow == true ) +with expansion: + true == true + +------------------------------------------------------------------------------- +Process can be configured on command line + use-colour + without option +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.useColour == UseColour::Auto ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +Process can be configured on command line + use-colour + auto +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.useColour == UseColour::Auto ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +Process can be configured on command line + use-colour + yes +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.useColour == UseColour::Yes ) +with expansion: + 1 == 1 + +------------------------------------------------------------------------------- +Process can be configured on command line + use-colour + no +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_NOTHROW( parseIntoConfig( argv, config ) ) + +TestMain.cpp:: +PASSED: + REQUIRE( config.useColour == UseColour::No ) +with expansion: + 2 == 2 + +------------------------------------------------------------------------------- +Process can be configured on command line + use-colour + error +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + REQUIRE_THROWS_WITH( parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) ) + +------------------------------------------------------------------------------- +SCOPED_INFO is reset for each loop +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: +PASSED: + REQUIRE( i < 10 ) +with expansion: + 0 < 10 +with messages: + current counter 0 + i := 0 + +MessageTests.cpp:: +PASSED: + REQUIRE( i < 10 ) +with expansion: + 1 < 10 +with messages: + current counter 1 + i := 1 + +MessageTests.cpp:: +PASSED: + REQUIRE( i < 10 ) +with expansion: + 2 < 10 +with messages: + current counter 2 + i := 2 + +MessageTests.cpp:: +PASSED: + REQUIRE( i < 10 ) +with expansion: + 3 < 10 +with messages: + current counter 3 + i := 3 + +MessageTests.cpp:: +PASSED: + REQUIRE( i < 10 ) +with expansion: + 4 < 10 +with messages: + current counter 4 + i := 4 + +MessageTests.cpp:: +PASSED: + REQUIRE( i < 10 ) +with expansion: + 5 < 10 +with messages: + current counter 5 + i := 5 + +MessageTests.cpp:: +PASSED: + REQUIRE( i < 10 ) +with expansion: + 6 < 10 +with messages: + current counter 6 + i := 6 + +MessageTests.cpp:: +PASSED: + REQUIRE( i < 10 ) +with expansion: + 7 < 10 +with messages: + current counter 7 + i := 7 + +MessageTests.cpp:: +PASSED: + REQUIRE( i < 10 ) +with expansion: + 8 < 10 +with messages: + current counter 8 + i := 8 + +MessageTests.cpp:: +PASSED: + REQUIRE( i < 10 ) +with expansion: + 9 < 10 +with messages: + current counter 9 + i := 9 + +MessageTests.cpp:: FAILED: + REQUIRE( i < 10 ) +with expansion: + 10 < 10 +with messages: + current counter 10 + i := 10 + +------------------------------------------------------------------------------- +SUCCEED counts as a test pass +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: +PASSED: +with message: + this is a success + +------------------------------------------------------------------------------- +SUCCESS does not require an argument +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or + methods + Given: No operations precede me +------------------------------------------------------------------------------- +BDDTests.cpp: +............................................................................... + +BDDTests.cpp:: +PASSED: + REQUIRE( before == 0 ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or + methods + Given: No operations precede me + When: We get the count + Then: Subsequently values are higher +------------------------------------------------------------------------------- +BDDTests.cpp: +............................................................................... + +BDDTests.cpp:: +PASSED: + REQUIRE( after > before ) +with expansion: + 1 > 0 + +------------------------------------------------------------------------------- +Scenario: Do that thing with the thing + Given: This stuff exists + When: I do this + Then: it should do this +------------------------------------------------------------------------------- +BDDTests.cpp: +............................................................................... + +BDDTests.cpp:: +PASSED: + REQUIRE( itDoesThis() ) +with expansion: + true + +------------------------------------------------------------------------------- +Scenario: Do that thing with the thing + Given: This stuff exists + When: I do this + Then: it should do this + And: do that +------------------------------------------------------------------------------- +BDDTests.cpp: +............................................................................... + +BDDTests.cpp:: +PASSED: + REQUIRE( itDoesThat() ) +with expansion: + true + +------------------------------------------------------------------------------- +Scenario: This is a really long scenario name to see how the list command deals + with wrapping + Given: A section name that is so long that it cannot fit in a single + console width + When: The test headers are printed as part of the normal running of the + scenario + Then: The, deliberately very long and overly verbose (you see what I did + there?) section names must wrap, along with an indent +------------------------------------------------------------------------------- +BDDTests.cpp: +............................................................................... + +BDDTests.cpp:: +PASSED: +with message: + boo! + +------------------------------------------------------------------------------- +Scenario: Vector resizing affects size and capacity + Given: an empty vector +------------------------------------------------------------------------------- +BDDTests.cpp: +............................................................................... + +BDDTests.cpp:: +PASSED: + REQUIRE( v.size() == 0 ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +Scenario: Vector resizing affects size and capacity + Given: an empty vector + When: it is made larger + Then: the size and capacity go up +------------------------------------------------------------------------------- +BDDTests.cpp: +............................................................................... + +BDDTests.cpp:: +PASSED: + REQUIRE( v.size() == 10 ) +with expansion: + 10 == 10 + +BDDTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +Scenario: Vector resizing affects size and capacity + Given: an empty vector + When: it is made larger + Then: the size and capacity go up + And when: it is made smaller again + Then: the size goes down but the capacity stays the same +------------------------------------------------------------------------------- +BDDTests.cpp: +............................................................................... + +BDDTests.cpp:: +PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +BDDTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +Scenario: Vector resizing affects size and capacity + Given: an empty vector +------------------------------------------------------------------------------- +BDDTests.cpp: +............................................................................... + +BDDTests.cpp:: +PASSED: + REQUIRE( v.size() == 0 ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +Scenario: Vector resizing affects size and capacity + Given: an empty vector + When: we reserve more space + Then: The capacity is increased but the size remains the same +------------------------------------------------------------------------------- +BDDTests.cpp: +............................................................................... + +BDDTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +BDDTests.cpp:: +PASSED: + REQUIRE( v.size() == 0 ) +with expansion: + 0 == 0 + +A string sent directly to stdout +A string sent directly to stderr +------------------------------------------------------------------------------- +Some simple comparisons between doubles +------------------------------------------------------------------------------- +ApproxTests.cpp: +............................................................................... + +ApproxTests.cpp:: +PASSED: + REQUIRE( d == Approx( 1.23 ) ) +with expansion: + 1.23 == Approx( 1.23 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( d != Approx( 1.22 ) ) +with expansion: + 1.23 != Approx( 1.22 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( d != Approx( 1.24 ) ) +with expansion: + 1.23 != Approx( 1.24 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( Approx( d ) == 1.23 ) +with expansion: + Approx( 1.23 ) == 1.23 + +ApproxTests.cpp:: +PASSED: + REQUIRE( Approx( d ) != 1.22 ) +with expansion: + Approx( 1.23 ) != 1.22 + +ApproxTests.cpp:: +PASSED: + REQUIRE( Approx( d ) != 1.24 ) +with expansion: + Approx( 1.23 ) != 1.24 + +Message from section one +------------------------------------------------------------------------------- +Standard output from all sections is reported + one +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + + +No assertions in section 'one' + +Message from section two +------------------------------------------------------------------------------- +Standard output from all sections is reported + two +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + + +No assertions in section 'two' + +------------------------------------------------------------------------------- +StartsWith string matcher +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( testStringForMatching(), StartsWith( "string" ) ) +with expansion: + "this string contains 'abc' as a substring" starts with: "string" + +------------------------------------------------------------------------------- +String matchers +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + REQUIRE_THAT( testStringForMatching(), Contains( "string" ) ) +with expansion: + "this string contains 'abc' as a substring" contains: "string" + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), Contains( "abc" ) ) +with expansion: + "this string contains 'abc' as a substring" contains: "abc" + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), StartsWith( "this" ) ) +with expansion: + "this string contains 'abc' as a substring" starts with: "this" + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) ) +with expansion: + "this string contains 'abc' as a substring" ends with: "substring" + +hello +hello +------------------------------------------------------------------------------- +Tabs and newlines show in output +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + CHECK( s1 == s2 ) +with expansion: + "if ($b == 10) { + $a = 20; + }" + == + "if ($b == 10) { + $a = 20; + } + " + +------------------------------------------------------------------------------- +Tag alias can be registered against tag patterns + The same tag alias can only be registered once +------------------------------------------------------------------------------- +TagAliasTests.cpp: +............................................................................... + +TagAliasTests.cpp:: +PASSED: + CHECK_THAT( what, Contains( "[@zzz]" ) ) +with expansion: + "error: tag alias, "[@zzz]" already registered. + First seen at file:2 + Redefined at file:10" contains: "[@zzz]" + +TagAliasTests.cpp:: +PASSED: + CHECK_THAT( what, Contains( "file" ) ) +with expansion: + "error: tag alias, "[@zzz]" already registered. + First seen at file:2 + Redefined at file:10" contains: "file" + +TagAliasTests.cpp:: +PASSED: + CHECK_THAT( what, Contains( "2" ) ) +with expansion: + "error: tag alias, "[@zzz]" already registered. + First seen at file:2 + Redefined at file:10" contains: "2" + +TagAliasTests.cpp:: +PASSED: + CHECK_THAT( what, Contains( "10" ) ) +with expansion: + "error: tag alias, "[@zzz]" already registered. + First seen at file:2 + Redefined at file:10" contains: "10" + +------------------------------------------------------------------------------- +Tag alias can be registered against tag patterns + Tag aliases must be of the form [@name] +------------------------------------------------------------------------------- +TagAliasTests.cpp: +............................................................................... + +TagAliasTests.cpp:: +PASSED: + CHECK_THROWS( registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) ) + +TagAliasTests.cpp:: +PASSED: + CHECK_THROWS( registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) ) + +TagAliasTests.cpp:: +PASSED: + CHECK_THROWS( registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) ) + +TagAliasTests.cpp:: +PASSED: + CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) ) + +------------------------------------------------------------------------------- +Test case with one argument +------------------------------------------------------------------------------- +VariadicMacrosTests.cpp: +............................................................................... + +VariadicMacrosTests.cpp:: +PASSED: +with message: + no assertions + +------------------------------------------------------------------------------- +Test enum bit values +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( 0x == bit30and31 ) +with expansion: + 3221225472 (0x) == 3221225472 + +------------------------------------------------------------------------------- +Text can be formatted using the Text class +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( Text( "hi there" ).toString() == "hi there" ) +with expansion: + "hi there" == "hi there" + +TestMain.cpp:: +PASSED: + CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" ) +with expansion: + "hi + there" + == + "hi + there" + +------------------------------------------------------------------------------- +The NO_FAIL macro reports a failure but does not fail the test +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: +FAILED - but was ok: + CHECK_NOFAIL( 1 == 2 ) + +------------------------------------------------------------------------------- +This test 'should' fail but doesn't +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: +with message: + oops! + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + successfully close one section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isSuccessfullyCompleted() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + fail one section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + fail one section + re-enter after failed section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + fail one section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + fail one section + re-enter after failed section and find next section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another + Re-enter - skips S1 and enters S2 +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another + Re-enter - skips S1 and enters S2 + Successfully close S2 +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isSuccessfullyCompleted() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isSuccessfullyCompleted() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another + Re-enter - skips S1 and enters S2 +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another + Re-enter - skips S1 and enters S2 + fail S2 +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase3.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1c.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2c.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase3.isSuccessfullyCompleted() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + open a nested section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + start a generator +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.index() == 0 ) +with expansion: + 0 == 0 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + close outer section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + close outer section + Re-enter for second generation +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.index() == 1 ) +with expansion: + 1 == 1 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isComplete() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + start a generator +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.index() == 0 ) +with expansion: + 0 == 0 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + Start a new inner section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + Start a new inner section + Re-enter for second generation +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.index() == 1 ) +with expansion: + 1 == 1 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isComplete() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + start a generator +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.index() == 0 ) +with expansion: + 0 == 0 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + Fail an inner section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + Fail an inner section + Re-enter for second generation +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.index() == 0 ) +with expansion: + 0 == 0 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase3.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1c.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1c.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1c.index() == 1 ) +with expansion: + 1 == 1 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2c.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2c.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1c.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1c.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase3.isComplete() ) +with expansion: + true + +------------------------------------------------------------------------------- +Unexpected exceptions can be translated +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: +due to unexpected exception with message: + 3.14 + +------------------------------------------------------------------------------- +Use a custom approx +------------------------------------------------------------------------------- +ApproxTests.cpp: +............................................................................... + +ApproxTests.cpp:: +PASSED: + REQUIRE( d == approx( 1.23 ) ) +with expansion: + 1.23 == Approx( 1.23 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( d == approx( 1.22 ) ) +with expansion: + 1.23 == Approx( 1.22 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( d == approx( 1.24 ) ) +with expansion: + 1.23 == Approx( 1.24 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( d != approx( 1.25 ) ) +with expansion: + 1.23 != Approx( 1.25 ) + +ApproxTests.cpp:: +PASSED: + REQUIRE( approx( d ) == 1.23 ) +with expansion: + Approx( 1.23 ) == 1.23 + +ApproxTests.cpp:: +PASSED: + REQUIRE( approx( d ) == 1.22 ) +with expansion: + Approx( 1.23 ) == 1.22 + +ApproxTests.cpp:: +PASSED: + REQUIRE( approx( d ) == 1.24 ) +with expansion: + Approx( 1.23 ) == 1.24 + +ApproxTests.cpp:: +PASSED: + REQUIRE( approx( d ) != 1.25 ) +with expansion: + Approx( 1.23 ) != 1.25 + +------------------------------------------------------------------------------- +Variadic macros + Section with one argument +------------------------------------------------------------------------------- +VariadicMacrosTests.cpp: +............................................................................... + +VariadicMacrosTests.cpp:: +PASSED: +with message: + no assertions + +------------------------------------------------------------------------------- +Vector matchers + Contains (element) +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( v, VectorContains( 1 ) ) +with expansion: + { 1, 2, 3 } Contains: 1 + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( v, VectorContains( 2 ) ) +with expansion: + { 1, 2, 3 } Contains: 2 + +------------------------------------------------------------------------------- +Vector matchers + Contains (vector) +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( v, Contains( v2 ) ) +with expansion: + { 1, 2, 3 } Contains: { 1, 2 } + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( v, Contains( v2 ) ) +with expansion: + { 1, 2, 3 } Contains: { 1, 2, 3 } + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( v, Contains( empty) ) +with expansion: + { 1, 2, 3 } Contains: { } + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( empty, Contains( empty) ) +with expansion: + { } Contains: { } + +------------------------------------------------------------------------------- +Vector matchers + Equals +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( v, Equals( v ) ) +with expansion: + { 1, 2, 3 } Equals: { 1, 2, 3 } + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( empty, Equals( empty ) ) +with expansion: + { } Equals: { } + +MatchersTests.cpp:: +PASSED: + CHECK_THAT( v, Equals( v2 ) ) +with expansion: + { 1, 2, 3 } Equals: { 1, 2, 3 } + +------------------------------------------------------------------------------- +Vector matchers that fail + Contains (element) +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( v, VectorContains( -1 ) ) +with expansion: + { 1, 2, 3 } Contains: -1 + +MatchersTests.cpp:: FAILED: + CHECK_THAT( empty, VectorContains( 1 ) ) +with expansion: + { } Contains: 1 + +------------------------------------------------------------------------------- +Vector matchers that fail + Contains (vector) +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( empty, Contains( v) ) +with expansion: + { } Contains: { 1, 2, 3 } + +MatchersTests.cpp:: FAILED: + CHECK_THAT( v, Contains( v2 ) ) +with expansion: + { 1, 2, 3 } Contains: { 1, 2, 4 } + +------------------------------------------------------------------------------- +Vector matchers that fail + Equals +------------------------------------------------------------------------------- +MatchersTests.cpp: +............................................................................... + +MatchersTests.cpp:: FAILED: + CHECK_THAT( v, Equals( v2 ) ) +with expansion: + { 1, 2, 3 } Equals: { 1, 2 } + +MatchersTests.cpp:: FAILED: + CHECK_THAT( v2, Equals( v ) ) +with expansion: + { 1, 2 } Equals: { 1, 2, 3 } + +MatchersTests.cpp:: FAILED: + CHECK_THAT( empty, Equals( v ) ) +with expansion: + { } Equals: { 1, 2, 3 } + +MatchersTests.cpp:: FAILED: + CHECK_THAT( v, Equals( empty ) ) +with expansion: + { 1, 2, 3 } Equals: { } + +------------------------------------------------------------------------------- +When checked exceptions are thrown they can be expected or unexpected +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: +PASSED: + REQUIRE_THROWS_AS( thisThrows(), std::domain_error ) + +ExceptionTests.cpp:: +PASSED: + REQUIRE_NOTHROW( thisDoesntThrow() ) + +ExceptionTests.cpp:: +PASSED: + REQUIRE_THROWS( thisThrows() ) + +------------------------------------------------------------------------------- +When unchecked exceptions are thrown directly they are always failures +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: +due to unexpected exception with message: + unexpected exception + +------------------------------------------------------------------------------- +When unchecked exceptions are thrown during a CHECK the test should continue +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + CHECK( thisThrows() == 0 ) +due to unexpected exception with message: + expected exception + +------------------------------------------------------------------------------- +When unchecked exceptions are thrown during a REQUIRE the test should abort +fail +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + REQUIRE( thisThrows() == 0 ) +due to unexpected exception with message: + expected exception + +------------------------------------------------------------------------------- +When unchecked exceptions are thrown from functions they are always failures +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: + CHECK( thisThrows() == 0 ) +due to unexpected exception with message: + expected exception + +------------------------------------------------------------------------------- +When unchecked exceptions are thrown from sections they are always failures + section name +------------------------------------------------------------------------------- +ExceptionTests.cpp: +............................................................................... + +ExceptionTests.cpp:: FAILED: +due to unexpected exception with message: + unexpected exception + +------------------------------------------------------------------------------- +Where the LHS is not a simple value +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +warning: + Uncomment the code in this test to check that it gives a sensible compiler + error + +------------------------------------------------------------------------------- +Where there is more to the expression after the RHS +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +warning: + Uncomment the code in this test to check that it gives a sensible compiler + error + +------------------------------------------------------------------------------- +X/level/0/a +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +X/level/0/b +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +X/level/1/a +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +X/level/1/b +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +XmlEncode + normal string +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( encode( "normal string" ) == "normal string" ) +with expansion: + "normal string" == "normal string" + +------------------------------------------------------------------------------- +XmlEncode + empty string +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( encode( "" ) == "" ) +with expansion: + "" == "" + +------------------------------------------------------------------------------- +XmlEncode + string with ampersand +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( encode( "smith & jones" ) == "smith & jones" ) +with expansion: + "smith & jones" == "smith & jones" + +------------------------------------------------------------------------------- +XmlEncode + string with less-than +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( encode( "smith < jones" ) == "smith < jones" ) +with expansion: + "smith < jones" == "smith < jones" + +------------------------------------------------------------------------------- +XmlEncode + string with greater-than +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( encode( "smith > jones" ) == "smith > jones" ) +with expansion: + "smith > jones" == "smith > jones" + +MiscTests.cpp:: +PASSED: + REQUIRE( encode( "smith ]]> jones" ) == "smith ]]> jones" ) +with expansion: + "smith ]]> jones" + == + "smith ]]> jones" + +------------------------------------------------------------------------------- +XmlEncode + string with quotes +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( encode( stringWithQuotes ) == stringWithQuotes ) +with expansion: + "don't "quote" me on that" + == + "don't "quote" me on that" + +MiscTests.cpp:: +PASSED: + REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't "quote" me on that" ) +with expansion: + "don't "quote" me on that" + == + "don't "quote" me on that" + +------------------------------------------------------------------------------- +XmlEncode + string with control char (1) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( encode( "[\x01]" ) == "[\\x01]" ) +with expansion: + "[\x01]" == "[\x01]" + +------------------------------------------------------------------------------- +XmlEncode + string with control char (x7F) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( encode( "[\x7F]" ) == "[\\x7F]" ) +with expansion: + "[\x7F]" == "[\x7F]" + +------------------------------------------------------------------------------- +atomic if +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( x == 0 ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +boolean member +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( obj.prop != 0 ) +with expansion: + 0x != 0 + +------------------------------------------------------------------------------- +checkedElse +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + CHECKED_ELSE( flag ) +with expansion: + true + +MiscTests.cpp:: +PASSED: + REQUIRE( testCheckedElse( true ) ) +with expansion: + true + +------------------------------------------------------------------------------- +checkedElse, failing +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + CHECKED_ELSE( flag ) +with expansion: + false + +MiscTests.cpp:: FAILED: + REQUIRE( testCheckedElse( false ) ) +with expansion: + false + +------------------------------------------------------------------------------- +checkedIf +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + CHECKED_IF( flag ) +with expansion: + true + +MiscTests.cpp:: +PASSED: + REQUIRE( testCheckedIf( true ) ) +with expansion: + true + +------------------------------------------------------------------------------- +checkedIf, failing +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + CHECKED_IF( flag ) +with expansion: + false + +MiscTests.cpp:: FAILED: + REQUIRE( testCheckedIf( false ) ) +with expansion: + false + +------------------------------------------------------------------------------- +comparisons between const int variables +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: +PASSED: + REQUIRE( unsigned_char_var == 1 ) +with expansion: + 1 == 1 + +ConditionTests.cpp:: +PASSED: + REQUIRE( unsigned_short_var == 1 ) +with expansion: + 1 == 1 + +ConditionTests.cpp:: +PASSED: + REQUIRE( unsigned_int_var == 1 ) +with expansion: + 1 == 1 + +ConditionTests.cpp:: +PASSED: + REQUIRE( unsigned_long_var == 1 ) +with expansion: + 1 == 1 + +------------------------------------------------------------------------------- +comparisons between int variables +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: +PASSED: + REQUIRE( long_var == unsigned_char_var ) +with expansion: + 1 == 1 + +ConditionTests.cpp:: +PASSED: + REQUIRE( long_var == unsigned_short_var ) +with expansion: + 1 == 1 + +ConditionTests.cpp:: +PASSED: + REQUIRE( long_var == unsigned_int_var ) +with expansion: + 1 == 1 + +ConditionTests.cpp:: +PASSED: + REQUIRE( long_var == unsigned_long_var ) +with expansion: + 1 == 1 + +------------------------------------------------------------------------------- +even more nested SECTION tests + c + d (leaf) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +even more nested SECTION tests + c + e (leaf) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +even more nested SECTION tests + f (leaf) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + +spanner------------------------------------------------------------------------------- +just failure +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: +explicitly with message: + Previous info should not be seen + +------------------------------------------------------------------------------- +looped SECTION tests + s1 +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + CHECK( b > a ) +with expansion: + 0 > 1 + +------------------------------------------------------------------------------- +looped tests +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[0] (1) is even + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[1] (1) is even + +MiscTests.cpp:: +PASSED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 0 == 0 +with message: + Testing if fib[2] (2) is even + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[3] (3) is even + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[4] (5) is even + +MiscTests.cpp:: +PASSED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 0 == 0 +with message: + Testing if fib[5] (8) is even + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[6] (13) is even + +MiscTests.cpp:: FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[7] (21) is even + +------------------------------------------------------------------------------- +more nested SECTION tests + s1 + s2 +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + REQUIRE( a == b ) +with expansion: + 1 == 2 + +------------------------------------------------------------------------------- +more nested SECTION tests + s1 + s3 +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( a != b ) +with expansion: + 1 != 2 + +------------------------------------------------------------------------------- +more nested SECTION tests + s1 + s4 +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( a < b ) +with expansion: + 1 < 2 + +------------------------------------------------------------------------------- +nested SECTION tests + s1 +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( a != b ) +with expansion: + 1 != 2 + +MiscTests.cpp:: +PASSED: + REQUIRE( b != a ) +with expansion: + 2 != 1 + +------------------------------------------------------------------------------- +nested SECTION tests + s1 + s2 +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( a != b ) +with expansion: + 1 != 2 + +------------------------------------------------------------------------------- +non streamable - with conv. op +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( s == "7" ) +with expansion: + "7" == "7" + +------------------------------------------------------------------------------- +not allowed +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +null strings +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( makeString( false ) != static_cast(0) ) +with expansion: + "valid string" != {null string} + +MiscTests.cpp:: +PASSED: + REQUIRE( makeString( true ) == static_cast(0) ) +with expansion: + {null string} == {null string} + +------------------------------------------------------------------------------- +pair > -> toString +------------------------------------------------------------------------------- +ToStringPair.cpp: +............................................................................... + +ToStringPair.cpp:: +PASSED: + REQUIRE( Catch::toString( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" ) +with expansion: + "{ { 42, "Arthur" }, { "Ford", 24 } }" + == + "{ { 42, "Arthur" }, { "Ford", 24 } }" + +------------------------------------------------------------------------------- +pointer to class +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: +PASSED: + REQUIRE( p == 0 ) +with expansion: + NULL == 0 + +------------------------------------------------------------------------------- +random SECTION tests + s1 +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( a != b ) +with expansion: + 1 != 2 + +MiscTests.cpp:: +PASSED: + REQUIRE( b != a ) +with expansion: + 2 != 1 + +------------------------------------------------------------------------------- +random SECTION tests + s2 +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( a != b ) +with expansion: + 1 != 2 + +------------------------------------------------------------------------------- +replaceInPlace + replace single char +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( replaceInPlace( letters, "b", "z" ) ) +with expansion: + true + +TestMain.cpp:: +PASSED: + CHECK( letters == "azcdefcg" ) +with expansion: + "azcdefcg" == "azcdefcg" + +------------------------------------------------------------------------------- +replaceInPlace + replace two chars +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( replaceInPlace( letters, "c", "z" ) ) +with expansion: + true + +TestMain.cpp:: +PASSED: + CHECK( letters == "abzdefzg" ) +with expansion: + "abzdefzg" == "abzdefzg" + +------------------------------------------------------------------------------- +replaceInPlace + replace first char +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( replaceInPlace( letters, "a", "z" ) ) +with expansion: + true + +TestMain.cpp:: +PASSED: + CHECK( letters == "zbcdefcg" ) +with expansion: + "zbcdefcg" == "zbcdefcg" + +------------------------------------------------------------------------------- +replaceInPlace + replace last char +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( replaceInPlace( letters, "g", "z" ) ) +with expansion: + true + +TestMain.cpp:: +PASSED: + CHECK( letters == "abcdefcz" ) +with expansion: + "abcdefcz" == "abcdefcz" + +------------------------------------------------------------------------------- +replaceInPlace + replace all chars +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( replaceInPlace( letters, letters, "replaced" ) ) +with expansion: + true + +TestMain.cpp:: +PASSED: + CHECK( letters == "replaced" ) +with expansion: + "replaced" == "replaced" + +------------------------------------------------------------------------------- +replaceInPlace + replace no chars +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK_FALSE( replaceInPlace( letters, "x", "z" ) ) +with expansion: + !false + +TestMain.cpp:: +PASSED: + CHECK( letters == letters ) +with expansion: + "abcdefcg" == "abcdefcg" + +------------------------------------------------------------------------------- +replaceInPlace + escape ' +------------------------------------------------------------------------------- +TestMain.cpp: +............................................................................... + +TestMain.cpp:: +PASSED: + CHECK( replaceInPlace( s, "'", "|'" ) ) +with expansion: + true + +TestMain.cpp:: +PASSED: + CHECK( s == "didn|'t" ) +with expansion: + "didn|'t" == "didn|'t" + +------------------------------------------------------------------------------- +send a single char to INFO +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: FAILED: + REQUIRE( false ) +with message: + 3 + +------------------------------------------------------------------------------- +sends information to INFO +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + +MessageTests.cpp:: FAILED: + REQUIRE( false ) +with messages: + hi + i := 7 + +------------------------------------------------------------------------------- +std::pair -> toString +------------------------------------------------------------------------------- +ToStringPair.cpp: +............................................................................... + +ToStringPair.cpp:: +PASSED: + REQUIRE( Catch::toString(value) == "{ 34, \"xyzzy\" }" ) +with expansion: + "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }" + +------------------------------------------------------------------------------- +std::pair -> toString +------------------------------------------------------------------------------- +ToStringPair.cpp: +............................................................................... + +ToStringPair.cpp:: +PASSED: + REQUIRE( Catch::toString( value ) == "{ 34, \"xyzzy\" }" ) +with expansion: + "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }" + +------------------------------------------------------------------------------- +std::vector > -> toString +------------------------------------------------------------------------------- +ToStringPair.cpp: +............................................................................... + +ToStringPair.cpp:: +PASSED: + REQUIRE( Catch::toString( pr ) == "{ { \"green\", 55 } }" ) +with expansion: + "{ { "green", 55 } }" + == + "{ { "green", 55 } }" + +------------------------------------------------------------------------------- +string literals of different sizes can be compared +------------------------------------------------------------------------------- +TrickyTests.cpp: +............................................................................... + +TrickyTests.cpp:: FAILED: + REQUIRE( std::string( "first" ) == "second" ) +with expansion: + "first" == "second" + +------------------------------------------------------------------------------- +toString on const wchar_t const pointer returns the string contents +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + CHECK( result == "\"wide load\"" ) +with expansion: + ""wide load"" == ""wide load"" + +------------------------------------------------------------------------------- +toString on const wchar_t pointer returns the string contents +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + CHECK( result == "\"wide load\"" ) +with expansion: + ""wide load"" == ""wide load"" + +------------------------------------------------------------------------------- +toString on wchar_t const pointer returns the string contents +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + CHECK( result == "\"wide load\"" ) +with expansion: + ""wide load"" == ""wide load"" + +------------------------------------------------------------------------------- +toString on wchar_t returns the string contents +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + CHECK( result == "\"wide load\"" ) +with expansion: + ""wide load"" == ""wide load"" + +------------------------------------------------------------------------------- +toString( has_maker ) +------------------------------------------------------------------------------- +ToStringWhich.cpp: +............................................................................... + +ToStringWhich.cpp:: +PASSED: + REQUIRE( Catch::toString( item ) == "StringMaker" ) +with expansion: + "StringMaker" + == + "StringMaker" + +------------------------------------------------------------------------------- +toString( has_maker_and_toString ) +------------------------------------------------------------------------------- +ToStringWhich.cpp: +............................................................................... + +ToStringWhich.cpp:: +PASSED: + REQUIRE( Catch::toString( item ) == "toString( has_maker_and_toString )" ) +with expansion: + "toString( has_maker_and_toString )" + == + "toString( has_maker_and_toString )" + +------------------------------------------------------------------------------- +toString( has_toString ) +------------------------------------------------------------------------------- +ToStringWhich.cpp: +............................................................................... + +ToStringWhich.cpp:: +PASSED: + REQUIRE( Catch::toString( item ) == "toString( has_toString )" ) +with expansion: + "toString( has_toString )" + == + "toString( has_toString )" + +------------------------------------------------------------------------------- +toString( vectors +............................................................................... + +ToStringWhich.cpp:: +PASSED: + REQUIRE( Catch::toString( v ) == "{ StringMaker }" ) +with expansion: + "{ StringMaker }" + == + "{ StringMaker }" + +------------------------------------------------------------------------------- +toString(enum w/operator<<) +------------------------------------------------------------------------------- +EnumToString.cpp: +............................................................................... + +EnumToString.cpp:: +PASSED: + CHECK( Catch::toString(e0) == "E2{0}" ) +with expansion: + "E2{0}" == "E2{0}" + +EnumToString.cpp:: +PASSED: + CHECK( Catch::toString(e1) == "E2{1}" ) +with expansion: + "E2{1}" == "E2{1}" + +------------------------------------------------------------------------------- +toString(enum) +------------------------------------------------------------------------------- +EnumToString.cpp: +............................................................................... + +EnumToString.cpp:: +PASSED: + CHECK( Catch::toString(e0) == "0" ) +with expansion: + "0" == "0" + +EnumToString.cpp:: +PASSED: + CHECK( Catch::toString(e1) == "1" ) +with expansion: + "1" == "1" + +------------------------------------------------------------------------------- +vector -> toString +------------------------------------------------------------------------------- +ToStringVector.cpp: +............................................................................... + +ToStringVector.cpp:: +PASSED: + REQUIRE( Catch::toString(vv) == "{ }" ) +with expansion: + "{ }" == "{ }" + +ToStringVector.cpp:: +PASSED: + REQUIRE( Catch::toString(vv) == "{ 42 }" ) +with expansion: + "{ 42 }" == "{ 42 }" + +ToStringVector.cpp:: +PASSED: + REQUIRE( Catch::toString(vv) == "{ 42, 250 }" ) +with expansion: + "{ 42, 250 }" == "{ 42, 250 }" + +------------------------------------------------------------------------------- +vector -> toString +------------------------------------------------------------------------------- +ToStringVector.cpp: +............................................................................... + +ToStringVector.cpp:: +PASSED: + REQUIRE( Catch::toString(vv) == "{ }" ) +with expansion: + "{ }" == "{ }" + +ToStringVector.cpp:: +PASSED: + REQUIRE( Catch::toString(vv) == "{ \"hello\" }" ) +with expansion: + "{ "hello" }" == "{ "hello" }" + +ToStringVector.cpp:: +PASSED: + REQUIRE( Catch::toString(vv) == "{ \"hello\", \"world\" }" ) +with expansion: + "{ "hello", "world" }" + == + "{ "hello", "world" }" + +------------------------------------------------------------------------------- +vectors can be sized and resized +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +MiscTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +vectors can be sized and resized + resizing bigger changes size and capacity +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( v.size() == 10 ) +with expansion: + 10 == 10 + +MiscTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +vectors can be sized and resized +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +MiscTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +vectors can be sized and resized + resizing smaller changes size but not capacity +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( v.size() == 0 ) +with expansion: + 0 == 0 + +MiscTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +vectors can be sized and resized + resizing smaller changes size but not capacity + We can use the 'swap trick' to reset the capacity +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( v.capacity() == 0 ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +vectors can be sized and resized +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +MiscTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +vectors can be sized and resized + reserving bigger changes capacity but not size +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +MiscTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +vectors can be sized and resized +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +MiscTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +vectors can be sized and resized + reserving smaller does not change size or capacity +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +MiscTests.cpp:: +PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +xmlentitycheck + embedded xml +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +xmlentitycheck + encoded chars +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + +=============================================================================== +test cases: 164 | 118 passed | 44 failed | 2 failed as expected +assertions: 957 | 851 passed | 88 failed | 18 failed as expected + diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/console.swa4.approved.txt b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/console.swa4.approved.txt new file mode 100644 index 0000000..098c33d --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/console.swa4.approved.txt @@ -0,0 +1,74 @@ + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + is a host application. +Run with -? for options + +------------------------------------------------------------------------------- +# A test name that starts with a # +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: +with message: + yay + +------------------------------------------------------------------------------- +#542 +------------------------------------------------------------------------------- +CompilationTests.cpp: +............................................................................... + +CompilationTests.cpp:: +PASSED: + CHECK_THROWS_AS( throws_int(true), int ) + +CompilationTests.cpp:: +PASSED: + CHECK_THROWS_AS( throws_int(true), int& ) + +CompilationTests.cpp:: +PASSED: + CHECK_THROWS_AS( throws_int(true), const int ) + +CompilationTests.cpp:: +PASSED: + CHECK_THROWS_AS( throws_int(true), const int& ) + +------------------------------------------------------------------------------- +#809 +------------------------------------------------------------------------------- +CompilationTests.cpp: +............................................................................... + +CompilationTests.cpp:: +PASSED: + REQUIRE( 42 == f ) +with expansion: + 42 == {?} + +------------------------------------------------------------------------------- +'Not' checks that should fail +------------------------------------------------------------------------------- +ConditionTests.cpp: +............................................................................... + +ConditionTests.cpp:: FAILED: + CHECK( false != false ) + +ConditionTests.cpp:: FAILED: + CHECK( true != true ) + +ConditionTests.cpp:: FAILED: + CHECK( !true ) +with expansion: + false + +ConditionTests.cpp:: FAILED: + CHECK_FALSE( true ) + +=============================================================================== +test cases: 4 | 3 passed | 1 failed +assertions: 10 | 6 passed | 4 failed + diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/junit.sw.approved.txt b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/junit.sw.approved.txt new file mode 100644 index 0000000..41cfb46 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/junit.sw.approved.txt @@ -0,0 +1,720 @@ + + + + + + + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + + + + + + + + + +ClassTests.cpp: + + + + + +ClassTests.cpp: + + + + + +to infinity and beyond +MiscTests.cpp: + + + + + +TrickyTests.cpp: + + +TrickyTests.cpp: + + + + + + + +unexpected exception +ExceptionTests.cpp: + + + + + + + + + + + + + + + + + + + + + + + + + +MatchersTests.cpp: + + + + +custom exception - not std +ExceptionTests.cpp: + + + + +custom exception - not std +ExceptionTests.cpp: + + + + +custom std exception +ExceptionTests.cpp: + + + + + +MatchersTests.cpp: + + + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + + + + + +MatchersTests.cpp: + + + + + + + +expected exception +ExceptionTests.cpp: + + +ExceptionTests.cpp: + + +expected exception +ExceptionTests.cpp: + + + + +This is a failure +MessageTests.cpp: + + + + +MessageTests.cpp: + + + + + + + + + +this message should be logged +so should this +MessageTests.cpp: + + + + +this message should be logged +MessageTests.cpp: + + +and this, but later +MessageTests.cpp: + + + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + + + + + + + + + + + + + + + + + + + + + + + + +MatchersTests.cpp: + + + + + +MatchersTests.cpp: + + + + +ExceptionTests.cpp: + + + + + +custom exception +ExceptionTests.cpp: + + + + + + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + +ConditionTests.cpp: + + + + + +Message from section one +MessageTests.cpp: + + + + +Message from section two +MessageTests.cpp: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +current counter 10 +i := 10 +MessageTests.cpp: + + + + + + + + + + + + + + + +A string sent directly to stdout + + +A string sent directly to stderr + + + + + +Message from section one +Message from section two + + + + +MatchersTests.cpp: + + + + + +hello +hello + + + + +MiscTests.cpp: + + + + + + + + + + + + + + + + + + + + + + + + + + + + +3.14 +ExceptionTests.cpp: + + + + + + + + + +MatchersTests.cpp: + + +MatchersTests.cpp: + + + + +MatchersTests.cpp: + + +MatchersTests.cpp: + + + + +MatchersTests.cpp: + + +MatchersTests.cpp: + + +MatchersTests.cpp: + + +MatchersTests.cpp: + + + + + +unexpected exception +ExceptionTests.cpp: + + + + +expected exception +ExceptionTests.cpp: + + + + +expected exception +ExceptionTests.cpp: + + + + +expected exception +ExceptionTests.cpp: + + + + +unexpected exception +ExceptionTests.cpp: + + + + + + + + + + + + + + + + + + + + + +MiscTests.cpp: + + +MiscTests.cpp: + + + + + +MiscTests.cpp: + + +MiscTests.cpp: + + + + + + + + + +Previous info should not be seen +MessageTests.cpp: + + + + +MiscTests.cpp: + + + + +Testing if fib[0] (1) is even +MiscTests.cpp: + + +Testing if fib[1] (1) is even +MiscTests.cpp: + + +Testing if fib[3] (3) is even +MiscTests.cpp: + + +Testing if fib[4] (5) is even +MiscTests.cpp: + + +Testing if fib[6] (13) is even +MiscTests.cpp: + + +Testing if fib[7] (21) is even +MiscTests.cpp: + + + + +MiscTests.cpp: + + + + + + + + + + + + + + + + + + + + + + +3 +MiscTests.cpp: + + + + +hi +i := 7 +MessageTests.cpp: + + + + + + + +TrickyTests.cpp: + + + + + + + + + + + + + + + + + + + + + + + +A string sent directly to stdout +Message from section one +Message from section two +hello +hello + + +A string sent directly to stderr + + + diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/xml.sw.approved.txt b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/xml.sw.approved.txt new file mode 100644 index 0000000..ab6ab08 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/Baselines/xml.sw.approved.txt @@ -0,0 +1,9994 @@ + + + + + + + + + + throws_int(true), int + + + throws_int(true), int + + + + + throws_int(true), int& + + + throws_int(true), int& + + + + + throws_int(true), const int + + + throws_int(true), const int + + + + + throws_int(true), const int& + + + throws_int(true), const int& + + + + + + + + 42 == f + + + 42 == {?} + + + + + + + + false != false + + + false != false + + + + + true != true + + + true != true + + + + + !true + + + false + + + + + !true + + + !true + + + + + !trueValue + + + false + + + + + !trueValue + + + !true + + + + + !(1 == 1) + + + false + + + + + !1 == 1 + + + !(1 == 1) + + + + + + + + false == false + + + false == false + + + + + true == true + + + true == true + + + + + !false + + + true + + + + + !false + + + !false + + + + + !falseValue + + + true + + + + + !falseValue + + + !false + + + + + !(1 == 2) + + + true + + + + + !1 == 2 + + + !(1 == 2) + + + + + +
+ + + is_true<true>::value == true + + + true == true + + + + + true == is_true<true>::value + + + true == true + + + +
+
+ + + is_true<false>::value == false + + + false == false + + + + + false == is_true<false>::value + + + false == false + + + +
+
+ + + !is_true<false>::value + + + true + + + +
+
+ + + !!is_true<true>::value + + + true + + + +
+
+ + + is_true<true>::value + + + true + + + + + !is_true<false>::value + + + !false + + + +
+ +
+ + + + s == "world" + + + "hello" == "world" + + + + + + + + s == "hello" + + + "hello" == "hello" + + + + + + + + m_a == 2 + + + 1 == 2 + + + + + + + + m_a == 1 + + + 1 == 1 + + + + + +
+
+ +
+ +
+ + to infinity and beyond + + +
+ + + + &o1 == &o2 + + + 0x == 0x + + + + + o1 == o2 + + + {?} == {?} + + + + + + + + 104.0 != Approx(100.0) + + + 104.0 != Approx( 100.0 ) + + + + + 104.0 == Approx(100.0).margin(5) + + + 104.0 == Approx( 100.0 ) + + + + + 104.0 != Approx(100.0).margin(3) + + + 104.0 != Approx( 100.0 ) + + + + + 100.3 != Approx(100.0) + + + 100.3 != Approx( 100.0 ) + + + + + 100.3 == Approx(100.0).margin(0.5) + + + 100.3 == Approx( 100.0 ) + + + + + + + + testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) + + + "this string contains 'abc' as a substring" ( contains: "string" and contains: "abc" ) + + + + + + + + + + + i++ == 7 + + + 7 == 7 + + + + + i++ == 8 + + + 8 == 8 + + + + + + + + 1 == 1 + + + 1 == 1 + + + + + {Unknown expression after the reported line} + + + {Unknown expression after the reported line} + + + unexpected exception + + + + + + + + + + + testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) + + + "this string contains 'abc' as a substring" ( contains: "string" or contains: "not there" ) + + + + + testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) + + + "this string contains 'abc' as a substring" ( contains: "not there" or contains: "string" ) + + + + + + + + divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) + + + 3.1428571429 == Approx( 3.141 ) + + + + + divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) + + + 3.1428571429 != Approx( 3.141 ) + + + + + + + + d != Approx( 1.231 ) + + + 1.23 != Approx( 1.231 ) + + + + + d == Approx( 1.231 ).epsilon( 0.1 ) + + + 1.23 == Approx( 1.231 ) + + + + + + + + 1.23f == Approx( 1.23f ) + + + 1.23f == Approx( 1.2300000191 ) + + + + + 0.0f == Approx( 0.0f ) + + + 0.0f == Approx( 0.0 ) + + + + + + + + 1 == Approx( 1 ) + + + 1 == Approx( 1.0 ) + + + + + 0 == Approx( 0 ) + + + 0 == Approx( 0.0 ) + + + + + + + + 1.0f == Approx( 1 ) + + + 1.0f == Approx( 1.0 ) + + + + + 0 == Approx( dZero) + + + 0 == Approx( 0.0 ) + + + + + 0 == Approx( dSmall ).epsilon( 0.001 ) + + + 0 == Approx( 0.00001 ) + + + + + 1.234f == Approx( dMedium ) + + + 1.234f == Approx( 1.234 ) + + + + + dMedium == Approx( 1.234f ) + + + 1.234 == Approx( 1.2339999676 ) + + + + + + + + Catch::alwaysTrue() + + + true + + +
+ + + Catch::alwaysTrue() + + + true + + +
+ + + Catch::alwaysTrue() + + + true + + + +
+ +
+ + + Catch::alwaysTrue() + + + true + + +
+ + + Catch::alwaysTrue() + + + true + + +
+ + + Catch::alwaysTrue() + + + true + + + +
+ +
+ +
+ +
+ + i := 2 + + + + true + + + true + + + +
+
+ + 3 + + + + true + + + true + + + +
+ +
+ +
+ + + tab == '\t' + + + '\t' == '\t' + + + + + newline == '\n' + + + '\n' == '\n' + + + + + carr_return == '\r' + + + '\r' == '\r' + + + + + form_feed == '\f' + + + '\f' == '\f' + + + +
+
+ + + space == ' ' + + + ' ' == ' ' + + + + + c == chars[i] + + + 'a' == 'a' + + + + + c == chars[i] + + + 'z' == 'z' + + + + + c == chars[i] + + + 'A' == 'A' + + + + + c == chars[i] + + + 'Z' == 'Z' + + + +
+
+ + + null_terminator == '\0' + + + 0 == 0 + + + + + c == i + + + 2 == 2 + + + + + c == i + + + 3 == 3 + + + + + c == i + + + 4 == 4 + + + + + c == i + + + 5 == 5 + + + +
+ +
+ + + + a + + + true + + + + + a == &foo + + + 0x == 0x + + + + + + + + m == &S::f + + + 0x +== +0x + + + + + + + + 54 == 6*9 + + + 54 == 54 + + + + + + + + ( -1 > 2u ) + + + true + + + + + -1 > 2u + + + -1 > 2 + + + + + ( 2u < -1 ) + + + true + + + + + 2u < -1 + + + 2 < -1 + + + + + ( minInt > 2u ) + + + true + + + + + minInt > 2u + + + -2147483648 > 2 + + + + + + + + i == 1 + + + 1 == 1 + + + + + ui == 2 + + + 2 == 2 + + + + + l == 3 + + + 3 == 3 + + + + + ul == 4 + + + 4 == 4 + + + + + c == 5 + + + 5 == 5 + + + + + uc == 6 + + + 6 == 6 + + + + + 1 == i + + + 1 == 1 + + + + + 2 == ui + + + 2 == 2 + + + + + 3 == l + + + 3 == 3 + + + + + 4 == ul + + + 4 == 4 + + + + + 5 == c + + + 5 == 5 + + + + + 6 == uc + + + 6 == 6 + + + + + (std::numeric_limits<unsigned long>::max)() > ul + + + 18446744073709551615 (0x) +> +4 + + + + + + + + testStringForMatching(), Contains( "not there" ) + + + "this string contains 'abc' as a substring" contains: "not there" + + + + + + + + throwCustom() + + + throwCustom() + + + custom exception - not std + + + + + + + + throwCustom(), std::exception + + + throwCustom(), std::exception + + + custom exception - not std + + + + + + + custom std exception + + + + + + + t == 1u + + + {?} == 1 + + + + + + + + testStringForMatching(), EndsWith( "this" ) + + + "this string contains 'abc' as a substring" ends with: "this" + + + + + + + + data.int_seven == 6 + + + 7 == 6 + + + + + data.int_seven == 8 + + + 7 == 8 + + + + + data.int_seven == 0 + + + 7 == 0 + + + + + data.float_nine_point_one == Approx( 9.11f ) + + + 9.1f == Approx( 9.1099996567 ) + + + + + data.float_nine_point_one == Approx( 9.0f ) + + + 9.1f == Approx( 9.0 ) + + + + + data.float_nine_point_one == Approx( 1 ) + + + 9.1f == Approx( 1.0 ) + + + + + data.float_nine_point_one == Approx( 0 ) + + + 9.1f == Approx( 0.0 ) + + + + + data.double_pi == Approx( 3.1415 ) + + + 3.1415926535 == Approx( 3.1415 ) + + + + + data.str_hello == "goodbye" + + + "hello" == "goodbye" + + + + + data.str_hello == "hell" + + + "hello" == "hell" + + + + + data.str_hello == "hello1" + + + "hello" == "hello1" + + + + + data.str_hello.size() == 6 + + + 5 == 6 + + + + + x == Approx( 1.301 ) + + + 1.3 == Approx( 1.301 ) + + + + + + + + data.int_seven == 7 + + + 7 == 7 + + + + + data.float_nine_point_one == Approx( 9.1f ) + + + 9.1f == Approx( 9.1000003815 ) + + + + + data.double_pi == Approx( 3.1415926535 ) + + + 3.1415926535 == Approx( 3.1415926535 ) + + + + + data.str_hello == "hello" + + + "hello" == "hello" + + + + + "hello" == data.str_hello + + + "hello" == "hello" + + + + + data.str_hello.size() == 5 + + + 5 == 5 + + + + + x == Approx( 1.3 ) + + + 1.3 == Approx( 1.3 ) + + + + + + + + testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) + + + "this string contains 'abc' as a substring" equals: "this string contains 'abc' as a substring" + + + + + + + + testStringForMatching(), Equals( "something else" ) + + + "this string contains 'abc' as a substring" equals: "something else" + + + + + +
+ + + thisThrows(), "expected exception" + + + thisThrows(), "expected exception" + + + +
+
+ + + thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) + + + thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) + + + +
+
+ + + thisThrows(), StartsWith( "expected" ) + + + thisThrows(), StartsWith( "expected" ) + + + + + thisThrows(), EndsWith( "exception" ) + + + thisThrows(), EndsWith( "exception" ) + + + + + thisThrows(), Contains( "except" ) + + + thisThrows(), Contains( "except" ) + + + + + thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) + + + thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) + + + +
+ +
+ + + + thisThrows(), std::string + + + thisThrows(), std::string + + + expected exception + + + + + thisDoesntThrow(), std::domain_error + + + thisDoesntThrow(), std::domain_error + + + + + thisThrows() + + + thisThrows() + + + expected exception + + + + + + + This is a failure + + + + + + + + + + + Factorial(0) == 1 + + + 1 == 1 + + + + + Factorial(1) == 1 + + + 1 == 1 + + + + + Factorial(2) == 2 + + + 2 == 2 + + + + + Factorial(3) == 6 + + + 6 == 6 + + + + + Factorial(10) == 3628800 + + + 3628800 (0x) == 3628800 (0x) + + + + + + + + i->first == i->second-1 + + + 0 == 0 + + + + + i->first == i->second-1 + + + 2 == 2 + + + + + + + + multiply( i, 2 ) == i*2 + + + 2 == 2 + + + + + multiply( j, 2 ) == j*2 + + + 200 == 200 + + + + + multiply( i, 2 ) == i*2 + + + 4 == 4 + + + + + multiply( j, 2 ) == j*2 + + + 200 == 200 + + + + + multiply( i, 2 ) == i*2 + + + 6 == 6 + + + + + multiply( j, 2 ) == j*2 + + + 200 == 200 + + + + + multiply( i, 2 ) == i*2 + + + 8 == 8 + + + + + multiply( j, 2 ) == j*2 + + + 200 == 200 + + + + + multiply( i, 2 ) == i*2 + + + 10 == 10 + + + + + multiply( j, 2 ) == j*2 + + + 200 == 200 + + + + + multiply( i, 2 ) == i*2 + + + 30 == 30 + + + + + multiply( j, 2 ) == j*2 + + + 200 == 200 + + + + + multiply( i, 2 ) == i*2 + + + 40 == 40 + + + + + multiply( j, 2 ) == j*2 + + + 200 == 200 + + + + + multiply( i, 2 ) == i*2 + + + 42 == 42 + + + + + multiply( j, 2 ) == j*2 + + + 200 == 200 + + + + + multiply( i, 2 ) == i*2 + + + 72 == 72 + + + + + multiply( j, 2 ) == j*2 + + + 200 == 200 + + + + + multiply( i, 2 ) == i*2 + + + 2 == 2 + + + + + multiply( j, 2 ) == j*2 + + + 202 == 202 + + + + + multiply( i, 2 ) == i*2 + + + 4 == 4 + + + + + multiply( j, 2 ) == j*2 + + + 202 == 202 + + + + + multiply( i, 2 ) == i*2 + + + 6 == 6 + + + + + multiply( j, 2 ) == j*2 + + + 202 == 202 + + + + + multiply( i, 2 ) == i*2 + + + 8 == 8 + + + + + multiply( j, 2 ) == j*2 + + + 202 == 202 + + + + + multiply( i, 2 ) == i*2 + + + 10 == 10 + + + + + multiply( j, 2 ) == j*2 + + + 202 == 202 + + + + + multiply( i, 2 ) == i*2 + + + 30 == 30 + + + + + multiply( j, 2 ) == j*2 + + + 202 == 202 + + + + + multiply( i, 2 ) == i*2 + + + 40 == 40 + + + + + multiply( j, 2 ) == j*2 + + + 202 == 202 + + + + + multiply( i, 2 ) == i*2 + + + 42 == 42 + + + + + multiply( j, 2 ) == j*2 + + + 202 == 202 + + + + + multiply( i, 2 ) == i*2 + + + 72 == 72 + + + + + multiply( j, 2 ) == j*2 + + + 202 == 202 + + + + + multiply( i, 2 ) == i*2 + + + 2 == 2 + + + + + multiply( j, 2 ) == j*2 + + + 204 == 204 + + + + + multiply( i, 2 ) == i*2 + + + 4 == 4 + + + + + multiply( j, 2 ) == j*2 + + + 204 == 204 + + + + + multiply( i, 2 ) == i*2 + + + 6 == 6 + + + + + multiply( j, 2 ) == j*2 + + + 204 == 204 + + + + + multiply( i, 2 ) == i*2 + + + 8 == 8 + + + + + multiply( j, 2 ) == j*2 + + + 204 == 204 + + + + + multiply( i, 2 ) == i*2 + + + 10 == 10 + + + + + multiply( j, 2 ) == j*2 + + + 204 == 204 + + + + + multiply( i, 2 ) == i*2 + + + 30 == 30 + + + + + multiply( j, 2 ) == j*2 + + + 204 == 204 + + + + + multiply( i, 2 ) == i*2 + + + 40 == 40 + + + + + multiply( j, 2 ) == j*2 + + + 204 == 204 + + + + + multiply( i, 2 ) == i*2 + + + 42 == 42 + + + + + multiply( j, 2 ) == j*2 + + + 204 == 204 + + + + + multiply( i, 2 ) == i*2 + + + 72 == 72 + + + + + multiply( j, 2 ) == j*2 + + + 204 == 204 + + + + + multiply( i, 2 ) == i*2 + + + 2 == 2 + + + + + multiply( j, 2 ) == j*2 + + + 206 == 206 + + + + + multiply( i, 2 ) == i*2 + + + 4 == 4 + + + + + multiply( j, 2 ) == j*2 + + + 206 == 206 + + + + + multiply( i, 2 ) == i*2 + + + 6 == 6 + + + + + multiply( j, 2 ) == j*2 + + + 206 == 206 + + + + + multiply( i, 2 ) == i*2 + + + 8 == 8 + + + + + multiply( j, 2 ) == j*2 + + + 206 == 206 + + + + + multiply( i, 2 ) == i*2 + + + 10 == 10 + + + + + multiply( j, 2 ) == j*2 + + + 206 == 206 + + + + + multiply( i, 2 ) == i*2 + + + 30 == 30 + + + + + multiply( j, 2 ) == j*2 + + + 206 == 206 + + + + + multiply( i, 2 ) == i*2 + + + 40 == 40 + + + + + multiply( j, 2 ) == j*2 + + + 206 == 206 + + + + + multiply( i, 2 ) == i*2 + + + 42 == 42 + + + + + multiply( j, 2 ) == j*2 + + + 206 == 206 + + + + + multiply( i, 2 ) == i*2 + + + 72 == 72 + + + + + multiply( j, 2 ) == j*2 + + + 206 == 206 + + + + + multiply( i, 2 ) == i*2 + + + 2 == 2 + + + + + multiply( j, 2 ) == j*2 + + + 208 == 208 + + + + + multiply( i, 2 ) == i*2 + + + 4 == 4 + + + + + multiply( j, 2 ) == j*2 + + + 208 == 208 + + + + + multiply( i, 2 ) == i*2 + + + 6 == 6 + + + + + multiply( j, 2 ) == j*2 + + + 208 == 208 + + + + + multiply( i, 2 ) == i*2 + + + 8 == 8 + + + + + multiply( j, 2 ) == j*2 + + + 208 == 208 + + + + + multiply( i, 2 ) == i*2 + + + 10 == 10 + + + + + multiply( j, 2 ) == j*2 + + + 208 == 208 + + + + + multiply( i, 2 ) == i*2 + + + 30 == 30 + + + + + multiply( j, 2 ) == j*2 + + + 208 == 208 + + + + + multiply( i, 2 ) == i*2 + + + 40 == 40 + + + + + multiply( j, 2 ) == j*2 + + + 208 == 208 + + + + + multiply( i, 2 ) == i*2 + + + 42 == 42 + + + + + multiply( j, 2 ) == j*2 + + + 208 == 208 + + + + + multiply( i, 2 ) == i*2 + + + 72 == 72 + + + + + multiply( j, 2 ) == j*2 + + + 208 == 208 + + + + + multiply( i, 2 ) == i*2 + + + 2 == 2 + + + + + multiply( j, 2 ) == j*2 + + + 210 == 210 + + + + + multiply( i, 2 ) == i*2 + + + 4 == 4 + + + + + multiply( j, 2 ) == j*2 + + + 210 == 210 + + + + + multiply( i, 2 ) == i*2 + + + 6 == 6 + + + + + multiply( j, 2 ) == j*2 + + + 210 == 210 + + + + + multiply( i, 2 ) == i*2 + + + 8 == 8 + + + + + multiply( j, 2 ) == j*2 + + + 210 == 210 + + + + + multiply( i, 2 ) == i*2 + + + 10 == 10 + + + + + multiply( j, 2 ) == j*2 + + + 210 == 210 + + + + + multiply( i, 2 ) == i*2 + + + 30 == 30 + + + + + multiply( j, 2 ) == j*2 + + + 210 == 210 + + + + + multiply( i, 2 ) == i*2 + + + 40 == 40 + + + + + multiply( j, 2 ) == j*2 + + + 210 == 210 + + + + + multiply( i, 2 ) == i*2 + + + 42 == 42 + + + + + multiply( j, 2 ) == j*2 + + + 210 == 210 + + + + + multiply( i, 2 ) == i*2 + + + 72 == 72 + + + + + multiply( j, 2 ) == j*2 + + + 210 == 210 + + + + + multiply( i, 2 ) == i*2 + + + 2 == 2 + + + + + multiply( j, 2 ) == j*2 + + + 212 == 212 + + + + + multiply( i, 2 ) == i*2 + + + 4 == 4 + + + + + multiply( j, 2 ) == j*2 + + + 212 == 212 + + + + + multiply( i, 2 ) == i*2 + + + 6 == 6 + + + + + multiply( j, 2 ) == j*2 + + + 212 == 212 + + + + + multiply( i, 2 ) == i*2 + + + 8 == 8 + + + + + multiply( j, 2 ) == j*2 + + + 212 == 212 + + + + + multiply( i, 2 ) == i*2 + + + 10 == 10 + + + + + multiply( j, 2 ) == j*2 + + + 212 == 212 + + + + + multiply( i, 2 ) == i*2 + + + 30 == 30 + + + + + multiply( j, 2 ) == j*2 + + + 212 == 212 + + + + + multiply( i, 2 ) == i*2 + + + 40 == 40 + + + + + multiply( j, 2 ) == j*2 + + + 212 == 212 + + + + + multiply( i, 2 ) == i*2 + + + 42 == 42 + + + + + multiply( j, 2 ) == j*2 + + + 212 == 212 + + + + + multiply( i, 2 ) == i*2 + + + 72 == 72 + + + + + multiply( j, 2 ) == j*2 + + + 212 == 212 + + + + + multiply( i, 2 ) == i*2 + + + 2 == 2 + + + + + multiply( j, 2 ) == j*2 + + + 214 == 214 + + + + + multiply( i, 2 ) == i*2 + + + 4 == 4 + + + + + multiply( j, 2 ) == j*2 + + + 214 == 214 + + + + + multiply( i, 2 ) == i*2 + + + 6 == 6 + + + + + multiply( j, 2 ) == j*2 + + + 214 == 214 + + + + + multiply( i, 2 ) == i*2 + + + 8 == 8 + + + + + multiply( j, 2 ) == j*2 + + + 214 == 214 + + + + + multiply( i, 2 ) == i*2 + + + 10 == 10 + + + + + multiply( j, 2 ) == j*2 + + + 214 == 214 + + + + + multiply( i, 2 ) == i*2 + + + 30 == 30 + + + + + multiply( j, 2 ) == j*2 + + + 214 == 214 + + + + + multiply( i, 2 ) == i*2 + + + 40 == 40 + + + + + multiply( j, 2 ) == j*2 + + + 214 == 214 + + + + + multiply( i, 2 ) == i*2 + + + 42 == 42 + + + + + multiply( j, 2 ) == j*2 + + + 214 == 214 + + + + + multiply( i, 2 ) == i*2 + + + 72 == 72 + + + + + multiply( j, 2 ) == j*2 + + + 214 == 214 + + + + + + + + d >= Approx( 1.22 ) + + + 1.23 >= Approx( 1.22 ) + + + + + d >= Approx( 1.23 ) + + + 1.23 >= Approx( 1.23 ) + + + + + !d >= Approx( 1.24 ) + + + !(1.23 >= Approx( 1.24 )) + + + + + d >= Approx( 1.24 ).epsilon(0.1) + + + 1.23 >= Approx( 1.24 ) + + + + + + + this is a message + + + this is a warning + + + + + + this message should be logged + + + so should this + + + + a == 1 + + + 2 == 1 + + + + + + + this message may be logged later + + + + a == 2 + + + 2 == 2 + + + + this message should be logged + + + + a == 1 + + + 2 == 1 + + + + and this, but later + + + + a == 0 + + + 2 == 0 + + + + but not this + + + + a == 2 + + + 2 == 2 + + + + + + + + data.int_seven != 7 + + + 7 != 7 + + + + + data.float_nine_point_one != Approx( 9.1f ) + + + 9.1f != Approx( 9.1000003815 ) + + + + + data.double_pi != Approx( 3.1415926535 ) + + + 3.1415926535 != Approx( 3.1415926535 ) + + + + + data.str_hello != "hello" + + + "hello" != "hello" + + + + + data.str_hello.size() != 5 + + + 5 != 5 + + + + + + + + data.int_seven != 6 + + + 7 != 6 + + + + + data.int_seven != 8 + + + 7 != 8 + + + + + data.float_nine_point_one != Approx( 9.11f ) + + + 9.1f != Approx( 9.1099996567 ) + + + + + data.float_nine_point_one != Approx( 9.0f ) + + + 9.1f != Approx( 9.0 ) + + + + + data.float_nine_point_one != Approx( 1 ) + + + 9.1f != Approx( 1.0 ) + + + + + data.float_nine_point_one != Approx( 0 ) + + + 9.1f != Approx( 0.0 ) + + + + + data.double_pi != Approx( 3.1415 ) + + + 3.1415926535 != Approx( 3.1415 ) + + + + + data.str_hello != "goodbye" + + + "hello" != "goodbye" + + + + + data.str_hello != "hell" + + + "hello" != "hell" + + + + + data.str_hello != "hello1" + + + "hello" != "hello1" + + + + + data.str_hello.size() != 6 + + + 5 != 6 + + + + + + + + d <= Approx( 1.24 ) + + + 1.23 <= Approx( 1.24 ) + + + + + d <= Approx( 1.23 ) + + + 1.23 <= Approx( 1.23 ) + + + + + !d <= Approx( 1.22 ) + + + !(1.23 <= Approx( 1.22 )) + + + + + d <= Approx( 1.22 ).epsilon(0.1) + + + 1.23 <= Approx( 1.22 ) + + + + + +
+
+ + + Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString + + + "one two three four" +== +"one two three four" + + + + + Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString + + + "one two three four" +== +"one two three four" + + + +
+ +
+
+
+ + + Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" + + + "one two three +four" +== +"one two three +four" + + + + + Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" + + + "one two three +four" +== +"one two three +four" + + + + + Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" + + + "one two three +four" +== +"one two three +four" + + + + + Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" + + + "one two three +four" +== +"one two three +four" + + + + + Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" + + + "one two +three four" +== +"one two +three four" + + + +
+ +
+
+
+ + + Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" + + + "one two +three +four" +== +"one two +three +four" + + + + + Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" + + + "one two +three +four" +== +"one two +three +four" + + + + + Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" + + + "one two +three +four" +== +"one two +three +four" + + + +
+ +
+
+
+ + + Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" + + + "one +two +three +four" +== +"one +two +three +four" + + + + + Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" + + + "one +two +three +four" +== +"one +two +three +four" + + + +
+ +
+
+
+ + + Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" + + + "abc- +def" +== +"abc- +def" + + + + + Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" + + + "abc- +defg" +== +"abc- +defg" + + + + + Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" + + + "abc- +def- +gh" +== +"abc- +def- +gh" + + + + + Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" + + + "one +two +thr- +ee +four" +== +"one +two +thr- +ee +four" + + + + + Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" + + + "one +two +th- +ree +fo- +ur" +== +"one +two +th- +ree +fo- +ur" + + + +
+ +
+
+
+ + + text.size() == 4 + + + 4 == 4 + + + + + text[0] == "one" + + + "one" == "one" + + + + + text[1] == "two" + + + "two" == "two" + + + + + text[2] == "three" + + + "three" == "three" + + + + + text[3] == "four" + + + "four" == "four" + + + +
+ +
+
+
+ + + text.toString() == " one two\n three\n four" + + + " one two + three + four" +== +" one two + three + four" + + + +
+ +
+
+
+ + + Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString + + + "one two +three four" +== +"one two +three four" + + + + + Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString + + + "one two +three four" +== +"one two +three four" + + + + + Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString + + + "one two +three four" +== +"one two +three four" + + + +
+ +
+
+
+ + + Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef" + + + "abcdef" == "abcdef" + + + + + Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" + + + "abcdef" == "abcdef" + + + + + Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" + + + "abcdef" == "abcdef" + + + + + Text( "abcdef\n", TextAttributes().setWidth( 5 ) ).toString() == "abcd-\nef" + + + "abcd- +ef" +== +"abcd- +ef" + + + +
+ +
+
+
+ + + Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" + + + "one two +three +four" +== +"one two +three +four" + + + + + Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" + + + "one two +three +four" +== +"one two +three +four" + + + + + Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" + + + "one two +three +four" +== +"one two +three +four" + + + +
+ +
+
+
+ + + Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" + + + "one +two +three +four" +== +"one +two +three +four" + + + +
+ +
+
+
+ + + Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString + + + "one,two(three) <here>" +== +"one,two(three) <here>" + + + + + Text( testString, TextAttributes().setWidth( 24 ) ).toString() == testString + + + "one,two(three) <here>" +== +"one,two(three) <here>" + + + +
+ +
+
+
+ + + Text( testString, TextAttributes().setWidth( 11 ) ).toString() == "one,two\n(three)\n<here>" + + + "one,two +(three) +<here>" +== +"one,two +(three) +<here>" + + + +
+ +
+
+
+ + + Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one,\ntwo\n(thre-\ne)\n<here>" + + + "one, +two +(thre- +e) +<here>" +== +"one, +two +(thre- +e) +<here>" + + + + + Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one,\ntwo\n(thr-\nee)\n<her-\ne>" + + + "one, +two +(thr- +ee) +<her- +e>" +== +"one, +two +(thr- +ee) +<her- +e>" + + + + + Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one,\ntwo\n(th-\nree)\n<he-\nre>" + + + "one, +two +(th- +ree) +<he- +re>" +== +"one, +two +(th- +ree) +<he- +re>" + + + +
+ +
+ +
+ + + + t.toString(), EndsWith( "... message truncated due to excessive size" ) + + + "******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +******************************************************************************- +************************ +******************************************************************************- +... message truncated due to excessive size" ends with: "... message truncated due to excessive size" + + + + + + + + + + + testStringForMatching(), Contains( "string" ) && Contains( "abc" ) && Contains( "substring" ) && Contains( "contains" ) + + + "this string contains 'abc' as a substring" ( contains: "string" and contains: "abc" and contains: "substring" and contains: "contains" ) + + + + + + + + testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) + + + "this string contains 'abc' as a substring" ( contains: "string" or contains: "different" or contains: "random" ) + + + + + testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) + + + "some completely different text that contains one common word" ( contains: "string" or contains: "different" or contains: "random" ) + + + + + + + + testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) + + + "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "substring" ) + + + + + + + + testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) + + + "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" ) + + + + + + + + testStringForMatching(), !Contains( "different" ) + + + "this string contains 'abc' as a substring" not contains: "different" + + + + + + + + testStringForMatching(), !Contains( "substring" ) + + + "this string contains 'abc' as a substring" not contains: "substring" + + + + + + + + thisThrows(), "expected exception" + + + thisThrows(), "expected exception" + + + + + thisThrows(), "should fail" + + + expected exception + + + + + + + This one ran + + + + + + custom exception + + + + + + + thisFunctionNotImplemented( 7 ) + + + thisFunctionNotImplemented( 7 ) + + + + + + + + True + + + true + + + + + !False + + + true + + + + + !False + + + !false + + + + + + + + 0x == o + + + 3221225472 (0x) == {?} + + + + + + + + data.int_seven > 7 + + + 7 > 7 + + + + + data.int_seven < 7 + + + 7 < 7 + + + + + data.int_seven > 8 + + + 7 > 8 + + + + + data.int_seven < 6 + + + 7 < 6 + + + + + data.int_seven < 0 + + + 7 < 0 + + + + + data.int_seven < -1 + + + 7 < -1 + + + + + data.int_seven >= 8 + + + 7 >= 8 + + + + + data.int_seven <= 6 + + + 7 <= 6 + + + + + data.float_nine_point_one < 9 + + + 9.1f < 9 + + + + + data.float_nine_point_one > 10 + + + 9.1f > 10 + + + + + data.float_nine_point_one > 9.2 + + + 9.1f > 9.2 + + + + + data.str_hello > "hello" + + + "hello" > "hello" + + + + + data.str_hello < "hello" + + + "hello" < "hello" + + + + + data.str_hello > "hellp" + + + "hello" > "hellp" + + + + + data.str_hello > "z" + + + "hello" > "z" + + + + + data.str_hello < "hellm" + + + "hello" < "hellm" + + + + + data.str_hello < "a" + + + "hello" < "a" + + + + + data.str_hello >= "z" + + + "hello" >= "z" + + + + + data.str_hello <= "a" + + + "hello" <= "a" + + + + + + + + data.int_seven < 8 + + + 7 < 8 + + + + + data.int_seven > 6 + + + 7 > 6 + + + + + data.int_seven > 0 + + + 7 > 0 + + + + + data.int_seven > -1 + + + 7 > -1 + + + + + data.int_seven >= 7 + + + 7 >= 7 + + + + + data.int_seven >= 6 + + + 7 >= 6 + + + + + data.int_seven <= 7 + + + 7 <= 7 + + + + + data.int_seven <= 8 + + + 7 <= 8 + + + + + data.float_nine_point_one > 9 + + + 9.1f > 9 + + + + + data.float_nine_point_one < 10 + + + 9.1f < 10 + + + + + data.float_nine_point_one < 9.2 + + + 9.1f < 9.2 + + + + + data.str_hello <= "hello" + + + "hello" <= "hello" + + + + + data.str_hello >= "hello" + + + "hello" >= "hello" + + + + + data.str_hello < "hellp" + + + "hello" < "hellp" + + + + + data.str_hello < "zebra" + + + "hello" < "zebra" + + + + + data.str_hello > "hellm" + + + "hello" > "hellm" + + + + + data.str_hello > "a" + + + "hello" > "a" + + + + + +
+ + Message from section one + + +
+
+ + Message from section two + + +
+ +
+ +
+ + + spec.hasFilters() == false + + + false == false + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == false + + + false == false + + + + + spec.matches(tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == false + + + false == false + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == true + + + true == true + + + + + spec.matches( tcC ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == true + + + true == true + + + + + spec.matches( tcD ) == false + + + false == false + + + + + parseTestSpec( "*a" ).matches( tcA ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == true + + + true == true + + + + + spec.matches( tcD ) == false + + + false == false + + + + + parseTestSpec( "a*" ).matches( tcA ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == true + + + true == true + + + + + spec.matches( tcD ) == true + + + true == true + + + + + parseTestSpec( "*a*" ).matches( tcA ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == true + + + true == true + + + + + spec.matches( tcB ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == true + + + true == true + + + + + spec.matches( tcB ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == true + + + true == true + + + + + spec.matches( tcB ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == true + + + true == true + + + + + spec.matches( tcD ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == true + + + true == true + + + + + spec.matches( tcB ) == true + + + true == true + + + + + spec.matches( tcC ) == true + + + true == true + + + + + spec.matches( tcD ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == true + + + true == true + + + + + spec.matches( tcC ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == true + + + true == true + + + + + spec.matches( tcC ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == true + + + true == true + + + + + spec.matches( tcD ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == true + + + true == true + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == true + + + true == true + + + + + spec.matches( tcC ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == false + + + false == false + + + + + spec.matches( tcD ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == false + + + false == false + + + + + spec.matches( tcD ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == true + + + true == true + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == true + + + true == true + + + + + spec.matches( tcD ) == true + + + true == true + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == true + + + true == true + + + + + spec.matches( tcB ) == true + + + true == true + + + + + spec.matches( tcC ) == false + + + false == false + + + + + spec.matches( tcD ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == true + + + true == true + + + + + spec.matches( tcB ) == true + + + true == true + + + + + spec.matches( tcC ) == true + + + true == true + + + + + spec.matches( tcD ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == true + + + true == true + + + + + spec.matches( tcB ) == true + + + true == true + + + + + spec.matches( tcC ) == true + + + true == true + + + + + spec.matches( tcD ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == true + + + true == true + + + + + spec.matches( tcD ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == false + + + false == false + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == false + + + false == false + + + + + spec.matches( tcD ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == false + + + false == false + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == false + + + false == false + + + + + spec.matches( tcD ) == false + + + false == false + + + +
+
+ + + spec.hasFilters() == true + + + true == true + + + + + spec.matches( tcA ) == false + + + false == false + + + + + spec.matches( tcB ) == false + + + false == false + + + + + spec.matches( tcC ) == false + + + false == false + + + + + spec.matches( tcD ) == true + + + true == true + + + +
+ +
+ + + + (std::pair<int, int>( 1, 2 )) == aNicePair + + + std::pair( 1, 2 ) == std::pair( 1, 2 ) + + + + + + + + p == 0 + + + NULL == 0 + + + + + p == pNULL + + + NULL == NULL + + + + + p != 0 + + + 0x != 0 + + + + + cp != 0 + + + 0x != 0 + + + + + cpc != 0 + + + 0x != 0 + + + + + returnsNull() == 0 + + + {null string} == 0 + + + + + returnsConstNull() == 0 + + + {null string} == 0 + + + + + 0 != p + + + 0 != 0x + + + + + + + actual address of p: 0x + + + toString(p): 0x + + + + +
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.shouldDebugBreak == false + + + false == false + + + + + config.abortAfter == -1 + + + -1 == -1 + + + + + config.noThrow == false + + + false == false + + + + + config.reporterNames.empty() + + + true + + + +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false + + + false == false + + + + + cfg.testSpec().matches( fakeTestCase( "test1" ) ) + + + true + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false + + + false == false + + + + + cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) + + + true + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false + + + false == false + + + + + cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) + + + true + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.reporterNames[0] == "console" + + + "console" == "console" + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.reporterNames[0] == "xml" + + + "xml" == "xml" + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.reporterNames.size() == 2 + + + 2 == 2 + + + + + config.reporterNames[0] == "xml" + + + "xml" == "xml" + + + + + config.reporterNames[1] == "junit" + + + "junit" == "junit" + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.reporterNames[0] == "junit" + + + "junit" == "junit" + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.shouldDebugBreak == true + + + true == true + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.shouldDebugBreak + + + true + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.abortAfter == 1 + + + 1 == 1 + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.abortAfter == 2 + + + 2 == 2 + + + +
+ +
+
+
+ + + parseIntoConfigAndReturnError( argv, config ), Contains( "greater than zero" ) + + + "Value after -x or --abortAfter must be greater than zero +- while parsing: (-x, --abortx <no. failures>)" contains: "greater than zero" + + + +
+ +
+
+
+ + + parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) + + + "Unable to convert oops to destination type +- while parsing: (-x, --abortx <no. failures>)" contains: "-x" + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.noThrow == true + + + true == true + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.noThrow == true + + + true == true + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.outputFilename == "filename.ext" + + + "filename.ext" == "filename.ext" + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.outputFilename == "filename.ext" + + + "filename.ext" == "filename.ext" + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.abortAfter == 1 + + + 1 == 1 + + + + + config.shouldDebugBreak + + + true + + + + + config.noThrow == true + + + true == true + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.useColour == UseColour::Auto + + + 0 == 0 + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.useColour == UseColour::Auto + + + 0 == 0 + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.useColour == UseColour::Yes + + + 1 == 1 + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ) + + + parseIntoConfig( argv, config ) + + + + + config.useColour == UseColour::No + + + 2 == 2 + + + +
+ +
+
+
+ + + parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) + + + parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) + + + +
+ +
+ +
+ + + current counter 0 + + + i := 0 + + + + i < 10 + + + 0 < 10 + + + + current counter 1 + + + i := 1 + + + + i < 10 + + + 1 < 10 + + + + current counter 2 + + + i := 2 + + + + i < 10 + + + 2 < 10 + + + + current counter 3 + + + i := 3 + + + + i < 10 + + + 3 < 10 + + + + current counter 4 + + + i := 4 + + + + i < 10 + + + 4 < 10 + + + + current counter 5 + + + i := 5 + + + + i < 10 + + + 5 < 10 + + + + current counter 6 + + + i := 6 + + + + i < 10 + + + 6 < 10 + + + + current counter 7 + + + i := 7 + + + + i < 10 + + + 7 < 10 + + + + current counter 8 + + + i := 8 + + + + i < 10 + + + 8 < 10 + + + + current counter 9 + + + i := 9 + + + + i < 10 + + + 9 < 10 + + + + current counter 10 + + + i := 10 + + + + i < 10 + + + 10 < 10 + + + + + + + + + + + +
+ + + before == 0 + + + 0 == 0 + + +
+
+ + + after > before + + + 1 > 0 + + + +
+ +
+ +
+ +
+ +
+
+
+ + + itDoesThis() + + + true + + +
+ + + itDoesThat() + + + true + + + +
+ +
+ +
+ +
+ +
+ +
+
+
+ +
+ +
+ +
+ +
+ +
+ + + v.size() == 0 + + + 0 == 0 + + +
+
+ + + v.size() == 10 + + + 10 == 10 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + +
+
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ +
+ +
+ +
+ +
+
+ + + v.size() == 0 + + + 0 == 0 + + +
+
+ + + v.capacity() >= 10 + + + 10 >= 10 + + + + + v.size() == 0 + + + 0 == 0 + + + +
+ +
+ +
+ +
+ + + +A string sent directly to stdout + + +A string sent directly to stderr + + + + + + + d == Approx( 1.23 ) + + + 1.23 == Approx( 1.23 ) + + + + + d != Approx( 1.22 ) + + + 1.23 != Approx( 1.22 ) + + + + + d != Approx( 1.24 ) + + + 1.23 != Approx( 1.24 ) + + + + + Approx( d ) == 1.23 + + + Approx( 1.23 ) == 1.23 + + + + + Approx( d ) != 1.22 + + + Approx( 1.23 ) != 1.22 + + + + + Approx( d ) != 1.24 + + + Approx( 1.23 ) != 1.24 + + + + + +
+ +
+
+ +
+ + +Message from section one +Message from section two + + +
+ + + + testStringForMatching(), StartsWith( "string" ) + + + "this string contains 'abc' as a substring" starts with: "string" + + + + + + + + testStringForMatching(), Contains( "string" ) + + + "this string contains 'abc' as a substring" contains: "string" + + + + + testStringForMatching(), Contains( "abc" ) + + + "this string contains 'abc' as a substring" contains: "abc" + + + + + testStringForMatching(), StartsWith( "this" ) + + + "this string contains 'abc' as a substring" starts with: "this" + + + + + testStringForMatching(), EndsWith( "substring" ) + + + "this string contains 'abc' as a substring" ends with: "substring" + + + + + + + +hello +hello + + + + + + + s1 == s2 + + + "if ($b == 10) { + $a = 20; +}" +== +"if ($b == 10) { + $a = 20; +} +" + + + + + +
+ + + what, Contains( "[@zzz]" ) + + + "error: tag alias, "[@zzz]" already registered. + First seen at file:2 + Redefined at file:10" contains: "[@zzz]" + + + + + what, Contains( "file" ) + + + "error: tag alias, "[@zzz]" already registered. + First seen at file:2 + Redefined at file:10" contains: "file" + + + + + what, Contains( "2" ) + + + "error: tag alias, "[@zzz]" already registered. + First seen at file:2 + Redefined at file:10" contains: "2" + + + + + what, Contains( "10" ) + + + "error: tag alias, "[@zzz]" already registered. + First seen at file:2 + Redefined at file:10" contains: "10" + + + +
+
+ + + registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) + + + registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) + + + + + registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) + + + registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) + + + + + registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) + + + registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) + + + + + registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) + + + registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) + + + +
+ +
+ + + + + + + 0x == bit30and31 + + + 3221225472 (0x) == 3221225472 + + + + + + + + Text( "hi there" ).toString() == "hi there" + + + "hi there" == "hi there" + + + + + Text( "hi there", narrow ).toString() == "hi\nthere" + + + "hi +there" +== +"hi +there" + + + + + + + + 1 == 2 + + + 1 == 2 + + + + + + + + + + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s1.isSuccessfullyCompleted() + + + true + + + + + testCase.isComplete() == false + + + false == false + + + + + ctx.completedCycle() + + + true + + + + + testCase.isSuccessfullyCompleted() + + + true + + + +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s1.isComplete() + + + true + + + + + s1.isSuccessfullyCompleted() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + + + + ctx.completedCycle() + + + true + + + + + testCase.isSuccessfullyCompleted() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() == false + + + false == false + + + + + ctx.completedCycle() + + + true + + + + + testCase.isComplete() + + + true + + + + + testCase.isSuccessfullyCompleted() + + + true + + + +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s1.isComplete() + + + true + + + + + s1.isSuccessfullyCompleted() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + + + + ctx.completedCycle() + + + true + + + + + testCase.isSuccessfullyCompleted() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() == false + + + false == false + + + + + s2.isOpen() + + + true + + + + + ctx.completedCycle() + + + true + + + + + testCase.isComplete() + + + true + + + + + testCase.isSuccessfullyCompleted() + + + true + + + +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s2.isOpen() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() == false + + + false == false + + + + + s2b.isOpen() + + + true + + + + + ctx.completedCycle() == false + + + false == false + + +
+ + + ctx.completedCycle() + + + true + + + + + s2b.isSuccessfullyCompleted() + + + true + + + + + testCase2.isComplete() == false + + + false == false + + + + + testCase2.isSuccessfullyCompleted() + + + true + + + +
+ +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s2.isOpen() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() == false + + + false == false + + + + + s2b.isOpen() + + + true + + + + + ctx.completedCycle() == false + + + false == false + + +
+ + + ctx.completedCycle() + + + true + + + + + s2b.isComplete() + + + true + + + + + s2b.isSuccessfullyCompleted() == false + + + false == false + + + + + testCase2.isSuccessfullyCompleted() == false + + + false == false + + + + + testCase3.isOpen() + + + true + + + + + s1c.isOpen() == false + + + false == false + + + + + s2c.isOpen() == false + + + false == false + + + + + testCase3.isSuccessfullyCompleted() + + + true + + + +
+ +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s2.isOpen() + + + true + + + + + s2.isComplete() + + + true + + + + + s1.isComplete() == false + + + false == false + + + + + s1.isComplete() + + + true + + + + + testCase.isComplete() == false + + + false == false + + + + + testCase.isComplete() + + + true + + + +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + g1.isOpen() + + + true + + + + + g1.index() == 0 + + + 0 == 0 + + + + + g1.isComplete() == false + + + false == false + + + + + s1.isComplete() == false + + + false == false + + +
+ + + s1.isComplete() == false + + + false == false + + + + + testCase.isSuccessfullyCompleted() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() + + + true + + + + + g1b.isOpen() + + + true + + + + + g1b.index() == 1 + + + 1 == 1 + + + + + s1.isComplete() == false + + + false == false + + + + + s1b.isComplete() + + + true + + + + + g1b.isComplete() + + + true + + + + + testCase2.isComplete() + + + true + + + +
+ +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + g1.isOpen() + + + true + + + + + g1.index() == 0 + + + 0 == 0 + + + + + g1.isComplete() == false + + + false == false + + + + + s1.isComplete() == false + + + false == false + + +
+ + + s2.isOpen() + + + true + + + + + s2.isComplete() + + + true + + + + + s1.isComplete() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() + + + true + + + + + g1b.isOpen() + + + true + + + + + g1b.index() == 1 + + + 1 == 1 + + + + + s2b.isOpen() + + + true + + + + + s2b.isComplete() + + + true + + + + + g1b.isComplete() + + + true + + + + + s1b.isComplete() + + + true + + + + + testCase2.isComplete() + + + true + + + +
+ +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + g1.isOpen() + + + true + + + + + g1.index() == 0 + + + 0 == 0 + + + + + g1.isComplete() == false + + + false == false + + + + + s1.isComplete() == false + + + false == false + + +
+ + + s2.isOpen() + + + true + + + + + s2.isComplete() + + + true + + + + + s2.isSuccessfullyCompleted() == false + + + false == false + + + + + s1.isComplete() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() + + + true + + + + + g1b.isOpen() + + + true + + + + + g1b.index() == 0 + + + 0 == 0 + + + + + s2b.isOpen() == false + + + false == false + + + + + g1b.isComplete() == false + + + false == false + + + + + s1b.isComplete() == false + + + false == false + + + + + testCase2.isComplete() == false + + + false == false + + + + + testCase3.isOpen() + + + true + + + + + s1c.isOpen() + + + true + + + + + g1c.isOpen() + + + true + + + + + g1c.index() == 1 + + + 1 == 1 + + + + + s2c.isOpen() + + + true + + + + + s2c.isComplete() + + + true + + + + + g1c.isComplete() + + + true + + + + + s1c.isComplete() + + + true + + + + + testCase3.isComplete() + + + true + + + +
+ +
+ +
+ +
+ + + 3.14 + + + + + + + d == approx( 1.23 ) + + + 1.23 == Approx( 1.23 ) + + + + + d == approx( 1.22 ) + + + 1.23 == Approx( 1.22 ) + + + + + d == approx( 1.24 ) + + + 1.23 == Approx( 1.24 ) + + + + + d != approx( 1.25 ) + + + 1.23 != Approx( 1.25 ) + + + + + approx( d ) == 1.23 + + + Approx( 1.23 ) == 1.23 + + + + + approx( d ) == 1.22 + + + Approx( 1.23 ) == 1.22 + + + + + approx( d ) == 1.24 + + + Approx( 1.23 ) == 1.24 + + + + + approx( d ) != 1.25 + + + Approx( 1.23 ) != 1.25 + + + + + +
+ +
+ +
+ +
+ + + v, VectorContains( 1 ) + + + { 1, 2, 3 } Contains: 1 + + + + + v, VectorContains( 2 ) + + + { 1, 2, 3 } Contains: 2 + + + +
+
+ + + v, Contains( v2 ) + + + { 1, 2, 3 } Contains: { 1, 2 } + + + + + v, Contains( v2 ) + + + { 1, 2, 3 } Contains: { 1, 2, 3 } + + + + + v, Contains( empty) + + + { 1, 2, 3 } Contains: { } + + + + + empty, Contains( empty) + + + { } Contains: { } + + + +
+
+ + + v, Equals( v ) + + + { 1, 2, 3 } Equals: { 1, 2, 3 } + + + + + empty, Equals( empty ) + + + { } Equals: { } + + + + + v, Equals( v2 ) + + + { 1, 2, 3 } Equals: { 1, 2, 3 } + + + +
+ +
+ +
+ + + v, VectorContains( -1 ) + + + { 1, 2, 3 } Contains: -1 + + + + + empty, VectorContains( 1 ) + + + { } Contains: 1 + + + +
+
+ + + empty, Contains( v) + + + { } Contains: { 1, 2, 3 } + + + + + v, Contains( v2 ) + + + { 1, 2, 3 } Contains: { 1, 2, 4 } + + + +
+
+ + + v, Equals( v2 ) + + + { 1, 2, 3 } Equals: { 1, 2 } + + + + + v2, Equals( v ) + + + { 1, 2 } Equals: { 1, 2, 3 } + + + + + empty, Equals( v ) + + + { } Equals: { 1, 2, 3 } + + + + + v, Equals( empty ) + + + { 1, 2, 3 } Equals: { } + + + +
+ +
+ + + + thisThrows(), std::domain_error + + + thisThrows(), std::domain_error + + + + + thisDoesntThrow() + + + thisDoesntThrow() + + + + + thisThrows() + + + thisThrows() + + + + + + + unexpected exception + + + + + + + thisThrows() == 0 + + + thisThrows() == 0 + + + expected exception + + + + + + + + thisThrows() == 0 + + + thisThrows() == 0 + + + expected exception + + + + + + + + thisThrows() == 0 + + + thisThrows() == 0 + + + expected exception + + + + + +
+ + unexpected exception + + +
+ +
+ + + + + + Uncomment the code in this test to check that it gives a sensible compiler error + + + + + + Uncomment the code in this test to check that it gives a sensible compiler error + + + + + + + + + + + + + + + + +
+ + + encode( "normal string" ) == "normal string" + + + "normal string" == "normal string" + + + +
+
+ + + encode( "" ) == "" + + + "" == "" + + + +
+
+ + + encode( "smith & jones" ) == "smith &amp; jones" + + + "smith &amp; jones" == "smith &amp; jones" + + + +
+
+ + + encode( "smith < jones" ) == "smith &lt; jones" + + + "smith &lt; jones" == "smith &lt; jones" + + + +
+
+ + + encode( "smith > jones" ) == "smith > jones" + + + "smith > jones" == "smith > jones" + + + + + encode( "smith ]]> jones" ) == "smith ]]&gt; jones" + + + "smith ]]&gt; jones" +== +"smith ]]&gt; jones" + + + +
+
+ + + encode( stringWithQuotes ) == stringWithQuotes + + + "don't "quote" me on that" +== +"don't "quote" me on that" + + + + + encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't &quot;quote&quot; me on that" + + + "don't &quot;quote&quot; me on that" +== +"don't &quot;quote&quot; me on that" + + + +
+
+ + + encode( "[\x01]" ) == "[\\x01]" + + + "[\x01]" == "[\x01]" + + + +
+
+ + + encode( "[\x7F]" ) == "[\\x7F]" + + + "[\x7F]" == "[\x7F]" + + + +
+ +
+ + + + x == 0 + + + 0 == 0 + + + + + + + + obj.prop != 0 + + + 0x != 0 + + + + + + + + flag + + + true + + + + + testCheckedElse( true ) + + + true + + + + + + + + flag + + + false + + + + + testCheckedElse( false ) + + + false + + + + + + + + flag + + + true + + + + + testCheckedIf( true ) + + + true + + + + + + + + flag + + + false + + + + + testCheckedIf( false ) + + + false + + + + + + + + unsigned_char_var == 1 + + + 1 == 1 + + + + + unsigned_short_var == 1 + + + 1 == 1 + + + + + unsigned_int_var == 1 + + + 1 == 1 + + + + + unsigned_long_var == 1 + + + 1 == 1 + + + + + + + + long_var == unsigned_char_var + + + 1 == 1 + + + + + long_var == unsigned_short_var + + + 1 == 1 + + + + + long_var == unsigned_int_var + + + 1 == 1 + + + + + long_var == unsigned_long_var + + + 1 == 1 + + + + + +
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ + + + +spanner + + + + Previous info should not be seen + + + + + + + +
+ + + b > a + + + 0 > 1 + + + +
+ +
+ + + Testing if fib[0] (1) is even + + + + ( fib[i] % 2 ) == 0 + + + 1 == 0 + + + + Testing if fib[1] (1) is even + + + + ( fib[i] % 2 ) == 0 + + + 1 == 0 + + + + Testing if fib[2] (2) is even + + + + ( fib[i] % 2 ) == 0 + + + 0 == 0 + + + + Testing if fib[3] (3) is even + + + + ( fib[i] % 2 ) == 0 + + + 1 == 0 + + + + Testing if fib[4] (5) is even + + + + ( fib[i] % 2 ) == 0 + + + 1 == 0 + + + + Testing if fib[5] (8) is even + + + + ( fib[i] % 2 ) == 0 + + + 0 == 0 + + + + Testing if fib[6] (13) is even + + + + ( fib[i] % 2 ) == 0 + + + 1 == 0 + + + + Testing if fib[7] (21) is even + + + + ( fib[i] % 2 ) == 0 + + + 1 == 0 + + + + + +
+
+ + + a == b + + + 1 == 2 + + + +
+ +
+
+
+ + + a != b + + + 1 != 2 + + + +
+ +
+
+
+ + + a < b + + + 1 < 2 + + + +
+ +
+ +
+ +
+ + + a != b + + + 1 != 2 + + + + + b != a + + + 2 != 1 + + +
+ + + a != b + + + 1 != 2 + + + +
+ +
+ +
+ + + + s == "7" + + + "7" == "7" + + + + + + + + + + + makeString( false ) != static_cast<char*>(0) + + + "valid string" != {null string} + + + + + makeString( true ) == static_cast<char*>(0) + + + {null string} == {null string} + + + + + + + + Catch::toString( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" + + + "{ { 42, "Arthur" }, { "Ford", 24 } }" +== +"{ { 42, "Arthur" }, { "Ford", 24 } }" + + + + + + + + p == 0 + + + NULL == 0 + + + + + +
+ + + a != b + + + 1 != 2 + + + + + b != a + + + 2 != 1 + + + +
+
+ + + a != b + + + 1 != 2 + + + +
+ +
+ +
+ + + replaceInPlace( letters, "b", "z" ) + + + true + + + + + letters == "azcdefcg" + + + "azcdefcg" == "azcdefcg" + + + +
+
+ + + replaceInPlace( letters, "c", "z" ) + + + true + + + + + letters == "abzdefzg" + + + "abzdefzg" == "abzdefzg" + + + +
+
+ + + replaceInPlace( letters, "a", "z" ) + + + true + + + + + letters == "zbcdefcg" + + + "zbcdefcg" == "zbcdefcg" + + + +
+
+ + + replaceInPlace( letters, "g", "z" ) + + + true + + + + + letters == "abcdefcz" + + + "abcdefcz" == "abcdefcz" + + + +
+
+ + + replaceInPlace( letters, letters, "replaced" ) + + + true + + + + + letters == "replaced" + + + "replaced" == "replaced" + + + +
+
+ + + !replaceInPlace( letters, "x", "z" ) + + + !false + + + + + letters == letters + + + "abcdefcg" == "abcdefcg" + + + +
+
+ + + replaceInPlace( s, "'", "|'" ) + + + true + + + + + s == "didn|'t" + + + "didn|'t" == "didn|'t" + + + +
+ +
+ + + + + + 3 + + + + false + + + false + + + + + + + hi + + + i := 7 + + + + false + + + false + + + + + + + + Catch::toString(value) == "{ 34, \"xyzzy\" }" + + + "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }" + + + + + + + + Catch::toString( value ) == "{ 34, \"xyzzy\" }" + + + "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }" + + + + + + + + Catch::toString( pr ) == "{ { \"green\", 55 } }" + + + "{ { "green", 55 } }" +== +"{ { "green", 55 } }" + + + + + + + + std::string( "first" ) == "second" + + + "first" == "second" + + + + + + + + result == "\"wide load\"" + + + ""wide load"" == ""wide load"" + + + + + + + + result == "\"wide load\"" + + + ""wide load"" == ""wide load"" + + + + + + + + result == "\"wide load\"" + + + ""wide load"" == ""wide load"" + + + + + + + + result == "\"wide load\"" + + + ""wide load"" == ""wide load"" + + + + + + + + Catch::toString( item ) == "StringMaker<has_maker>" + + + "StringMaker<has_maker>" +== +"StringMaker<has_maker>" + + + + + + + + Catch::toString( item ) == "toString( has_maker_and_toString )" + + + "toString( has_maker_and_toString )" +== +"toString( has_maker_and_toString )" + + + + + + + + Catch::toString( item ) == "toString( has_toString )" + + + "toString( has_toString )" +== +"toString( has_toString )" + + + + + + + + Catch::toString( v ) == "{ StringMaker<has_maker> }" + + + "{ StringMaker<has_maker> }" +== +"{ StringMaker<has_maker> }" + + + + + + + + Catch::toString(e0) == "E2{0}" + + + "E2{0}" == "E2{0}" + + + + + Catch::toString(e1) == "E2{1}" + + + "E2{1}" == "E2{1}" + + + + + + + + Catch::toString(e0) == "0" + + + "0" == "0" + + + + + Catch::toString(e1) == "1" + + + "1" == "1" + + + + + + + + Catch::toString(vv) == "{ }" + + + "{ }" == "{ }" + + + + + Catch::toString(vv) == "{ 42 }" + + + "{ 42 }" == "{ 42 }" + + + + + Catch::toString(vv) == "{ 42, 250 }" + + + "{ 42, 250 }" == "{ 42, 250 }" + + + + + + + + Catch::toString(vv) == "{ }" + + + "{ }" == "{ }" + + + + + Catch::toString(vv) == "{ \"hello\" }" + + + "{ "hello" }" == "{ "hello" }" + + + + + Catch::toString(vv) == "{ \"hello\", \"world\" }" + + + "{ "hello", "world" }" +== +"{ "hello", "world" }" + + + + + + + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 10 + + + 10 == 10 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 0 + + + 0 == 0 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.capacity() == 0 + + + 0 == 0 + + + +
+ +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + + +
+ +
+ +
+ +
+
+ +
+ +
+ +
+ +
diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ClassTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ClassTests.cpp new file mode 100644 index 0000000..a470784 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ClassTests.cpp @@ -0,0 +1,57 @@ +/* + * Created by Phil on 09/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + +namespace +{ + class TestClass + { + std::string s; + + public: + TestClass() + : s( "hello" ) + {} + + void succeedingCase() + { + REQUIRE( s == "hello" ); + } + void failingCase() + { + REQUIRE( s == "world" ); + } + }; +} + + +METHOD_AS_TEST_CASE( TestClass::succeedingCase, "A METHOD_AS_TEST_CASE based test run that succeeds", "[class]" ) +METHOD_AS_TEST_CASE( TestClass::failingCase, "A METHOD_AS_TEST_CASE based test run that fails", "[.][class][failing]" ) + + +struct Fixture +{ + Fixture() : m_a( 1 ) {} + + int m_a; +}; + +TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that succeeds", "[class]" ) +{ + REQUIRE( m_a == 1 ); +} + +// We should be able to write our tests within a different namespace +namespace Inner +{ + TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that fails", "[.][class][failing]" ) + { + REQUIRE( m_a == 2 ); + } +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/CmdLineTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/CmdLineTests.cpp new file mode 100644 index 0000000..83b79fd --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/CmdLineTests.cpp @@ -0,0 +1,264 @@ +/* + * Created by Phil on 13/5/2013. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" +#include "internal/catch_test_spec_parser.hpp" + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Wc++98-compat" +#endif + +inline Catch::TestCase fakeTestCase( const char* name, const char* desc = "" ){ return Catch::makeTestCase( CATCH_NULL, "", name, desc, CATCH_INTERNAL_LINEINFO ); } + +TEST_CASE( "Parse test names and tags", "" ) { + + using Catch::parseTestSpec; + using Catch::TestSpec; + + Catch::TestCase tcA = fakeTestCase( "a", "" ); + Catch::TestCase tcB = fakeTestCase( "b", "[one][x]" ); + Catch::TestCase tcC = fakeTestCase( "longer name with spaces", "[two][three][.][x]" ); + Catch::TestCase tcD = fakeTestCase( "zlonger name with spacesz", "" ); + + SECTION( "Empty test spec should have no filters", "" ) { + TestSpec spec; + CHECK( spec.hasFilters() == false ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + } + + SECTION( "Test spec from empty string should have no filters", "" ) { + TestSpec spec = parseTestSpec( "" ); + CHECK( spec.hasFilters() == false ); + CHECK( spec.matches(tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + } + + SECTION( "Test spec from just a comma should have no filters", "" ) { + TestSpec spec = parseTestSpec( "," ); + CHECK( spec.hasFilters() == false ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + } + + SECTION( "Test spec from name should have one filter", "" ) { + TestSpec spec = parseTestSpec( "b" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == true ); + } + + SECTION( "Test spec from quoted name should have one filter", "" ) { + TestSpec spec = parseTestSpec( "\"b\"" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == true ); + } + + SECTION( "Test spec from name should have one filter", "" ) { + TestSpec spec = parseTestSpec( "b" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == true ); + CHECK( spec.matches( tcC ) == false ); + } + + SECTION( "Wildcard at the start", "" ) { + TestSpec spec = parseTestSpec( "*spaces" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == true ); + CHECK( spec.matches( tcD ) == false ); + CHECK( parseTestSpec( "*a" ).matches( tcA ) == true ); + } + SECTION( "Wildcard at the end", "" ) { + TestSpec spec = parseTestSpec( "long*" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == true ); + CHECK( spec.matches( tcD ) == false ); + CHECK( parseTestSpec( "a*" ).matches( tcA ) == true ); + } + SECTION( "Wildcard at both ends", "" ) { + TestSpec spec = parseTestSpec( "*name*" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == true ); + CHECK( spec.matches( tcD ) == true ); + CHECK( parseTestSpec( "*a*" ).matches( tcA ) == true ); + } + SECTION( "Redundant wildcard at the start", "" ) { + TestSpec spec = parseTestSpec( "*a" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == true ); + CHECK( spec.matches( tcB ) == false ); + } + SECTION( "Redundant wildcard at the end", "" ) { + TestSpec spec = parseTestSpec( "a*" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == true ); + CHECK( spec.matches( tcB ) == false ); + } + SECTION( "Redundant wildcard at both ends", "" ) { + TestSpec spec = parseTestSpec( "*a*" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == true ); + CHECK( spec.matches( tcB ) == false ); + } + SECTION( "Wildcard at both ends, redundant at start", "" ) { + TestSpec spec = parseTestSpec( "*longer*" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == true ); + CHECK( spec.matches( tcD ) == true ); + } + SECTION( "Just wildcard", "" ) { + TestSpec spec = parseTestSpec( "*" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == true ); + CHECK( spec.matches( tcB ) == true ); + CHECK( spec.matches( tcC ) == true ); + CHECK( spec.matches( tcD ) == true ); + } + + SECTION( "Single tag", "" ) { + TestSpec spec = parseTestSpec( "[one]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == true ); + CHECK( spec.matches( tcC ) == false ); + } + SECTION( "Single tag, two matches", "" ) { + TestSpec spec = parseTestSpec( "[x]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == true ); + CHECK( spec.matches( tcC ) == true ); + } + SECTION( "Two tags", "" ) { + TestSpec spec = parseTestSpec( "[two][x]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == true ); + } + SECTION( "Two tags, spare separated", "" ) { + TestSpec spec = parseTestSpec( "[two] [x]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == true ); + } + SECTION( "Wildcarded name and tag", "" ) { + TestSpec spec = parseTestSpec( "*name*[x]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == true ); + CHECK( spec.matches( tcD ) == false ); + } + SECTION( "Single tag exclusion", "" ) { + TestSpec spec = parseTestSpec( "~[one]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == true ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == true ); + } + SECTION( "One tag exclusion and one tag inclusion", "" ) { + TestSpec spec = parseTestSpec( "~[two][x]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == true ); + CHECK( spec.matches( tcC ) == false ); + } + SECTION( "One tag exclusion and one wldcarded name inclusion", "" ) { + TestSpec spec = parseTestSpec( "~[two]*name*" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == false ); + CHECK( spec.matches( tcD ) == true ); + } + SECTION( "One tag exclusion, using exclude:, and one wldcarded name inclusion", "" ) { + TestSpec spec = parseTestSpec( "exclude:[two]*name*" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == false ); + CHECK( spec.matches( tcD ) == true ); + } + SECTION( "name exclusion", "" ) { + TestSpec spec = parseTestSpec( "~b" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == true ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == true ); + CHECK( spec.matches( tcD ) == true ); + } + SECTION( "wildcarded name exclusion", "" ) { + TestSpec spec = parseTestSpec( "~*name*" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == true ); + CHECK( spec.matches( tcB ) == true ); + CHECK( spec.matches( tcC ) == false ); + CHECK( spec.matches( tcD ) == false ); + } + SECTION( "wildcarded name exclusion with tag inclusion", "" ) { + TestSpec spec = parseTestSpec( "~*name*,[three]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == true ); + CHECK( spec.matches( tcB ) == true ); + CHECK( spec.matches( tcC ) == true ); + CHECK( spec.matches( tcD ) == false ); + } + SECTION( "wildcarded name exclusion, using exclude:, with tag inclusion", "" ) { + TestSpec spec = parseTestSpec( "exclude:*name*,[three]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == true ); + CHECK( spec.matches( tcB ) == true ); + CHECK( spec.matches( tcC ) == true ); + CHECK( spec.matches( tcD ) == false ); + } + SECTION( "two wildcarded names", "" ) { + TestSpec spec = parseTestSpec( "\"longer*\"\"*spaces\"" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == true ); + CHECK( spec.matches( tcD ) == false ); + } + SECTION( "empty tag", "" ) { + TestSpec spec = parseTestSpec( "[]" ); + CHECK( spec.hasFilters() == false ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == false ); + CHECK( spec.matches( tcD ) == false ); + } + SECTION( "empty quoted name", "" ) { + TestSpec spec = parseTestSpec( "\"\"" ); + CHECK( spec.hasFilters() == false ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == false ); + CHECK( spec.matches( tcD ) == false ); + } + SECTION( "quoted string followed by tag exclusion", "" ) { + TestSpec spec = parseTestSpec( "\"*name*\"~[.]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == false ); + CHECK( spec.matches( tcD ) == true ); + } + +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/CompilationTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/CompilationTests.cpp new file mode 100644 index 0000000..635c62c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/CompilationTests.cpp @@ -0,0 +1,42 @@ +/* + * Created by Martin on 17/02/2017. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + + +// This is a minimal example for an issue we have found in 1.7.0 +struct foo { + int i; +}; + +template +bool operator==(const T& val, foo f){ + return val == f.i; +} + +TEST_CASE("#809") { + foo f; f.i = 42; + REQUIRE(42 == f); +} + +// ------------------------------------------------------------------ +// REQUIRE_THROWS_AS was changed to catch exceptions by const& +// using type traits. This means that this should compile cleanly + +// Provides indirection to prevent unreachable-code warnings +void throws_int(bool b) { + if (b) { + throw 1; + } +} + +TEST_CASE("#542") { + CHECK_THROWS_AS(throws_int(true), int); + CHECK_THROWS_AS(throws_int(true), int&); + CHECK_THROWS_AS(throws_int(true), const int); + CHECK_THROWS_AS(throws_int(true), const int&); +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ConditionTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ConditionTests.cpp new file mode 100644 index 0000000..2eb99ba --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ConditionTests.cpp @@ -0,0 +1,326 @@ +/* + * Created by Phil on 08/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifdef __clang__ +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wc++98-compat" +#endif + +#include "catch.hpp" + +#include +#include + +struct TestData { + TestData() + : int_seven( 7 ), + str_hello( "hello" ), + float_nine_point_one( 9.1f ), + double_pi( 3.1415926535 ) + {} + + int int_seven; + std::string str_hello; + float float_nine_point_one; + double double_pi; +}; + + +struct TestDef { + TestDef& operator + ( const std::string& ) { + return *this; + } + TestDef& operator[]( const std::string& ) { + return *this; + } + +}; + +// The "failing" tests all use the CHECK macro, which continues if the specific test fails. +// This allows us to see all results, even if an earlier check fails + +// Equality tests +TEST_CASE( "Equality checks that should succeed", "" ) +{ + + TestDef td; + td + "hello" + "hello"; + + TestData data; + + REQUIRE( data.int_seven == 7 ); + REQUIRE( data.float_nine_point_one == Approx( 9.1f ) ); + REQUIRE( data.double_pi == Approx( 3.1415926535 ) ); + REQUIRE( data.str_hello == "hello" ); + REQUIRE( "hello" == data.str_hello ); + REQUIRE( data.str_hello.size() == 5 ); + + double x = 1.1 + 0.1 + 0.1; + REQUIRE( x == Approx( 1.3 ) ); +} + +TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" ) +{ + TestData data; + + CHECK( data.int_seven == 6 ); + CHECK( data.int_seven == 8 ); + CHECK( data.int_seven == 0 ); + CHECK( data.float_nine_point_one == Approx( 9.11f ) ); + CHECK( data.float_nine_point_one == Approx( 9.0f ) ); + CHECK( data.float_nine_point_one == Approx( 1 ) ); + CHECK( data.float_nine_point_one == Approx( 0 ) ); + CHECK( data.double_pi == Approx( 3.1415 ) ); + CHECK( data.str_hello == "goodbye" ); + CHECK( data.str_hello == "hell" ); + CHECK( data.str_hello == "hello1" ); + CHECK( data.str_hello.size() == 6 ); + + double x = 1.1 + 0.1 + 0.1; + CHECK( x == Approx( 1.301 ) ); +} + +TEST_CASE( "Inequality checks that should succeed", "" ) +{ + TestData data; + + REQUIRE( data.int_seven != 6 ); + REQUIRE( data.int_seven != 8 ); + REQUIRE( data.float_nine_point_one != Approx( 9.11f ) ); + REQUIRE( data.float_nine_point_one != Approx( 9.0f ) ); + REQUIRE( data.float_nine_point_one != Approx( 1 ) ); + REQUIRE( data.float_nine_point_one != Approx( 0 ) ); + REQUIRE( data.double_pi != Approx( 3.1415 ) ); + REQUIRE( data.str_hello != "goodbye" ); + REQUIRE( data.str_hello != "hell" ); + REQUIRE( data.str_hello != "hello1" ); + REQUIRE( data.str_hello.size() != 6 ); +} + +TEST_CASE( "Inequality checks that should fail", "[.][failing][!shouldfail]" ) +{ + TestData data; + + CHECK( data.int_seven != 7 ); + CHECK( data.float_nine_point_one != Approx( 9.1f ) ); + CHECK( data.double_pi != Approx( 3.1415926535 ) ); + CHECK( data.str_hello != "hello" ); + CHECK( data.str_hello.size() != 5 ); +} + +// Ordering comparison tests +TEST_CASE( "Ordering comparison checks that should succeed", "" ) +{ + TestData data; + + REQUIRE( data.int_seven < 8 ); + REQUIRE( data.int_seven > 6 ); + REQUIRE( data.int_seven > 0 ); + REQUIRE( data.int_seven > -1 ); + + REQUIRE( data.int_seven >= 7 ); + REQUIRE( data.int_seven >= 6 ); + REQUIRE( data.int_seven <= 7 ); + REQUIRE( data.int_seven <= 8 ); + + REQUIRE( data.float_nine_point_one > 9 ); + REQUIRE( data.float_nine_point_one < 10 ); + REQUIRE( data.float_nine_point_one < 9.2 ); + + REQUIRE( data.str_hello <= "hello" ); + REQUIRE( data.str_hello >= "hello" ); + + REQUIRE( data.str_hello < "hellp" ); + REQUIRE( data.str_hello < "zebra" ); + REQUIRE( data.str_hello > "hellm" ); + REQUIRE( data.str_hello > "a" ); +} + +TEST_CASE( "Ordering comparison checks that should fail", "[.][failing]" ) +{ + TestData data; + + CHECK( data.int_seven > 7 ); + CHECK( data.int_seven < 7 ); + CHECK( data.int_seven > 8 ); + CHECK( data.int_seven < 6 ); + CHECK( data.int_seven < 0 ); + CHECK( data.int_seven < -1 ); + + CHECK( data.int_seven >= 8 ); + CHECK( data.int_seven <= 6 ); + + CHECK( data.float_nine_point_one < 9 ); + CHECK( data.float_nine_point_one > 10 ); + CHECK( data.float_nine_point_one > 9.2 ); + + CHECK( data.str_hello > "hello" ); + CHECK( data.str_hello < "hello" ); + CHECK( data.str_hello > "hellp" ); + CHECK( data.str_hello > "z" ); + CHECK( data.str_hello < "hellm" ); + CHECK( data.str_hello < "a" ); + + CHECK( data.str_hello >= "z" ); + CHECK( data.str_hello <= "a" ); +} + +// Comparisons with int literals +TEST_CASE( "Comparisons with int literals don't warn when mixing signed/ unsigned", "" ) +{ + int i = 1; + unsigned int ui = 2; + long l = 3; + unsigned long ul = 4; + char c = 5; + unsigned char uc = 6; + + REQUIRE( i == 1 ); + REQUIRE( ui == 2 ); + REQUIRE( l == 3 ); + REQUIRE( ul == 4 ); + REQUIRE( c == 5 ); + REQUIRE( uc == 6 ); + + REQUIRE( 1 == i ); + REQUIRE( 2 == ui ); + REQUIRE( 3 == l ); + REQUIRE( 4 == ul ); + REQUIRE( 5 == c ); + REQUIRE( 6 == uc ); + + REQUIRE( (std::numeric_limits::max)() > ul ); +} + +// Disable warnings about sign conversions for the next two tests +// (as we are deliberately invoking them) +// - Currently only disabled for GCC/ LLVM. Should add VC++ too +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-compare" +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif +#ifdef _MSC_VER +#pragma warning(disable:4389) // '==' : signed/unsigned mismatch +#endif + +TEST_CASE( "comparisons between int variables", "" ) +{ + long long_var = 1L; + unsigned char unsigned_char_var = 1; + unsigned short unsigned_short_var = 1; + unsigned int unsigned_int_var = 1; + unsigned long unsigned_long_var = 1L; + + REQUIRE( long_var == unsigned_char_var ); + REQUIRE( long_var == unsigned_short_var ); + REQUIRE( long_var == unsigned_int_var ); + REQUIRE( long_var == unsigned_long_var ); +} + +TEST_CASE( "comparisons between const int variables", "" ) +{ + const unsigned char unsigned_char_var = 1; + const unsigned short unsigned_short_var = 1; + const unsigned int unsigned_int_var = 1; + const unsigned long unsigned_long_var = 1L; + + REQUIRE( unsigned_char_var == 1 ); + REQUIRE( unsigned_short_var == 1 ); + REQUIRE( unsigned_int_var == 1 ); + REQUIRE( unsigned_long_var == 1 ); +} + +TEST_CASE( "Comparisons between unsigned ints and negative signed ints match c++ standard behaviour", "" ) +{ + CHECK( ( -1 > 2u ) ); + CHECK( -1 > 2u ); + + CHECK( ( 2u < -1 ) ); + CHECK( 2u < -1 ); + + const int minInt = (std::numeric_limits::min)(); + CHECK( ( minInt > 2u ) ); + CHECK( minInt > 2u ); +} + +TEST_CASE( "Comparisons between ints where one side is computed", "" ) +{ + CHECK( 54 == 6*9 ); +} + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +inline const char* returnsConstNull(){ return CATCH_NULL; } +inline char* returnsNull(){ return CATCH_NULL; } + +TEST_CASE( "Pointers can be compared to null", "" ) +{ + TestData* p = CATCH_NULL; + TestData* pNULL = CATCH_NULL; + + REQUIRE( p == CATCH_NULL ); + REQUIRE( p == pNULL ); + + TestData data; + p = &data; + + REQUIRE( p != CATCH_NULL ); + + const TestData* cp = p; + REQUIRE( cp != CATCH_NULL ); + + const TestData* const cpc = p; + REQUIRE( cpc != CATCH_NULL ); + + REQUIRE( returnsNull() == CATCH_NULL ); + REQUIRE( returnsConstNull() == CATCH_NULL ); + + REQUIRE( CATCH_NULL != p ); +} + +// Not (!) tests +// The problem with the ! operator is that it has right-to-left associativity. +// This means we can't isolate it when we decompose. The simple REQUIRE( !false ) form, therefore, +// cannot have the operand value extracted. The test will work correctly, and the situation +// is detected and a warning issued. +// An alternative form of the macros (CHECK_FALSE and REQUIRE_FALSE) can be used instead to capture +// the operand value. +TEST_CASE( "'Not' checks that should succeed", "" ) +{ + bool falseValue = false; + + REQUIRE( false == false ); + REQUIRE( true == true ); + REQUIRE( !false ); + REQUIRE_FALSE( false ); + + REQUIRE( !falseValue ); + REQUIRE_FALSE( falseValue ); + + REQUIRE( !(1 == 2) ); + REQUIRE_FALSE( 1 == 2 ); +} + +TEST_CASE( "'Not' checks that should fail", "[.][failing]" ) +{ + bool trueValue = true; + + CHECK( false != false ); + CHECK( true != true ); + CHECK( !true ); + CHECK_FALSE( true ); + + CHECK( !trueValue ); + CHECK_FALSE( trueValue ); + + CHECK( !(1 == 1) ); + CHECK_FALSE( 1 == 1 ); +} + diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/EnumToString.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/EnumToString.cpp new file mode 100644 index 0000000..f591520 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/EnumToString.cpp @@ -0,0 +1,76 @@ +#include "catch.hpp" + +/* + TODO: maybe ought to check that user-provided specialisations of + Catch::toString also do the right thing +*/ + +// Enum without user-provided stream operator +enum Enum1 { Enum1Value0, Enum1Value1 }; + +TEST_CASE( "toString(enum)", "[toString][enum]" ) { + Enum1 e0 = Enum1Value0; + CHECK( Catch::toString(e0) == "0" ); + Enum1 e1 = Enum1Value1; + CHECK( Catch::toString(e1) == "1" ); +} + +// Enum with user-provided stream operator +enum Enum2 { Enum2Value0, Enum2Value1 }; + +inline std::ostream& operator<<( std::ostream& os, Enum2 v ) { + return os << "E2{" << static_cast(v) << "}"; +} + +TEST_CASE( "toString(enum w/operator<<)", "[toString][enum]" ) { + Enum2 e0 = Enum2Value0; + CHECK( Catch::toString(e0) == "E2{0}" ); + Enum2 e1 = Enum2Value1; + CHECK( Catch::toString(e1) == "E2{1}" ); +} + +#if defined(CATCH_CPP11_OR_GREATER) +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++98-compat" +#endif + +// Enum class without user-provided stream operator +enum class EnumClass1 { EnumClass1Value0, EnumClass1Value1 }; + +TEST_CASE( "toString(enum class)", "[toString][enum][enumClass][c++11][.]" ) { + EnumClass1 e0 = EnumClass1::EnumClass1Value0; + CHECK( Catch::toString(e0) == "0" ); + EnumClass1 e1 = EnumClass1::EnumClass1Value1; + CHECK( Catch::toString(e1) == "1" ); +} + +// Enum class with user-provided stream operator +enum class EnumClass2 : short { EnumClass2Value0, EnumClass2Value1 }; + +inline std::ostream& operator<<( std::ostream& os, EnumClass2 e2 ) { + switch( static_cast( e2 ) ) { + case static_cast( EnumClass2::EnumClass2Value0 ): + return os << "E2/V0"; + case static_cast( EnumClass2::EnumClass2Value1 ): + return os << "E2/V1"; + default: + return os << "Unknown enum value " << static_cast( e2 ); + } +} + +TEST_CASE( "toString(enum class w/operator<<)", "[toString][enum][enumClass][c++11][.]" ) { + EnumClass2 e0 = EnumClass2::EnumClass2Value0; + CHECK( Catch::toString(e0) == "E2/V0" ); + EnumClass2 e1 = EnumClass2::EnumClass2Value1; + CHECK( Catch::toString(e1) == "E2/V1" ); + + EnumClass2 e3 = static_cast(10); + CHECK( Catch::toString(e3) == "Unknown enum value 10" ); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#endif // CATCH_CPP11_OR_GREATER + diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ExceptionTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ExceptionTests.cpp new file mode 100644 index 0000000..de8f6fa --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ExceptionTests.cpp @@ -0,0 +1,207 @@ +/* + * Created by Phil on 09/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + +#include +#include + +namespace +{ + inline int thisThrows() + { + if( Catch::alwaysTrue() ) + throw std::domain_error( "expected exception" ); + return 1; + } + + int thisDoesntThrow() + { + return 0; + } +} + +TEST_CASE( "When checked exceptions are thrown they can be expected or unexpected", "[!throws]" ) +{ + REQUIRE_THROWS_AS( thisThrows(), std::domain_error ); + REQUIRE_NOTHROW( thisDoesntThrow() ); + REQUIRE_THROWS( thisThrows() ); +} + +TEST_CASE( "Expected exceptions that don't throw or unexpected exceptions fail the test", "[.][failing][!throws]" ) +{ + CHECK_THROWS_AS( thisThrows(), std::string ); + CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error ); + CHECK_NOTHROW( thisThrows() ); +} + +TEST_CASE( "When unchecked exceptions are thrown directly they are always failures", "[.][failing][!throws]" ) +{ + if( Catch::alwaysTrue() ) + throw std::domain_error( "unexpected exception" ); +} + +TEST_CASE( "An unchecked exception reports the line of the last assertion", "[.][failing][!throws]" ) +{ + CHECK( 1 == 1 ); + if( Catch::alwaysTrue() ) + throw std::domain_error( "unexpected exception" ); +} + +TEST_CASE( "When unchecked exceptions are thrown from sections they are always failures", "[.][failing][!throws]" ) +{ + SECTION( "section name", "" ) + { + if( Catch::alwaysTrue() ) + throw std::domain_error( "unexpected exception" ); + } +} + +TEST_CASE( "When unchecked exceptions are thrown from functions they are always failures", "[.][failing][!throws]" ) +{ + CHECK( thisThrows() == 0 ); +} + +TEST_CASE( "When unchecked exceptions are thrown during a REQUIRE the test should abort fail", "[.][failing][!throws]" ) +{ + REQUIRE( thisThrows() == 0 ); + FAIL( "This should never happen" ); +} + +TEST_CASE( "When unchecked exceptions are thrown during a CHECK the test should continue", "[.][failing][!throws]" ) +{ + try { + CHECK(thisThrows() == 0); + } + catch(...) { + FAIL( "This should never happen" ); + } +} + +TEST_CASE( "When unchecked exceptions are thrown, but caught, they do not affect the test", "[!throws]" ) +{ + try + { + throw std::domain_error( "unexpected exception" ); + } + catch(...) + { + } +} + +class CustomException +{ +public: + CustomException( const std::string& msg ) + : m_msg( msg ) + {} + + std::string getMessage() const + { + return m_msg; + } + +private: + std::string m_msg; +}; + +class CustomStdException : public std::exception +{ +public: + CustomStdException( const std::string& msg ) + : m_msg( msg ) + {} + ~CustomStdException() CATCH_NOEXCEPT {} + + std::string getMessage() const + { + return m_msg; + } + +private: + std::string m_msg; +}; + + +CATCH_TRANSLATE_EXCEPTION( CustomException& ex ) +{ + return ex.getMessage(); +} + +CATCH_TRANSLATE_EXCEPTION( CustomStdException& ex ) +{ + return ex.getMessage(); +} + +CATCH_TRANSLATE_EXCEPTION( double& ex ) +{ + return Catch::toString( ex ); +} + +TEST_CASE("Non-std exceptions can be translated", "[.][failing][!throws]" ) +{ + if( Catch::alwaysTrue() ) + throw CustomException( "custom exception" ); +} + +TEST_CASE("Custom std-exceptions can be custom translated", "[.][failing][!throws]" ) +{ + if( Catch::alwaysTrue() ) + throw CustomException( "custom std exception" ); +} + +inline void throwCustom() { + if( Catch::alwaysTrue() ) + throw CustomException( "custom exception - not std" ); +} + +TEST_CASE( "Custom exceptions can be translated when testing for nothrow", "[.][failing][!throws]" ) +{ + REQUIRE_NOTHROW( throwCustom() ); +} + +TEST_CASE( "Custom exceptions can be translated when testing for throwing as something else", "[.][failing][!throws]" ) +{ + REQUIRE_THROWS_AS( throwCustom(), std::exception ); +} + + +TEST_CASE( "Unexpected exceptions can be translated", "[.][failing][!throws]" ) +{ + if( Catch::alwaysTrue() ) + throw double( 3.14 ); +} + +inline int thisFunctionNotImplemented( int ) { + CATCH_NOT_IMPLEMENTED; +} + +TEST_CASE( "NotImplemented exception", "[!throws]" ) +{ + REQUIRE_THROWS( thisFunctionNotImplemented( 7 ) ); +} + +TEST_CASE( "Exception messages can be tested for", "[!throws]" ) { + using namespace Catch::Matchers; + SECTION( "exact match" ) + REQUIRE_THROWS_WITH( thisThrows(), "expected exception" ); + SECTION( "different case" ) + REQUIRE_THROWS_WITH( thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) ); + SECTION( "wildcarded" ) { + REQUIRE_THROWS_WITH( thisThrows(), StartsWith( "expected" ) ); + REQUIRE_THROWS_WITH( thisThrows(), EndsWith( "exception" ) ); + REQUIRE_THROWS_WITH( thisThrows(), Contains( "except" ) ); + REQUIRE_THROWS_WITH( thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) ); + } +} + +TEST_CASE( "Mismatching exception messages failing the test", "[.][failing][!throws]" ) { + REQUIRE_THROWS_WITH( thisThrows(), "expected exception" ); + REQUIRE_THROWS_WITH( thisThrows(), "should fail" ); + REQUIRE_THROWS_WITH( thisThrows(), "expected exception" ); +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/GeneratorTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/GeneratorTests.cpp new file mode 100644 index 0000000..af08b1d --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/GeneratorTests.cpp @@ -0,0 +1,42 @@ +/* + * Created by Phil on 28/01/2011. + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// This define means we have to prefix all the CATCH macros with CATCH_ +// We're using it here to test it out +#define CATCH_CONFIG_PREFIX_ALL +#include "catch.hpp" + +inline int multiply( int a, int b ) +{ + return a*b; +} + +CATCH_TEST_CASE( "Generators over two ranges", "[generators]" ) +{ + using namespace Catch::Generators; + + int i = CATCH_GENERATE( between( 1, 5 ).then( values( 15, 20, 21 ).then( 36 ) ) ); + int j = CATCH_GENERATE( between( 100, 107 ) ); + + CATCH_REQUIRE( multiply( i, 2 ) == i*2 ); + CATCH_REQUIRE( multiply( j, 2 ) == j*2 ); +} + +struct IntPair { int first, second; }; + +CATCH_TEST_CASE( "Generator over a range of pairs", "[generators]" ) +{ + using namespace Catch::Generators; + + IntPair p[] = { { 0, 1 }, { 2, 3 } }; + + IntPair* i = CATCH_GENERATE( between( p, &p[1] ) ); + + CATCH_REQUIRE( i->first == i->second-1 ); + +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/MatchersTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/MatchersTests.cpp new file mode 100644 index 0000000..7bcd3cf --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/MatchersTests.cpp @@ -0,0 +1,168 @@ +/* + * Created by Phil on 21/02/2017. + * Copyright 2017 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + +inline const char* testStringForMatching() +{ + return "this string contains 'abc' as a substring"; +} +inline const char* testStringForMatching2() +{ + return "some completely different text that contains one common word"; +} + +using namespace Catch::Matchers; + +TEST_CASE("String matchers", "[matchers]" ) +{ + REQUIRE_THAT( testStringForMatching(), Contains( "string" ) ); + CHECK_THAT( testStringForMatching(), Contains( "abc" ) ); + + CHECK_THAT( testStringForMatching(), StartsWith( "this" ) ); + CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) ); +} + +TEST_CASE("Contains string matcher", "[.][failing][matchers]") +{ + CHECK_THAT( testStringForMatching(), Contains( "not there" ) ); +} + +TEST_CASE("StartsWith string matcher", "[.][failing][matchers]") +{ + CHECK_THAT( testStringForMatching(), StartsWith( "string" ) ); +} + +TEST_CASE("EndsWith string matcher", "[.][failing][matchers]") +{ + CHECK_THAT( testStringForMatching(), EndsWith( "this" ) ); +} + +TEST_CASE("Equals string matcher", "[.][failing][matchers]") +{ + CHECK_THAT( testStringForMatching(), Equals( "something else" ) ); +} + +TEST_CASE("AllOf matcher", "[matchers]") +{ + CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) ); +} +TEST_CASE("AnyOf matcher", "[matchers]") +{ + CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) ); + CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) ); +} + +TEST_CASE("Equals", "[matchers]") +{ + CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) ); +} + +TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]") +{ + CHECK_THAT( testStringForMatching(), + Contains( "string" ) && + Contains( "abc" ) && + Contains( "substring" ) && + Contains( "contains" ) ); +} + +TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]") +{ + CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) ); + CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) ); +} + +TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]") +{ + CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) ); +} + +TEST_CASE("Matchers can be composed with both && and || - failing", "[matchers][operators][operator||][operator&&][.failing]") +{ + CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) ); +} + +TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]") +{ + CHECK_THAT( testStringForMatching(), !Contains( "different" ) ); +} + +TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", "[matchers][operators][not][.failing]") +{ + CHECK_THAT( testStringForMatching(), !Contains( "substring" ) ); +} + +TEST_CASE( "Vector matchers", "[matchers][vector]" ) { + std::vector v; + v.push_back( 1 ); + v.push_back( 2 ); + v.push_back( 3 ); + + std::vector v2; + v2.push_back( 1 ); + v2.push_back( 2 ); + + std::vector empty; + + SECTION( "Contains (element)" ) { + CHECK_THAT( v, VectorContains( 1 ) ); + CHECK_THAT( v, VectorContains( 2 ) ); + } + SECTION( "Contains (vector)" ) { + CHECK_THAT( v, Contains( v2 ) ); + v2.push_back( 3 ); // now exactly matches + CHECK_THAT( v, Contains( v2 ) ); + + CHECK_THAT( v, Contains( empty) ); + CHECK_THAT( empty, Contains( empty) ); + } + + SECTION( "Equals" ) { + + // Same vector + CHECK_THAT( v, Equals( v ) ); + + CHECK_THAT( empty, Equals( empty ) ); + + // Different vector with same elements + v2.push_back( 3 ); + CHECK_THAT( v, Equals( v2 ) ); + } +} + +TEST_CASE( "Vector matchers that fail", "[matchers][vector][.][failing]" ) { + std::vector v; + v.push_back( 1 ); + v.push_back( 2 ); + v.push_back( 3 ); + + std::vector v2; + v2.push_back( 1 ); + v2.push_back( 2 ); + + std::vector empty; + + SECTION( "Contains (element)" ) { + CHECK_THAT( v, VectorContains( -1 ) ); + CHECK_THAT( empty, VectorContains( 1 ) ); + } + SECTION( "Contains (vector)" ) { + CHECK_THAT( empty, Contains( v) ); + v2.push_back( 4 ); + CHECK_THAT( v, Contains( v2 ) ); + } + + SECTION( "Equals" ) { + + CHECK_THAT( v, Equals( v2 ) ); + CHECK_THAT( v2, Equals( v ) ); + CHECK_THAT( empty, Equals( v ) ); + CHECK_THAT( v, Equals( empty ) ); + } +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/MessageTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/MessageTests.cpp new file mode 100644 index 0000000..87a85a8 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/MessageTests.cpp @@ -0,0 +1,133 @@ +/* + * Created by Phil on 09/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" +#include + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +TEST_CASE( "INFO and WARN do not abort tests", "[messages][.]" ) +{ + INFO( "this is a " << "message" ); // This should output the message if a failure occurs + WARN( "this is a " << "warning" ); // This should always output the message but then continue +} +TEST_CASE( "SUCCEED counts as a test pass", "[messages]" ) +{ + SUCCEED( "this is a " << "success" ); +} + +TEST_CASE( "INFO gets logged on failure", "[failing][messages][.]" ) +{ + INFO( "this message should be logged" ); + INFO( "so should this" ); + int a = 2; + REQUIRE( a == 1 ); +} + +TEST_CASE( "INFO gets logged on failure, even if captured before successful assertions", "[failing][messages][.]" ) +{ + INFO( "this message may be logged later" ); + int a = 2; + CHECK( a == 2 ); + + INFO( "this message should be logged" ); + + CHECK( a == 1 ); + + INFO( "and this, but later" ); + + CHECK( a == 0 ); + + INFO( "but not this" ); + + CHECK( a == 2 ); +} + +TEST_CASE( "FAIL aborts the test", "[failing][messages][.]" ) +{ + FAIL( "This is a " << "failure" ); // This should output the message and abort +} + +#ifdef CATCH_CONFIG_VARIADIC_MACROS +TEST_CASE( "FAIL does not require an argument", "[failing][messages][.]" ) +{ + FAIL(); +} +TEST_CASE( "SUCCESS does not require an argument", "[messages][.]" ) +{ + SUCCEED(); +} +#endif + +TEST_CASE( "Output from all sections is reported", "[failing][messages][.]" ) +{ + SECTION( "one", "" ) + { + FAIL( "Message from section one" ); + } + + SECTION( "two", "" ) + { + FAIL( "Message from section two" ); + } +} + +TEST_CASE( "Standard output from all sections is reported", "[messages][.]" ) +{ + SECTION( "one", "" ) + { + std::cout << "Message from section one" << std::endl; + } + + SECTION( "two", "" ) + { + std::cout << "Message from section two" << std::endl; + } +} + +TEST_CASE( "SCOPED_INFO is reset for each loop", "[messages][failing][.]" ) +{ + for( int i=0; i<100; i++ ) + { + SCOPED_INFO( "current counter " << i ); + SCOPED_CAPTURE( i ); + REQUIRE( i < 10 ); + } +} + +TEST_CASE( "The NO_FAIL macro reports a failure but does not fail the test", "[messages]" ) +{ + CHECK_NOFAIL( 1 == 2 ); +} + +TEST_CASE( "just info", "[info][isolated info][messages]" ) +{ + INFO( "this should never be seen" ); +} +TEST_CASE( "just failure", "[fail][isolated info][.][messages]" ) +{ + FAIL( "Previous info should not be seen" ); +} + + +TEST_CASE( "sends information to INFO", "[.][failing]" ) +{ + INFO( "hi" ); + int i = 7; + CAPTURE( i ); + REQUIRE( false ); +} + +TEST_CASE( "Pointers can be converted to strings", "[messages][.]" ) +{ + int p; + WARN( "actual address of p: " << &p ); + WARN( "toString(p): " << Catch::toString( &p ) ); +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/MiscTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/MiscTests.cpp new file mode 100644 index 0000000..88a524f --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/MiscTests.cpp @@ -0,0 +1,395 @@ +/* + * Created by Phil on 29/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Wc++98-compat" +# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +#include "../include/internal/catch_xmlwriter.hpp" + +#include + +TEST_CASE( "random SECTION tests", "[.][sections][failing]" ) +{ + int a = 1; + int b = 2; + + SECTION( "s1", "doesn't equal" ) + { + REQUIRE( a != b ); + REQUIRE( b != a ); + } + + SECTION( "s2", "not equal" ) + { + REQUIRE( a != b); + } +} + +TEST_CASE( "nested SECTION tests", "[.][sections][failing]" ) +{ + int a = 1; + int b = 2; + + SECTION( "s1", "doesn't equal" ) + { + REQUIRE( a != b ); + REQUIRE( b != a ); + + SECTION( "s2", "not equal" ) + { + REQUIRE( a != b); + } + } +} + +TEST_CASE( "more nested SECTION tests", "[sections][failing][.]" ) +{ + int a = 1; + int b = 2; + + SECTION( "s1", "doesn't equal" ) + { + SECTION( "s2", "equal" ) + { + REQUIRE( a == b ); + } + + SECTION( "s3", "not equal" ) + { + REQUIRE( a != b ); + } + SECTION( "s4", "less than" ) + { + REQUIRE( a < b ); + } + } +} + +TEST_CASE( "even more nested SECTION tests", "[sections]" ) +{ + SECTION( "c", "" ) + { + SECTION( "d (leaf)", "" ) + { + SUCCEED(""); // avoid failing due to no tests + } + + SECTION( "e (leaf)", "" ) + { + SUCCEED(""); // avoid failing due to no tests + } + } + + SECTION( "f (leaf)", "" ) + { + SUCCEED(""); // avoid failing due to no tests + } +} + +TEST_CASE( "looped SECTION tests", "[.][failing][sections]" ) +{ + int a = 1; + + for( int b = 0; b < 10; ++b ) + { + std::ostringstream oss; + oss << "b is currently: " << b; + SECTION( "s1", oss.str() ) + { + CHECK( b > a ); + } + } +} + +TEST_CASE( "looped tests", "[.][failing]" ) +{ + static const int fib[] = { 1, 1, 2, 3, 5, 8, 13, 21 }; + + for( size_t i=0; i < sizeof(fib)/sizeof(int); ++i ) + { + INFO( "Testing if fib[" << i << "] (" << fib[i] << ") is even" ); + CHECK( ( fib[i] % 2 ) == 0 ); + } +} + +TEST_CASE( "Sends stuff to stdout and stderr", "[.]" ) +{ + std::cout << "A string sent directly to stdout" << std::endl; + + std::cerr << "A string sent directly to stderr" << std::endl; +} + +inline const char* makeString( bool makeNull ) +{ + return makeNull ? CATCH_NULL : "valid string"; +} + +TEST_CASE( "null strings", "" ) +{ + REQUIRE( makeString( false ) != static_cast(CATCH_NULL)); + REQUIRE( makeString( true ) == static_cast(CATCH_NULL)); +} + + +inline bool testCheckedIf( bool flag ) +{ + CHECKED_IF( flag ) + return true; + else + return false; +} + +TEST_CASE( "checkedIf", "" ) +{ + REQUIRE( testCheckedIf( true ) ); +} + +TEST_CASE( "checkedIf, failing", "[failing][.]" ) +{ + REQUIRE( testCheckedIf( false ) ); +} + +inline bool testCheckedElse( bool flag ) +{ + CHECKED_ELSE( flag ) + return false; + + return true; +} + +TEST_CASE( "checkedElse", "" ) +{ + REQUIRE( testCheckedElse( true ) ); +} + +TEST_CASE( "checkedElse, failing", "[failing][.]" ) +{ + REQUIRE( testCheckedElse( false ) ); +} + +TEST_CASE( "xmlentitycheck", "" ) +{ + SECTION( "embedded xml", "it should be possible to embed xml characters, such as <, \" or &, or even whole documents within an attribute" ) + { + SUCCEED(""); // We need this here to stop it failing due to no tests + } + SECTION( "encoded chars", "these should all be encoded: &&&\"\"\"<<<&\"<<&\"" ) + { + SUCCEED(""); // We need this here to stop it failing due to no tests + } +} + +TEST_CASE( "send a single char to INFO", "[failing][.]" ) +{ + INFO(3); + REQUIRE(false); +} + +TEST_CASE( "atomic if", "[failing][0]") +{ + size_t x = 0; + + if( x ) + REQUIRE(x > 0); + else + REQUIRE(x == 0); +} + +inline unsigned int Factorial( unsigned int number ) +{ +// return number <= 1 ? number : Factorial(number-1)*number; + return number > 1 ? Factorial(number-1)*number : 1; +} + +TEST_CASE( "Factorials are computed", "[factorial]" ) { + REQUIRE( Factorial(0) == 1 ); + REQUIRE( Factorial(1) == 1 ); + REQUIRE( Factorial(2) == 2 ); + REQUIRE( Factorial(3) == 6 ); + REQUIRE( Factorial(10) == 3628800 ); +} + +TEST_CASE( "An empty test with no assertions", "[empty]" ) +{ +} + +TEST_CASE( "Nice descriptive name", "[tag1][tag2][tag3][.]" ) +{ + WARN( "This one ran" ); +} +TEST_CASE( "first tag", "[tag1]" ) +{ +} +TEST_CASE( "second tag", "[tag2]" ) +{ +} +// +//TEST_CASE( "spawn a new process", "[.]" ) +//{ +// // !TBD Work in progress +// char line[200]; +// FILE* output = popen("./CatchSelfTest ./failing/matchers/StartsWith", "r"); +// while ( fgets(line, 199, output) ) +// std::cout << line; +//} + +TEST_CASE( "vectors can be sized and resized", "[vector]" ) { + + std::vector v( 5 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 5 ); + + SECTION( "resizing bigger changes size and capacity", "" ) { + v.resize( 10 ); + + REQUIRE( v.size() == 10 ); + REQUIRE( v.capacity() >= 10 ); + } + SECTION( "resizing smaller changes size but not capacity", "" ) { + v.resize( 0 ); + + REQUIRE( v.size() == 0 ); + REQUIRE( v.capacity() >= 5 ); + + SECTION( "We can use the 'swap trick' to reset the capacity", "" ) { + std::vector empty; + empty.swap( v ); + + REQUIRE( v.capacity() == 0 ); + } + } + SECTION( "reserving bigger changes capacity but not size", "" ) { + v.reserve( 10 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 10 ); + } + SECTION( "reserving smaller does not change size or capacity", "" ) { + v.reserve( 0 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 5 ); + } +} + +// https://github.com/philsquared/Catch/issues/166 +TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]") +{ + SECTION("Outer", "") + SECTION("Inner", "") + SUCCEED("that's not flying - that's failing in style"); + + FAIL("to infinity and beyond"); +} + +TEST_CASE("not allowed", "[!throws]") +{ + // This test case should not be included if you run with -e on the command line + SUCCEED( "" ); +} + +//TEST_CASE( "Is big endian" ) { +// CHECK( Catch::Detail::Endianness::which() == Catch::Detail::Endianness::Little ); +//} + +TEST_CASE( "Tabs and newlines show in output", "[.][whitespace][failing]" ) { + + // Based on issue #242 + std::string s1 = "if ($b == 10) {\n\t\t$a\t= 20;\n}"; + std::string s2 = "if ($b == 10) {\n\t$a = 20;\n}\n"; + CHECK( s1 == s2 ); +} + + +TEST_CASE( "toString on const wchar_t const pointer returns the string contents", "[toString]" ) { + const wchar_t * const s = L"wide load"; + std::string result = Catch::toString( s ); + CHECK( result == "\"wide load\"" ); +} + +TEST_CASE( "toString on const wchar_t pointer returns the string contents", "[toString]" ) { + const wchar_t * s = L"wide load"; + std::string result = Catch::toString( s ); + CHECK( result == "\"wide load\"" ); +} + +TEST_CASE( "toString on wchar_t const pointer returns the string contents", "[toString]" ) { + wchar_t * const s = const_cast( L"wide load" ); + std::string result = Catch::toString( s ); + CHECK( result == "\"wide load\"" ); +} + +TEST_CASE( "toString on wchar_t returns the string contents", "[toString]" ) { + wchar_t * s = const_cast( L"wide load" ); + std::string result = Catch::toString( s ); + CHECK( result == "\"wide load\"" ); +} + +inline std::string encode( std::string const& str, Catch::XmlEncode::ForWhat forWhat = Catch::XmlEncode::ForTextNodes ) { + std::ostringstream oss; + oss << Catch::XmlEncode( str, forWhat ); + return oss.str(); +} + +TEST_CASE( "XmlEncode" ) { + SECTION( "normal string" ) { + REQUIRE( encode( "normal string" ) == "normal string" ); + } + SECTION( "empty string" ) { + REQUIRE( encode( "" ) == "" ); + } + SECTION( "string with ampersand" ) { + REQUIRE( encode( "smith & jones" ) == "smith & jones" ); + } + SECTION( "string with less-than" ) { + REQUIRE( encode( "smith < jones" ) == "smith < jones" ); + } + SECTION( "string with greater-than" ) { + REQUIRE( encode( "smith > jones" ) == "smith > jones" ); + REQUIRE( encode( "smith ]]> jones" ) == "smith ]]> jones" ); + } + SECTION( "string with quotes" ) { + std::string stringWithQuotes = "don't \"quote\" me on that"; + REQUIRE( encode( stringWithQuotes ) == stringWithQuotes ); + REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't "quote" me on that" ); + } + SECTION( "string with control char (1)" ) { + REQUIRE( encode( "[\x01]" ) == "[\\x01]" ); + } + SECTION( "string with control char (x7F)" ) { + REQUIRE( encode( "[\x7F]" ) == "[\\x7F]" ); + } +} + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG +TEST_CASE( "long long", "[c++11][.]" ) { + long long l = std::numeric_limits::max(); + + REQUIRE( l == std::numeric_limits::max() ); +} +#endif + +//TEST_CASE( "Divide by Zero signal handler", "[.][sig]" ) { +// int i = 0; +// int x = 10/i; // This should cause the signal to fire +// CHECK( x == 0 ); +//} + +TEST_CASE( "This test 'should' fail but doesn't", "[.][failing][!shouldfail]" ) +{ + SUCCEED( "oops!" ); +} + +TEST_CASE( "# A test name that starts with a #" ) { + SUCCEED( "yay" ); +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/PartTrackerTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/PartTrackerTests.cpp new file mode 100644 index 0000000..45f4cf1 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/PartTrackerTests.cpp @@ -0,0 +1,333 @@ +/* + * Created by Phil on 1/10/2015. + * Copyright 2015 Two Blue Cubes Ltd + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_test_case_tracker.hpp" + + +namespace Catch +{ + class LocalContext { + + public: + TrackerContext& operator()() const { + return TrackerContext::instance(); + } + }; + +} // namespace Catch + +inline Catch::TrackerContext& C_A_T_C_H_Context() { + return Catch::TrackerContext::instance(); +} + +// ------------------- + +#include "catch.hpp" + +using namespace Catch; + +//inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) { +// +// REQUIRE( C_A_T_C_H_Context().i() == 42 ); +//} + +Catch::TestCaseTracking::NameAndLocation makeNAL( std::string const& name ) { + return Catch::TestCaseTracking::NameAndLocation( name, Catch::SourceLineInfo() ); +} + +TEST_CASE( "Tracker", "" ) { + + TrackerContext ctx; + ctx.startRun(); + ctx.startCycle(); + + + ITracker& testCase = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); + REQUIRE( testCase.isOpen() ); + + ITracker& s1 = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); + REQUIRE( s1.isOpen() ); + + SECTION( "successfully close one section", "" ) { + s1.close(); + REQUIRE( s1.isSuccessfullyCompleted() ); + REQUIRE( testCase.isComplete() == false ); + + testCase.close(); + REQUIRE( ctx.completedCycle() ); + REQUIRE( testCase.isSuccessfullyCompleted() ); + } + + SECTION( "fail one section", "" ) { + s1.fail(); + REQUIRE( s1.isComplete() ); + REQUIRE( s1.isSuccessfullyCompleted() == false ); + REQUIRE( testCase.isComplete() == false ); + + testCase.close(); + REQUIRE( ctx.completedCycle() ); + REQUIRE( testCase.isSuccessfullyCompleted() == false ); + + SECTION( "re-enter after failed section", "" ) { + ctx.startCycle(); + ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); + REQUIRE( testCase2.isOpen() ); + + ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); + REQUIRE( s1b.isOpen() == false ); + + testCase2.close(); + REQUIRE( ctx.completedCycle() ); + REQUIRE( testCase.isComplete() ); + REQUIRE( testCase.isSuccessfullyCompleted() ); + } + SECTION( "re-enter after failed section and find next section", "" ) { + ctx.startCycle(); + ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); + REQUIRE( testCase2.isOpen() ); + + ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); + REQUIRE( s1b.isOpen() == false ); + + ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); + REQUIRE( s2.isOpen() ); + + s2.close(); + REQUIRE( ctx.completedCycle() ); + + testCase2.close(); + REQUIRE( testCase.isComplete() ); + REQUIRE( testCase.isSuccessfullyCompleted() ); + } + } + + SECTION( "successfully close one section, then find another", "" ) { + s1.close(); + + ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); + REQUIRE( s2.isOpen() == false ); + + testCase.close(); + REQUIRE( testCase.isComplete() == false ); + + SECTION( "Re-enter - skips S1 and enters S2", "" ) { + ctx.startCycle(); + ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); + REQUIRE( testCase2.isOpen() ); + + ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); + REQUIRE( s1b.isOpen() == false ); + + ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); + REQUIRE( s2b.isOpen() ); + + REQUIRE( ctx.completedCycle() == false ); + + SECTION ("Successfully close S2") { + s2b.close(); + REQUIRE( ctx.completedCycle() ); + + REQUIRE( s2b.isSuccessfullyCompleted() ); + REQUIRE( testCase2.isComplete() == false ); + + testCase2.close(); + REQUIRE( testCase2.isSuccessfullyCompleted() ); + } + SECTION ("fail S2") { + s2b.fail(); + REQUIRE( ctx.completedCycle() ); + + REQUIRE( s2b.isComplete() ); + REQUIRE( s2b.isSuccessfullyCompleted() == false ); + + testCase2.close(); + REQUIRE( testCase2.isSuccessfullyCompleted() == false ); + + // Need a final cycle + ctx.startCycle(); + ITracker& testCase3 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); + REQUIRE( testCase3.isOpen() ); + + ITracker& s1c = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); + REQUIRE( s1c.isOpen() == false ); + + ITracker& s2c = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); + REQUIRE( s2c.isOpen() == false ); + + testCase3.close(); + REQUIRE( testCase3.isSuccessfullyCompleted() ); + } + } + } + + SECTION( "open a nested section", "" ) { + ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); + REQUIRE( s2.isOpen() ); + + s2.close(); + REQUIRE( s2.isComplete() ); + REQUIRE( s1.isComplete() == false ); + + s1.close(); + REQUIRE( s1.isComplete() ); + REQUIRE( testCase.isComplete() == false ); + + testCase.close(); + REQUIRE( testCase.isComplete() ); + } + + SECTION( "start a generator", "" ) { + IndexTracker& g1 = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 ); + REQUIRE( g1.isOpen() ); + REQUIRE( g1.index() == 0 ); + + REQUIRE( g1.isComplete() == false ); + REQUIRE( s1.isComplete() == false ); + + SECTION( "close outer section" ) + { + s1.close(); + REQUIRE( s1.isComplete() == false ); + testCase.close(); + REQUIRE( testCase.isSuccessfullyCompleted() == false ); + + SECTION( "Re-enter for second generation", "" ) { + ctx.startCycle(); + ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); + REQUIRE( testCase2.isOpen() ); + + ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); + REQUIRE( s1b.isOpen() ); + + + IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 ); + REQUIRE( g1b.isOpen() ); + REQUIRE( g1b.index() == 1 ); + + REQUIRE( s1.isComplete() == false ); + + s1b.close(); + REQUIRE( s1b.isComplete() ); + REQUIRE( g1b.isComplete() ); + testCase2.close(); + REQUIRE( testCase2.isComplete() ); + } + } + SECTION( "Start a new inner section", "" ) { + ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); + REQUIRE( s2.isOpen() ); + + s2.close(); + REQUIRE( s2.isComplete() ); + + s1.close(); + REQUIRE( s1.isComplete() == false ); + + testCase.close(); + REQUIRE( testCase.isComplete() == false ); + + SECTION( "Re-enter for second generation", "" ) { + ctx.startCycle(); + ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); + REQUIRE( testCase2.isOpen() ); + + ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); + REQUIRE( s1b.isOpen() ); + + // generator - next value + IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 ); + REQUIRE( g1b.isOpen() ); + REQUIRE( g1b.index() == 1 ); + + // inner section again + ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); + REQUIRE( s2b.isOpen() ); + + s2b.close(); + REQUIRE( s2b.isComplete() ); + + s1b.close(); + REQUIRE( g1b.isComplete() ); + REQUIRE( s1b.isComplete() ); + + testCase2.close(); + REQUIRE( testCase2.isComplete() ); + } + } + + SECTION( "Fail an inner section", "" ) { + ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); + REQUIRE( s2.isOpen() ); + + s2.fail(); + REQUIRE( s2.isComplete() ); + REQUIRE( s2.isSuccessfullyCompleted() == false ); + + s1.close(); + REQUIRE( s1.isComplete() == false ); + + testCase.close(); + REQUIRE( testCase.isComplete() == false ); + + SECTION( "Re-enter for second generation", "" ) { + ctx.startCycle(); + ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); + REQUIRE( testCase2.isOpen() ); + + ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); + REQUIRE( s1b.isOpen() ); + + // generator - still same value + IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 ); + REQUIRE( g1b.isOpen() ); + REQUIRE( g1b.index() == 0 ); + + // inner section again - this time won't open + ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); + REQUIRE( s2b.isOpen() == false ); + + s1b.close(); + REQUIRE( g1b.isComplete() == false ); + REQUIRE( s1b.isComplete() == false ); + + testCase2.close(); + REQUIRE( testCase2.isComplete() == false ); + + // Another cycle - now should complete + ctx.startCycle(); + ITracker& testCase3 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); + REQUIRE( testCase3.isOpen() ); + + ITracker& s1c = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); + REQUIRE( s1c.isOpen() ); + + // generator - now next value + IndexTracker& g1c = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 ); + REQUIRE( g1c.isOpen() ); + REQUIRE( g1c.index() == 1 ); + + // inner section - now should open again + ITracker& s2c = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); + REQUIRE( s2c.isOpen() ); + + s2c.close(); + REQUIRE( s2c.isComplete() ); + + s1c.close(); + REQUIRE( g1c.isComplete() ); + REQUIRE( s1c.isComplete() ); + + testCase3.close(); + REQUIRE( testCase3.isComplete() ); + } + } + // !TBD" + // nested generator + // two sections within a generator + } +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_common.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_common.cpp new file mode 100644 index 0000000..65377f3 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_common.cpp @@ -0,0 +1,3 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_common.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_console_colour.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_console_colour.cpp new file mode 100644 index 0000000..c28aa01 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_console_colour.cpp @@ -0,0 +1,3 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_console_colour.hpp" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_debugger.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_debugger.cpp new file mode 100644 index 0000000..04f4e07 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_debugger.cpp @@ -0,0 +1,2 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_debugger.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_capture.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_capture.cpp new file mode 100644 index 0000000..f46dae4 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_capture.cpp @@ -0,0 +1,3 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_interfaces_capture.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_config.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_config.cpp new file mode 100644 index 0000000..46f80e8 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_config.cpp @@ -0,0 +1,2 @@ +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_interfaces_config.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_exception.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_exception.cpp new file mode 100644 index 0000000..f5ad487 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_exception.cpp @@ -0,0 +1,2 @@ +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_interfaces_exception.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_generators.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_generators.cpp new file mode 100644 index 0000000..2eda981 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_generators.cpp @@ -0,0 +1 @@ +#include "internal/catch_interfaces_generators.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_registry_hub.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_registry_hub.cpp new file mode 100644 index 0000000..b399d86 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_registry_hub.cpp @@ -0,0 +1,3 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_interfaces_registry_hub.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_reporter.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_reporter.cpp new file mode 100644 index 0000000..f3c7158 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_reporter.cpp @@ -0,0 +1,2 @@ +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_interfaces_reporter.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_runner.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_runner.cpp new file mode 100644 index 0000000..800f32a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_runner.cpp @@ -0,0 +1 @@ +#include "internal/catch_interfaces_runner.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_testcase.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_testcase.cpp new file mode 100644 index 0000000..0d6903c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_testcase.cpp @@ -0,0 +1,2 @@ +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_interfaces_testcase.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_message.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_message.cpp new file mode 100644 index 0000000..40f4403 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_message.cpp @@ -0,0 +1,3 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_message.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_option.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_option.cpp new file mode 100644 index 0000000..a4ca37c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_option.cpp @@ -0,0 +1,3 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_option.hpp" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_ptr.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_ptr.cpp new file mode 100644 index 0000000..90796ca --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_ptr.cpp @@ -0,0 +1,3 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_ptr.hpp" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_stream.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_stream.cpp new file mode 100644 index 0000000..a76d841 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_stream.cpp @@ -0,0 +1,3 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_stream.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_streambuf.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_streambuf.cpp new file mode 100644 index 0000000..a9222e4 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_streambuf.cpp @@ -0,0 +1,3 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_streambuf.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_test_case_tracker.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_test_case_tracker.cpp new file mode 100644 index 0000000..bd67a8a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_test_case_tracker.cpp @@ -0,0 +1,2 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_test_case_tracker.hpp" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp new file mode 100644 index 0000000..9993b80 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp @@ -0,0 +1,3 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_test_spec.hpp" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_xmlwriter.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_xmlwriter.cpp new file mode 100644 index 0000000..169d2d7 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/SurrogateCpps/catch_xmlwriter.cpp @@ -0,0 +1,4 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_xmlwriter.hpp" +#include "internal/catch_reenable_warnings.h" diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/TagAliasTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/TagAliasTests.cpp new file mode 100644 index 0000000..002a93c --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/TagAliasTests.cpp @@ -0,0 +1,41 @@ +/* + * Created by Phil on 27/06/2014. + * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" +#include "internal/catch_tag_alias_registry.h" + +TEST_CASE( "Tag alias can be registered against tag patterns", "" ) { + + using namespace Catch::Matchers; + + Catch::TagAliasRegistry registry; + + registry.add( "[@zzz]", "[one][two]", Catch::SourceLineInfo( "file", 2 ) ); + + SECTION( "The same tag alias can only be registered once", "" ) { + + try { + registry.add( "[@zzz]", "[one][two]", Catch::SourceLineInfo( "file", 10 ) ); + FAIL( "expected exception" ); + } + catch( std::exception& ex ) { + std::string what = ex.what(); + CHECK_THAT( what, Contains( "[@zzz]" ) ); + CHECK_THAT( what, Contains( "file" ) ); + CHECK_THAT( what, Contains( "2" ) ); + CHECK_THAT( what, Contains( "10" ) ); + } + } + + SECTION( "Tag aliases must be of the form [@name]", "" ) { + CHECK_THROWS( registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) ); + CHECK_THROWS( registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) ); + CHECK_THROWS( registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) ); + CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) ); + } +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/TestMain.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/TestMain.cpp new file mode 100644 index 0000000..e00966a --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/TestMain.cpp @@ -0,0 +1,494 @@ +/* + * Created by Phil on 22/10/2010. + * Copyright 2010 Two Blue Cubes Ltd + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define CATCH_CONFIG_MAIN +#include "catch.hpp" +#include "../include/reporters/catch_reporter_teamcity.hpp" +#include "../include/reporters/catch_reporter_tap.hpp" +#include "../include/reporters/catch_reporter_automake.hpp" + + +// Some example tag aliases +CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" ) +CATCH_REGISTER_TAG_ALIAS( "[@tricky]", "[tricky]~[.]" ) + + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wweak-vtables" +# pragma clang diagnostic ignored "-Wc++98-compat" +#endif + + +template +void parseIntoConfig( const char * (&argv)[size], Catch::ConfigData& config ) { + Catch::Clara::CommandLine parser = Catch::makeCommandLineParser(); + parser.parseInto( Catch::Clara::argsToVector( size, argv ), config ); +} + +template +std::string parseIntoConfigAndReturnError( const char * (&argv)[size], Catch::ConfigData& config ) { + try { + parseIntoConfig( argv, config ); + FAIL( "expected exception" ); + } + catch( std::exception& ex ) { + return ex.what(); + } + return ""; +} + +inline Catch::TestCase fakeTestCase( const char* name, const char* desc = "" ){ return Catch::makeTestCase( CATCH_NULL, "", name, desc, CATCH_INTERNAL_LINEINFO ); } + +TEST_CASE( "Process can be configured on command line", "[config][command-line]" ) { + + using namespace Catch::Matchers; + + Catch::ConfigData config; + + SECTION( "default - no arguments", "" ) { + const char* argv[] = { "test" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + CHECK( config.shouldDebugBreak == false ); + CHECK( config.abortAfter == -1 ); + CHECK( config.noThrow == false ); + CHECK( config.reporterNames.empty() ); + } + + SECTION( "test lists", "" ) { + SECTION( "1 test", "Specify one test case using" ) { + const char* argv[] = { "test", "test1" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + Catch::Config cfg( config ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) ); + } + SECTION( "Specify one test case exclusion using exclude:", "" ) { + const char* argv[] = { "test", "exclude:test1" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + Catch::Config cfg( config ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ); + } + + SECTION( "Specify one test case exclusion using ~", "" ) { + const char* argv[] = { "test", "~test1" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + Catch::Config cfg( config ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ); + } + + } + + SECTION( "reporter", "" ) { + SECTION( "-r/console", "" ) { + const char* argv[] = { "test", "-r", "console" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.reporterNames[0] == "console" ); + } + SECTION( "-r/xml", "" ) { + const char* argv[] = { "test", "-r", "xml" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.reporterNames[0] == "xml" ); + } + SECTION( "-r xml and junit", "" ) { + const char* argv[] = { "test", "-r", "xml", "-r", "junit" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.reporterNames.size() == 2 ); + REQUIRE( config.reporterNames[0] == "xml" ); + REQUIRE( config.reporterNames[1] == "junit" ); + } + SECTION( "--reporter/junit", "" ) { + const char* argv[] = { "test", "--reporter", "junit" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.reporterNames[0] == "junit" ); + } + } + + SECTION( "debugger", "" ) { + SECTION( "-b", "" ) { + const char* argv[] = { "test", "-b" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.shouldDebugBreak == true ); + } + SECTION( "--break", "" ) { + const char* argv[] = { "test", "--break" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.shouldDebugBreak ); + } + } + + SECTION( "abort", "" ) { + SECTION( "-a aborts after first failure", "" ) { + const char* argv[] = { "test", "-a" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.abortAfter == 1 ); + } + SECTION( "-x 2 aborts after two failures", "" ) { + const char* argv[] = { "test", "-x", "2" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.abortAfter == 2 ); + } + SECTION( "-x must be greater than zero", "" ) { + const char* argv[] = { "test", "-x", "0" }; + REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "greater than zero" ) ); + } + SECTION( "-x must be numeric", "" ) { + const char* argv[] = { "test", "-x", "oops" }; + REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) ); + } + } + + SECTION( "nothrow", "" ) { + SECTION( "-e", "" ) { + const char* argv[] = { "test", "-e" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.noThrow == true ); + } + SECTION( "--nothrow", "" ) { + const char* argv[] = { "test", "--nothrow" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.noThrow == true ); + } + } + + SECTION( "output filename", "" ) { + SECTION( "-o filename", "" ) { + const char* argv[] = { "test", "-o", "filename.ext" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.outputFilename == "filename.ext" ); + } + SECTION( "--out", "" ) { + const char* argv[] = { "test", "--out", "filename.ext" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.outputFilename == "filename.ext" ); + } + } + + SECTION( "combinations", "" ) { + SECTION( "Single character flags can be combined", "" ) { + const char* argv[] = { "test", "-abe" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + CHECK( config.abortAfter == 1 ); + CHECK( config.shouldDebugBreak ); + CHECK( config.noThrow == true ); + } + } + + SECTION( "use-colour", "") { + + using Catch::UseColour; + + SECTION( "without option", "" ) { + const char* argv[] = { "test" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.useColour == UseColour::Auto ); + } + + SECTION( "auto", "" ) { + const char* argv[] = { "test", "--use-colour", "auto" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.useColour == UseColour::Auto ); + } + + SECTION( "yes", "" ) { + const char* argv[] = { "test", "--use-colour", "yes" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.useColour == UseColour::Yes ); + } + + SECTION( "no", "" ) { + const char* argv[] = { "test", "--use-colour", "no" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.useColour == UseColour::No ); + } + + SECTION( "error", "" ) { + const char* argv[] = { "test", "--use-colour", "wrong" }; + REQUIRE_THROWS_WITH( parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) ); + } + } +} + + +TEST_CASE( "Long strings can be wrapped", "[wrap]" ) { + + using namespace Catch; + SECTION( "plain string", "" ) { + // guide: 123456789012345678 + std::string testString = "one two three four"; + + SECTION( "No wrapping", "" ) { + CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ); + CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString ); + } + SECTION( "Wrapped once", "" ) { + CHECK( Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" ); + CHECK( Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" ); + CHECK( Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" ); + CHECK( Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" ); + CHECK( Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" ); + } + SECTION( "Wrapped twice", "" ) { + CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" ); + CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" ); + CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" ); + } + SECTION( "Wrapped three times", "" ) { + CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" ); + CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" ); + } + SECTION( "Short wrap", "" ) { + CHECK( Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" ); + CHECK( Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" ); + CHECK( Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" ); + + CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" ); + CHECK( Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" ); + } + SECTION( "As container", "" ) { + Text text( testString, TextAttributes().setWidth( 6 ) ); + REQUIRE( text.size() == 4 ); + CHECK( text[0] == "one" ); + CHECK( text[1] == "two" ); + CHECK( text[2] == "three" ); + CHECK( text[3] == "four" ); + } + SECTION( "Indent first line differently", "" ) { + Text text( testString, TextAttributes() + .setWidth( 10 ) + .setIndent( 4 ) + .setInitialIndent( 1 ) ); + CHECK( text.toString() == " one two\n three\n four" ); + } + + } + + SECTION( "With newlines", "" ) { + + // guide: 1234567890123456789 + std::string testString = "one two\nthree four"; + + SECTION( "No wrapping" , "" ) { + CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ); + CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString ); + CHECK( Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString ); + } + SECTION( "Trailing newline" , "" ) { + CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef" ); + CHECK( Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" ); + CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" ); + CHECK( Text( "abcdef\n", TextAttributes().setWidth( 5 ) ).toString() == "abcd-\nef" ); + } + SECTION( "Wrapped once", "" ) { + CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" ); + CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" ); + CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" ); + } + SECTION( "Wrapped twice", "" ) { + CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" ); + } + } + + SECTION( "With wrap-before/ after characters", "" ) { + std::string testString = "one,two(three) "; + + SECTION( "No wrapping", "" ) { + CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ); + CHECK( Text( testString, TextAttributes().setWidth( 24 ) ).toString() == testString ); + } + SECTION( "Wrap before", "" ) { + CHECK( Text( testString, TextAttributes().setWidth( 11 ) ).toString() == "one,two\n(three)\n" ); + } + SECTION( "Wrap after", "" ) { + CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one,\ntwo\n(thre-\ne)\n" ); + CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one,\ntwo\n(thr-\nee)\n" ); + CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one,\ntwo\n(th-\nree)\n" ); + } + } + +} + +using namespace Catch; + +class ColourString { +public: + + struct ColourIndex { + ColourIndex( Colour::Code _colour, std::size_t _fromIndex, std::size_t _toIndex ) + : colour( _colour ), + fromIndex( _fromIndex ), + toIndex( _toIndex ) + {} + + Colour::Code colour; + std::size_t fromIndex; + std::size_t toIndex; + }; + + ColourString( std::string const& _string ) + : string( _string ) + {} + ColourString( std::string const& _string, std::vector const& _colours ) + : string( _string ), colours( _colours ) + {} + + ColourString& addColour( Colour::Code colour, int _index ) { + colours.push_back( ColourIndex( colour, + resolveRelativeIndex( _index ), + resolveRelativeIndex( _index )+1 ) ); + return *this; + } + ColourString& addColour( Colour::Code colour, int _fromIndex, int _toIndex ) { + colours.push_back( ColourIndex( colour, + resolveRelativeIndex(_fromIndex), + resolveLastRelativeIndex( _toIndex ) ) ); + return *this; + } + + void writeToStream( std::ostream& _stream ) const { + std::size_t last = 0; + for( std::size_t i = 0; i < colours.size(); ++i ) { + ColourIndex const& index = colours[i]; + if( index.fromIndex > last ) + _stream << string.substr( last, index.fromIndex-last ); + { + Colour colourGuard( index.colour ); + _stream << string.substr( index.fromIndex, index.toIndex-index.fromIndex ); + } + last = index.toIndex; + } + if( last < string.size() ) + _stream << string.substr( last ); + } + friend std::ostream& operator << ( std::ostream& _stream, ColourString const& _colourString ) { + _colourString.writeToStream( _stream ); + return _stream; + } + +private: + + std::size_t resolveLastRelativeIndex( int _index ) { + std::size_t index = resolveRelativeIndex( _index ); + return index == 0 ? string.size() : index; + } + std::size_t resolveRelativeIndex( int _index ) { + return static_cast( _index >= 0 + ? _index + : static_cast( string.size() )+_index ); + } + std::string string; + std::vector colours; +}; + +TEST_CASE( "replaceInPlace", "" ) { + std::string letters = "abcdefcg"; + SECTION( "replace single char" ) { + CHECK( replaceInPlace( letters, "b", "z" ) ); + CHECK( letters == "azcdefcg" ); + } + SECTION( "replace two chars" ) { + CHECK( replaceInPlace( letters, "c", "z" ) ); + CHECK( letters == "abzdefzg" ); + } + SECTION( "replace first char" ) { + CHECK( replaceInPlace( letters, "a", "z" ) ); + CHECK( letters == "zbcdefcg" ); + } + SECTION( "replace last char" ) { + CHECK( replaceInPlace( letters, "g", "z" ) ); + CHECK( letters == "abcdefcz" ); + } + SECTION( "replace all chars" ) { + CHECK( replaceInPlace( letters, letters, "replaced" ) ); + CHECK( letters == "replaced" ); + } + SECTION( "replace no chars" ) { + CHECK_FALSE( replaceInPlace( letters, "x", "z" ) ); + CHECK( letters == letters ); + } + SECTION( "escape '" ) { + std::string s = "didn't"; + CHECK( replaceInPlace( s, "'", "|'" ) ); + CHECK( s == "didn|'t" ); + } +} + +// !TBD: This will be folded into Text class +TEST_CASE( "Strings can be rendered with colour", "[.colour]" ) { + + { + ColourString cs( "hello" ); + cs .addColour( Colour::Red, 0 ) + .addColour( Colour::Green, -1 ); + + Catch::cout() << cs << std::endl; + } + + { + ColourString cs( "hello" ); + cs .addColour( Colour::Blue, 1, -2 ); + + Catch::cout() << cs << std::endl; + } + +} + +TEST_CASE( "Text can be formatted using the Text class", "" ) { + + CHECK( Text( "hi there" ).toString() == "hi there" ); + + TextAttributes narrow; + narrow.setWidth( 6 ); + + CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" ); +} + +TEST_CASE( "Long text is truncated", "[Text][Truncated]" ) { + + std::string longLine( 90, '*' ); + + std::ostringstream oss; + for(int i = 0; i < 600; ++i ) + oss << longLine << longLine << "\n"; + Text t( oss.str() ); + CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) ); + +} + +inline void manuallyRegisteredTestFunction() { + SUCCEED( "was called" ); +} +struct AutoTestReg { + AutoTestReg() { + REGISTER_TEST_CASE( manuallyRegisteredTestFunction, "ManuallyRegistered", "" ); + } +}; +AutoTestReg autoTestReg; diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringGeneralTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringGeneralTests.cpp new file mode 100644 index 0000000..bca913f --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringGeneralTests.cpp @@ -0,0 +1,54 @@ +/* + * Created by Martin on 17/02/2017. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + + +TEST_CASE( "Character pretty printing" ){ + // + SECTION("Specifically escaped"){ + char tab = '\t'; + char newline = '\n'; + char carr_return = '\r'; + char form_feed = '\f'; + CHECK(tab == '\t'); + CHECK(newline == '\n'); + CHECK(carr_return == '\r'); + CHECK(form_feed == '\f'); + } + SECTION("General chars"){ + char space = ' '; + CHECK(space == ' '); + char chars[] = {'a', 'z', 'A', 'Z'}; + for (int i = 0; i < 4; ++i){ + char c = chars[i]; + REQUIRE(c == chars[i]); + } + } + SECTION("Low ASCII"){ + char null_terminator = '\0'; + CHECK(null_terminator == '\0'); + for (int i = 2; i < 6; ++i){ + char c = static_cast(i); + REQUIRE(c == i); + } + } +} + + +TEST_CASE( "Capture and info messages" ) { + SECTION("Capture should stringify like assertions") { + int i = 2; + CAPTURE(i); + REQUIRE(true); + } + SECTION("Info should NOT stringify the way assertions do") { + int i = 3; + INFO(i); + REQUIRE(true); + } +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringPair.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringPair.cpp new file mode 100644 index 0000000..8f51070 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringPair.cpp @@ -0,0 +1,47 @@ +#include "catch.hpp" + +// === Pair === +namespace Catch { + // Note: If we put this in the right place in catch_tostring, then + // we can make it an overload of Catch::toString + template + struct StringMaker > { + static std::string convert( const std::pair& pair ) { + std::ostringstream oss; + oss << "{ " + << toString( pair.first ) + << ", " + << toString( pair.second ) + << " }"; + return oss.str(); + } + }; +} + +TEST_CASE( "std::pair -> toString", "[toString][pair]" ) { + std::pair value( 34, "xyzzy" ); + REQUIRE( Catch::toString( value ) == "{ 34, \"xyzzy\" }" ); +} + +TEST_CASE( "std::pair -> toString", "[toString][pair]" ) { + std::pair value( 34, "xyzzy" ); + REQUIRE( Catch::toString(value) == "{ 34, \"xyzzy\" }" ); +} + +TEST_CASE( "std::vector > -> toString", "[toString][pair]" ) { + std::vector > pr; + pr.push_back( std::make_pair("green", 55 ) ); + REQUIRE( Catch::toString( pr ) == "{ { \"green\", 55 } }" ); +} + +// This is pretty contrived - I figure if this works, anything will... +TEST_CASE( "pair > -> toString", "[toString][pair]" ) { + typedef std::pair left_t; + typedef std::pair right_t; + + left_t left( 42, "Arthur" ); + right_t right( "Ford", 24 ); + + std::pair pair( left, right ); + REQUIRE( Catch::toString( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" ); +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringTuple.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringTuple.cpp new file mode 100644 index 0000000..fa61f63 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringTuple.cpp @@ -0,0 +1,59 @@ +#include "catch.hpp" + +#ifdef CATCH_CPP11_OR_GREATER + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++98-compat" +#endif + +TEST_CASE( "tuple<>", "[toString][tuple][c++11][.]" ) +{ + typedef std::tuple<> type; + CHECK( "{ }" == Catch::toString(type{}) ); + type value {}; + CHECK( "{ }" == Catch::toString(value) ); +} + +TEST_CASE( "tuple", "[toString][tuple][c++11][.]" ) +{ + typedef std::tuple type; + CHECK( "{ 0 }" == Catch::toString(type{0}) ); +} + + +TEST_CASE( "tuple", "[toString][tuple][c++11][.]" ) +{ + typedef std::tuple type; + CHECK( "1.2f" == Catch::toString(float(1.2)) ); + CHECK( "{ 1.2f, 0 }" == Catch::toString(type{1.2,0}) ); +} + +TEST_CASE( "tuple", "[toString][tuple][c++11][.]" ) +{ + typedef std::tuple type; + CHECK( "{ \"hello\", \"world\" }" == Catch::toString(type{"hello","world"}) ); +} + +TEST_CASE( "tuple,tuple<>,float>", "[toString][tuple][c++11][.]" ) +{ + typedef std::tuple,std::tuple<>,float> type; + type value { std::tuple{42}, {}, 1.2f }; + CHECK( "{ { 42 }, { }, 1.2f }" == Catch::toString(value) ); +} + +#ifdef CATCH_CONFIG_CPP11_NULLPTR +TEST_CASE( "tuple", "[toString][tuple][c++11][.]" ) +{ + typedef std::tuple type; + type value { nullptr, 42, "Catch me" }; + CHECK( "{ nullptr, 42, \"Catch me\" }" == Catch::toString(value) ); +} +#endif + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif /* #ifdef CATCH_CPP11_OR_GREATER */ + diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringVector.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringVector.cpp new file mode 100644 index 0000000..cd071a9 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringVector.cpp @@ -0,0 +1,77 @@ +#include "catch.hpp" +#include + + +// vedctor +TEST_CASE( "vector -> toString", "[toString][vector]" ) +{ + std::vector vv; + REQUIRE( Catch::toString(vv) == "{ }" ); + vv.push_back( 42 ); + REQUIRE( Catch::toString(vv) == "{ 42 }" ); + vv.push_back( 250 ); + REQUIRE( Catch::toString(vv) == "{ 42, 250 }" ); +} + +TEST_CASE( "vector -> toString", "[toString][vector]" ) +{ + std::vector vv; + REQUIRE( Catch::toString(vv) == "{ }" ); + vv.push_back( "hello" ); + REQUIRE( Catch::toString(vv) == "{ \"hello\" }" ); + vv.push_back( "world" ); + REQUIRE( Catch::toString(vv) == "{ \"hello\", \"world\" }" ); +} + +#if defined(CATCH_CPP11_OR_GREATER) +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++98-compat" +#endif + +/* + Note: These tests *can* be made to work with C++ < 11, but the + allocator is a lot more work... +*/ +namespace { + /* Minimal Allocator */ + template + struct minimal_allocator { + typedef T value_type; + typedef std::size_t size_type; + T *allocate( size_type n ) { + return static_cast( ::operator new( n * sizeof(T) ) ); + } + void deallocate( T *p, size_type /*n*/ ) { + ::operator delete( static_cast(p) ); + } + template + bool operator==( const minimal_allocator& ) const { return true; } + template + bool operator!=( const minimal_allocator& ) const { return false; } + }; +} + +TEST_CASE( "vector -> toString", "[toString][vector,allocator][c++11][.]" ) { + std::vector > vv; + REQUIRE( Catch::toString(vv) == "{ }" ); + vv.push_back( 42 ); + REQUIRE( Catch::toString(vv) == "{ 42 }" ); + vv.push_back( 250 ); + REQUIRE( Catch::toString(vv) == "{ 42, 250 }" ); +} + +TEST_CASE( "vec> -> toString", "[toString][vector,allocator][c++11][.]" ) { + typedef std::vector > inner; + typedef std::vector vector; + vector v; + REQUIRE( Catch::toString(v) == "{ }" ); + v.push_back( inner { "hello" } ); + v.push_back( inner { "world" } ); + REQUIRE( Catch::toString(v) == "{ { \"hello\" }, { \"world\" } }" ); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#endif // CATCH_CPP11_OR_GREATER diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringWhich.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringWhich.cpp new file mode 100644 index 0000000..a1d2a60 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/ToStringWhich.cpp @@ -0,0 +1,71 @@ +#include "catch.hpp" +/* + Demonstrate which version of toString/StringMaker is being used + for various types +*/ + + +struct has_toString { }; +struct has_maker {}; +struct has_maker_and_toString {}; + +namespace Catch { + inline std::string toString( const has_toString& ) { + return "toString( has_toString )"; + } + inline std::string toString( const has_maker_and_toString& ) { + return "toString( has_maker_and_toString )"; + } + template<> + struct StringMaker { + static std::string convert( const has_maker& ) { + return "StringMaker"; + } + }; + template<> + struct StringMaker { + static std::string convert( const has_maker_and_toString& ) { + return "StringMaker"; + } + }; +} + +// Call the overload +TEST_CASE( "toString( has_toString )", "[toString]" ) { + has_toString item; + REQUIRE( Catch::toString( item ) == "toString( has_toString )" ); +} + +// Call the overload +TEST_CASE( "toString( has_maker )", "toString]" ) { + has_maker item; + REQUIRE( Catch::toString( item ) == "StringMaker" ); +} + +// Call the overload +TEST_CASE( "toString( has_maker_and_toString )", "[.][toString]" ) { + has_maker_and_toString item; + REQUIRE( Catch::toString( item ) == "toString( has_maker_and_toString )" ); +} + +// Vectors... + +// Don't run this in approval tests as it is sensitive to two phase lookup differences +TEST_CASE( "toString( vectors v(1); + // This invokes template toString which actually gives us '{ ? }' + REQUIRE( Catch::toString( v ) == "{ {?} }" ); +} + +TEST_CASE( "toString( vectors v(1); + REQUIRE( Catch::toString( v ) == "{ StringMaker }" ); +} + + +// Don't run this in approval tests as it is sensitive to two phase lookup differences +TEST_CASE( "toString( vectors v(1); + // Note: This invokes the template toString -> StringMaker + REQUIRE( Catch::toString( v ) == "{ StringMaker }" ); +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/TrickyTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/TrickyTests.cpp new file mode 100644 index 0000000..26625b0 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/TrickyTests.cpp @@ -0,0 +1,409 @@ +/* + * Created by Phil on 09/11/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wpadded" +#endif + +#include + +#include "catch.hpp" + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wc++98-compat" +#pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +namespace Catch +{ + template<> + std::string toString >( const std::pair& value ) + { + std::ostringstream oss; + oss << "std::pair( " << value.first << ", " << value.second << " )"; + return oss.str(); + + } +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Parsing a std::pair", + "[Tricky][std::pair]" +) +{ + std::pair aNicePair( 1, 2 ); + + REQUIRE( (std::pair( 1, 2 )) == aNicePair ); +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Where there is more to the expression after the RHS", + "[Tricky][failing][.]" +) +{ +// int a = 1, b = 2; +// REQUIRE( a == 2 || b == 2 ); + WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" ); +} +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "Where the LHS is not a simple value", + "[Tricky][failing][.]" +) +{ + /* + int a = 1; + int b = 2; + + // This only captures part of the expression, but issues a warning about the rest + REQUIRE( a+1 == b-1 ); + */ + WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" ); +} + +struct Opaque +{ + int val; + bool operator ==( const Opaque& o ) const + { + return val == o.val; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "A failing expression with a non streamable type is still captured", + "[Tricky][failing][.]" +) +{ + + Opaque o1, o2; + o1.val = 7; + o2.val = 8; + + CHECK( &o1 == &o2 ); + CHECK( o1 == o2 ); +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "string literals of different sizes can be compared", + "[Tricky][failing][.]" +) +{ + REQUIRE( std::string( "first" ) == "second" ); + +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE +( + "An expression with side-effects should only be evaluated once", + "[Tricky]" +) +{ + int i = 7; + + REQUIRE( i++ == 7 ); + REQUIRE( i++ == 8 ); + +} + +namespace A { + struct X + { + X() : a(4), b(2), c(7) {} + X(int v) : a(v), b(2), c(7) {} + int a; + int b; + int c; + }; +} + +namespace B { + struct Y + { + Y() : a(4), b(2), c(7) {} + Y(int v) : a(v), b(2), c(7) {} + int a; + int b; + int c; + }; +} + +inline bool operator==(const A::X& lhs, const B::Y& rhs) +{ + return (lhs.a == rhs.a); +} + +inline bool operator==(const B::Y& lhs, const A::X& rhs) +{ + return (lhs.a == rhs.a); +} + + +/////////////////////////////////////////////////////////////////////////////// +/* This, currently, does not compile with LLVM +TEST_CASE +( + "Operators at different namespace levels not hijacked by Koenig lookup" + "[Tricky]" +) +{ + A::X x; + B::Y y; + REQUIRE( x == y ); +} +*/ + +namespace ObjectWithConversions +{ + struct Object + { + operator unsigned int() {return 0xc0000000;} + }; + + /////////////////////////////////////////////////////////////////////////////// + TEST_CASE + ( + "Operators at different namespace levels not hijacked by Koenig lookup", + "[Tricky]" + ) + { + Object o; + REQUIRE(0xc0000000 == o ); + } +} + +namespace ObjectWithNonConstEqualityOperator +{ + struct Test + { + Test( unsigned int v ) + : m_value(v) + {} + + bool operator==( const Test&rhs ) + { + return (m_value == rhs.m_value); + } + bool operator==( const Test&rhs ) const + { + return (m_value != rhs.m_value); + } + unsigned int m_value; + }; + + TEST_CASE("Demonstrate that a non-const == is not used", "[Tricky]" ) + { + Test t( 1 ); + REQUIRE( t == 1u ); + } +} + +namespace EnumBitFieldTests +{ + enum Bits {bit0 = 0x0001, bit1 = 0x0002, bit2 = 0x0004, bit3 = 0x0008, bit1and2 = 0x0006, + bit30 = 0x40000000, bit31 = 0x80000000, + bit30and31 = 0xc0000000}; + + TEST_CASE( "Test enum bit values", "[Tricky]" ) + { + REQUIRE( 0xc0000000 == bit30and31 ); + } +} + +struct Obj +{ + Obj():prop(&p){} + + int p; + int* prop; +}; + +TEST_CASE("boolean member", "[Tricky]") +{ + Obj obj; + REQUIRE( obj.prop != CATCH_NULL ); +} + +// Tests for a problem submitted by Ralph McArdell +// +// The static bool value should not need to be defined outside the +// struct it is declared in - but when evaluating it in a deduced +// context it appears to require the extra definition. +// The issue was fixed by adding bool overloads to bypass the +// templates that were there to deduce it. +template +struct is_true +{ + static const bool value = B; +}; + +TEST_CASE( "(unimplemented) static bools can be evaluated", "[Tricky]" ) +{ + SECTION("compare to true","") + { + REQUIRE( is_true::value == true ); + REQUIRE( true == is_true::value ); + } + SECTION("compare to false","") + { + REQUIRE( is_true::value == false ); + REQUIRE( false == is_true::value ); + } + + SECTION("negation", "") + { + REQUIRE( !is_true::value ); + } + + SECTION("double negation","") + { + REQUIRE( !!is_true::value ); + } + + SECTION("direct","") + { + REQUIRE( is_true::value ); + REQUIRE_FALSE( is_true::value ); + } +} + +// Uncomment these tests to produce an error at test registration time +/* +TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" ) +{ + +} +TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" ) +{ + +} +*/ + +struct Boolable +{ + explicit Boolable( bool value ) : m_value( value ) {} + + operator Catch::SafeBool::type() const { + return Catch::SafeBool::makeSafe( m_value ); + } + + bool m_value; +}; + +TEST_CASE( "Objects that evaluated in boolean contexts can be checked", "[Tricky][SafeBool]" ) +{ + Boolable True( true ); + Boolable False( false ); + + CHECK( True ); + CHECK( !False ); + CHECK_FALSE( False ); +} + +TEST_CASE( "Assertions then sections", "[Tricky]" ) +{ + // This was causing a failure due to the way the console reporter was handling + // the current section + + REQUIRE( Catch::alwaysTrue() ); + + SECTION( "A section", "" ) + { + REQUIRE( Catch::alwaysTrue() ); + + SECTION( "Another section", "" ) + { + REQUIRE( Catch::alwaysTrue() ); + } + SECTION( "Another other section", "" ) + { + REQUIRE( Catch::alwaysTrue() ); + } + } +} + +struct Awkward +{ + operator int() const { return 7; } +}; + +TEST_CASE( "non streamable - with conv. op", "[Tricky]" ) +{ + Awkward awkward; + std::string s = Catch::toString( awkward ); + REQUIRE( s == "7" ); +} + +inline void foo() {} + +typedef void (*fooptr_t)(); + +TEST_CASE( "Comparing function pointers", "[Tricky][function pointer]" ) +{ + // This was giving a warning in VS2010 + // #179 + fooptr_t a = foo; + + REQUIRE( a ); + REQUIRE( a == &foo ); +} + +struct S +{ + void f() {} +}; + + +TEST_CASE( "Comparing member function pointers", "[Tricky][member function pointer]" ) +{ + typedef void (S::*MF)(); + MF m = &S::f; + + CHECK( m == &S::f ); +} + +class ClassName {}; + +TEST_CASE( "pointer to class", "[Tricky]" ) +{ + ClassName *p = 0; + REQUIRE( p == 0 ); +} + +#ifdef CATCH_CONFIG_CPP11_NULLPTR + +#include + +TEST_CASE( "null_ptr", "[Tricky][c++11][.]" ) +{ + std::unique_ptr ptr; + REQUIRE(ptr.get() == nullptr); +} + +#endif + +TEST_CASE( "X/level/0/a", "[Tricky]" ) { SUCCEED(""); } +TEST_CASE( "X/level/0/b", "[Tricky][fizz]" ){ SUCCEED(""); } +TEST_CASE( "X/level/1/a", "[Tricky]" ) { SUCCEED(""); } +TEST_CASE( "X/level/1/b", "[Tricky]" ) { SUCCEED(""); } + +TEST_CASE( "has printf", "" ) { + + // This can cause problems as, currently, stdout itself is not redirect - only the cout (and cerr) buffer + printf( "spanner" ); +} diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/VariadicMacrosTests.cpp b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/VariadicMacrosTests.cpp new file mode 100644 index 0000000..b784076 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/SelfTest/VariadicMacrosTests.cpp @@ -0,0 +1,31 @@ +/* + * Created by Phil on 15/03/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + +TEST_CASE() +{ + SUCCEED( "anonymous test case" ); +} + +TEST_CASE( "Test case with one argument" ) +{ + SUCCEED( "no assertions" ); +} + +TEST_CASE( "Variadic macros", "[variadic][sections]" ) +{ + SECTION( "Section with one argument" ) + { + SUCCEED( "no assertions" ); + } +} + +#endif diff --git a/libraries/Lora_Serialization/test/lib/Catch/projects/Where did the projects go.txt b/libraries/Lora_Serialization/test/lib/Catch/projects/Where did the projects go.txt new file mode 100644 index 0000000..c7b011d --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/projects/Where did the projects go.txt @@ -0,0 +1,13 @@ +The canonical project format is now CMake. +To generate an XCode or Visual Studio project you'll need CMake, which you can download from https://cmake.org if necessary. + +To generate the project files open a terminal/ console within the projects directory (where this file is located), create a directory called "Generated" (using mkdir or md), cd into it, then type: + +CMake -G ../.. + +Where is XCode for XCode projects, or "Visual Studio 14" for Visual Studio 2015 (replace 14 with the major version number for any other supported Visual Studio version - or execute CMake -help for the full list) + +Remember to re-run CMake any time you pull from GitHub. +Note that the projects/Generated folder is excluded in .gitignore. So it is recommended to use this. + +CMake can also generate make files or projects for other build systems. Run CMake -help for the full set of options. diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/approvalTests.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/approvalTests.py new file mode 100644 index 0000000..b1b1d65 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/approvalTests.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import os +import sys +import subprocess +import re +import difflib + +import scriptCommon +from scriptCommon import catchPath + +rootPath = os.path.join(catchPath, 'projects/SelfTest/Baselines') + + +filelocParser = re.compile(r''' + .*/ + (.+\.[ch]pp) # filename + (?::|\() # : is starting separator between filename and line number on Linux, ( on Windows + ([0-9]*) # line number + \)? # Windows also has an ending separator, ) +''', re.VERBOSE) +lineNumberParser = re.compile(r' line="[0-9]*"') +hexParser = re.compile(r'\b(0[xX][0-9a-fA-F]+)\b') +durationsParser = re.compile(r' time="[0-9]*\.[0-9]*"') +timestampsParser = re.compile(r' timestamp="\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}Z"') +versionParser = re.compile(r'Catch v[0-9]+\.[0-9]+\.[0-9]+(-develop\.[0-9]+)?') +nullParser = re.compile(r'\b(__null|nullptr)\b') +exeNameParser = re.compile(r''' + \b + (CatchSelfTest|SelfTest) # Expected executable name + (?:.exe)? # Executable name contains .exe on Windows. + \b +''', re.VERBOSE) +# This is a hack until something more reasonable is figured out +specialCaseParser = re.compile(r'file\((\d+)\)') + +if len(sys.argv) == 2: + cmdPath = sys.argv[1] +else: + cmdPath = os.path.join(catchPath, scriptCommon.getBuildExecutable()) + +overallResult = 0 + +def diffFiles(fileA, fileB): + with open(fileA, 'r') as file: + aLines = file.readlines() + with open(fileB, 'r') as file: + bLines = file.readlines() + + shortenedFilenameA = fileA.rsplit(os.sep, 1)[-1] + shortenedFilenameB = fileB.rsplit(os.sep, 1)[-1] + + diff = difflib.unified_diff(aLines, bLines, fromfile=shortenedFilenameA, tofile=shortenedFilenameB, n=0) + return [line for line in diff if line[0] in ('+', '-')] + + +def filterLine(line): + if catchPath in line: + # make paths relative to Catch root + line = line.replace(catchPath + os.sep, '') + # go from \ in windows paths to / + line = line.replace('\\', '/') + + + # strip source line numbers + m = filelocParser.match(line) + if m: + # note that this also strips directories, leaving only the filename + filename, lnum = m.groups() + lnum = ":" if lnum else "" + line = filename + lnum + line[m.end():] + else: + line = lineNumberParser.sub(" ", line) + + # strip Catch version number + line = versionParser.sub("", line) + + # replace *null* with 0 + line = nullParser.sub("0", line) + + # strip executable name + line = exeNameParser.sub("", line) + + # strip hexadecimal numbers (presumably pointer values) + line = hexParser.sub("0x", line) + + # strip durations and timestamps + line = durationsParser.sub(' time="{duration}"', line) + line = timestampsParser.sub(' timestamp="{iso8601-timestamp}"', line) + line = specialCaseParser.sub('file:\g<1>', line) + return line + + +def approve(baseName, args): + global overallResult + args[0:0] = [cmdPath] + if not os.path.exists(cmdPath): + raise Exception("Executable doesn't exist at " + cmdPath) + baselinesPath = os.path.join(rootPath, '{0}.approved.txt'.format(baseName)) + rawResultsPath = os.path.join(rootPath, '_{0}.tmp'.format(baseName)) + filteredResultsPath = os.path.join(rootPath, '{0}.unapproved.txt'.format(baseName)) + + f = open(rawResultsPath, 'w') + subprocess.call(args, stdout=f, stderr=f) + f.close() + + rawFile = open(rawResultsPath, 'r') + filteredFile = open(filteredResultsPath, 'w') + for line in rawFile: + filteredFile.write(filterLine(line).rstrip() + "\n") + filteredFile.close() + rawFile.close() + + os.remove(rawResultsPath) + print() + print(baseName + ":") + if os.path.exists(baselinesPath): + diffResult = diffFiles(baselinesPath, filteredResultsPath) + if diffResult: + print(''.join(diffResult)) + print(" \n****************************\n \033[91mResults differed") + if len(diffResult) > overallResult: + overallResult = len(diffResult) + else: + os.remove(filteredResultsPath) + print(" \033[92mResults matched") + print("\033[0m") + else: + print(" first approval") + if overallResult == 0: + overallResult = 1 + + +print("Running approvals against executable:") +print(" " + cmdPath) + +# Standard console reporter +approve("console.std", ["~[c++11]~[!nonportable]", "--order", "lex"]) +# console reporter, include passes, warn about No Assertions +approve("console.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "--order", "lex"]) +# console reporter, include passes, warn about No Assertions, limit failures to first 4 +approve("console.swa4", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-x", "4", "--order", "lex"]) +# junit reporter, include passes, warn about No Assertions +approve("junit.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-r", "junit", "--order", "lex"]) +# xml reporter, include passes, warn about No Assertions +approve("xml.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex"]) + +if overallResult != 0: + print("If these differences are expected, run approve.py to approve new baselines.") +exit(overallResult) diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/approve.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/approve.py new file mode 100644 index 0000000..78a2a9e --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/approve.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import os +import sys +import shutil +import glob +from scriptCommon import catchPath + +rootPath = os.path.join( catchPath, 'projects/SelfTest/Baselines' ) + +if len(sys.argv) > 1: + files = [os.path.join( rootPath, f ) for f in sys.argv[1:]] +else: + files = glob.glob( os.path.join( rootPath, "*.unapproved.txt" ) ) + + +def approveFile( approvedFile, unapprovedFile ): + justFilename = unapprovedFile[len(rootPath)+1:] + if os.path.exists( unapprovedFile ): + if os.path.exists( approvedFile ): + os.remove( approvedFile ) + os.rename( unapprovedFile, approvedFile ) + print( "approved " + justFilename ) + else: + print( "approval file " + justFilename + " does not exist" ) + +if len(files) > 0: + for unapprovedFile in files: + approveFile( unapprovedFile.replace( "unapproved.txt", "approved.txt" ), unapprovedFile ) +else: + print( "no files to approve" ) diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/benchmarkCompile.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/benchmarkCompile.py new file mode 100644 index 0000000..13e6189 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/benchmarkCompile.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import time, subprocess, sys, os, shutil, glob, random +import argparse + +def median(lst): + lst = sorted(lst) + mid, odd = divmod(len(lst), 2) + if odd: + return lst[mid] + else: + return (lst[mid - 1] + lst[mid]) / 2.0 + +def mean(lst): + return float(sum(lst)) / max(len(lst), 1) + +compiler_path = '' +flags = [] + +main_file = r''' +#define CATCH_CONFIG_MAIN +#include "catch.hpp" +''' +main_name = 'catch-main.cpp' + +dir_name = 'benchmark-dir' + +files = 20 +test_cases_in_file = 20 +sections_in_file = 4 +assertions_per_section = 5 + +checks = [ + 'a != b', 'a != c', 'a != d', 'a != e', 'b != c', 'b != d', 'b != e', 'c != d', 'c != e', 'd != e', 'a + a == a', + 'a + b == b', 'a + c == c', 'a + d == d', 'a + e == e', 'b + a == b', 'b + b == c', 'b + c == d', + 'b + d == e', 'c + a == c', 'c + b == d', 'c + c == e', 'd + a == d', 'd + b == e', 'e + a == e', + 'a + a + a == a', 'b + c == a + d', 'c + a + a == a + b + b + a', + 'a < b', 'b < c', 'c < d', 'd < e', 'a >= a', 'd >= b', +] + +def create_temp_dir(): + if os.path.exists(dir_name): + shutil.rmtree(dir_name) + os.mkdir(dir_name) + +def copy_catch(path_to_catch): + shutil.copy(path_to_catch, dir_name) + +def create_catch_main(): + with open(main_name, 'w') as f: + f.write(main_file) + +def compile_main(): + start_t = time.time() + subprocess.check_call([compiler_path, main_name, '-c'] + flags) + end_t = time.time() + return end_t - start_t + +def compile_files(): + cpp_files = glob.glob('*.cpp') + start_t = time.time() + subprocess.check_call([compiler_path, '-c'] + flags + cpp_files) + end_t = time.time() + return end_t - start_t + +def link_files(): + obj_files = glob.glob('*.o') + start_t = time.time() + subprocess.check_call([compiler_path] + flags + obj_files) + end_t = time.time() + return end_t - start_t + +def benchmark(func): + results = [func() for i in range(10)] + return mean(results), median(results) + +def char_range(start, end): + for c in range(ord(start), ord(end)): + yield chr(c) + +def generate_sections(fd): + for i in range(sections_in_file): + fd.write(' SECTION("Section {}") {{\n'.format(i)) + fd.write('\n'.join(' CHECK({});'.format(check) for check in random.sample(checks, assertions_per_section))) + fd.write(' }\n') + + +def generate_file(file_no): + with open('tests{}.cpp'.format(file_no), 'w') as f: + f.write('#include "catch.hpp"\n\n') + for i in range(test_cases_in_file): + f.write('TEST_CASE("File {} test {}", "[.compile]"){{\n'.format(file_no, i)) + for i, c in enumerate(char_range('a', 'f')): + f.write(' int {} = {};\n'.format(c, i)) + generate_sections(f) + f.write('}\n\n') + + +def generate_files(): + create_catch_main() + for i in range(files): + generate_file(i) + + +options = ['all', 'main', 'files', 'link'] + +parser = argparse.ArgumentParser(description='Benchmarks Catch\'s compile times against some synthetic tests') +# Add first arg -- benchmark type +parser.add_argument('benchmark_kind', nargs='?', default='all', choices=options, help='What kind of benchmark to run, default: all') + +# Args to allow changing header/compiler +parser.add_argument('-I', '--catch-header', default='catch.hpp', help = 'Path to catch.hpp, default: catch.hpp') +parser.add_argument('-c', '--compiler', default='g++', help = 'Compiler to use, default: g++') + +parser.add_argument('-f', '--flags', nargs='*', help = 'Flags to be passed to the compiler') + +# Allow creating files only, without running the whole thing +parser.add_argument('-g', '--generate-files', action='store_true', help='Generate test files and quit') + +args = parser.parse_args() + +compiler_path = args.compiler +catch_path = args.catch_header + +if args.generate_files: + create_temp_dir() + os.chdir(dir_name) + copy_catch(catch_path) + # now create the fake test files + generate_files() + # Early exit + print('Finished generating files') + exit(1) + +os.chdir(dir_name) + +if args.flags: + flags = args.flags + +print('Time needed for ...') +if args.benchmark_kind in ('all', 'main'): + print(' ... compiling main, mean: {:.2f}, median: {:.2f} s'.format(*benchmark(compile_main))) +if args.benchmark_kind in ('all', 'files'): + print(' ... compiling test files, mean: {:.2f}, median: {:.2f} s'.format(*benchmark(compile_files))) +if args.benchmark_kind in ('all', 'link'): + print(' ... linking everything, mean: {:.2f}, median: {:.2f} s'.format(*benchmark(link_files))) diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/benchmarkRunner.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/benchmarkRunner.py new file mode 100644 index 0000000..dc753cf --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/benchmarkRunner.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +import subprocess, os, sys +import xml.etree.ElementTree as ET +from collections import defaultdict +from statistics import median, stdev +from datetime import datetime + +def get_commit_hash(): + res = subprocess.run('git rev-parse HEAD'.split(), check=True, stdout=subprocess.PIPE, universal_newlines=True) + return res.stdout.strip() + +if len(sys.argv) < 2: + print('Usage: {} benchmark-binary'.format(sys.argv[0])) + exit(1) + + +num_runs = 10 +data = defaultdict(list) + + +def parse_file(file): + + def recursive_search(node): + if node.tag == 'TestCase': + results = node.find('OverallResult') + time = results.get('durationInSeconds') + data[node.get('name')].append(float(time)) + elif node.tag in ('Group', 'Catch'): + for child in node: + recursive_search(child) + + tree = ET.parse(file) + recursive_search(tree.getroot()) + +def run_benchmarks(binary): + call = [binary] + '-d yes -r xml -o'.split() + for i in range(num_runs): + file = 'temp{}.xml'.format(i) + print('Run number {}'.format(i)) + subprocess.run(call + [file]) + parse_file(file) + # Remove file right after parsing, because benchmark output can be big + os.remove(file) + + +# Run benchmarks +run_benchmarks(sys.argv[1]) + +result_file = '{:%Y-%m-%dT%H-%M-%S}-{}.result'.format(datetime.now(), get_commit_hash()) + + +print('Writing results to {}'.format(result_file)) +with open(result_file, 'w') as file: + for k in sorted(data): + file.write('{}: median: {} (s), stddev: {} (s)\n'.format(k, median(data[k]), stdev(data[k]))) diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/developBuild.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/developBuild.py new file mode 100644 index 0000000..c16c8a6 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/developBuild.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +from __future__ import print_function +from releaseCommon import Version + +v = Version() +v.incrementBuildNumber() +v.updateVersionFile() +v.updateReadmeFile() + +print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) ) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/fixWhitespace.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/fixWhitespace.py new file mode 100644 index 0000000..6f37c53 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/fixWhitespace.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +from __future__ import print_function +import os +from scriptCommon import catchPath + +changedFiles = 0 + +def isSourceFile( path ): + return path.endswith( ".cpp" ) or path.endswith( ".h" ) or path.endswith( ".hpp" ) + +def fixAllFilesInDir( dir ): + for f in os.listdir( dir ): + path = os.path.join( dir,f ) + if os.path.isfile( path ): + if isSourceFile( path ): + fixFile( path ) + else: + fixAllFilesInDir( path ) + +def fixFile( path ): + f = open( path, 'r' ) + lines = [] + changed = 0 + for line in f: + trimmed = line.rstrip() + "\n" + trimmed = trimmed.replace('\t', ' ') + if trimmed != line: + changed = changed +1 + lines.append( trimmed ) + f.close() + if changed > 0: + global changedFiles + changedFiles = changedFiles + 1 + print( path + ":" ) + print( " - fixed " + str(changed) + " line(s)" ) + altPath = path + ".backup" + os.rename( path, altPath ) + f2 = open( path, 'w' ) + for line in lines: + f2.write( line ) + f2.close() + os.remove( altPath ) + +fixAllFilesInDir(catchPath) +if changedFiles > 0: + print( "Fixed " + str(changedFiles) + " file(s)" ) +else: + print( "No trailing whitespace found" ) diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/generateSingleHeader.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/generateSingleHeader.py new file mode 100644 index 0000000..18a2612 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/generateSingleHeader.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import os +import sys +import re +import datetime +import string + +from scriptCommon import catchPath +from releaseCommon import Version + + +includesParser = re.compile( r'\s*#\s*include\s*"(.*)"' ) +guardParser = re.compile( r'\s*#.*TWOBLUECUBES_CATCH_.*_INCLUDED') +defineParser = re.compile( r'\s*#define') +ifParser = re.compile( r'\s*#ifndef TWOBLUECUBES_CATCH_.*_INCLUDED') +endIfParser = re.compile( r'\s*#endif // TWOBLUECUBES_CATCH_.*_INCLUDED') +ifImplParser = re.compile( r'\s*#ifdef CATCH_CONFIG_RUNNER' ) +commentParser1 = re.compile( r'^\s*/\*') +commentParser2 = re.compile( r'^ \*') +blankParser = re.compile( r'^\s*$') +seenHeaders = set([]) +rootPath = os.path.join( catchPath, 'include/' ) +outputPath = os.path.join( catchPath, 'single_include/catch.hpp' ) + +includeImpl = True + +for arg in sys.argv[1:]: + arg = string.lower(arg) + if arg == "noimpl": + includeImpl = False + print( "Not including impl code" ) + else: + print( "\n** Unrecognised argument: " + arg + " **\n" ) + exit(1) + +out = open( outputPath, 'w' ) +ifdefs = 0 +implIfDefs = -1 + +def write( line ): + if includeImpl or implIfDefs == -1: + out.write( line ) + +def parseFile( path, filename ): + global ifdefs + global implIfDefs + + f = open( path + filename, 'r' ) + blanks = 0 + for line in f: + if ifParser.match( line ): + ifdefs = ifdefs + 1 + elif endIfParser.match( line ): + ifdefs = ifdefs - 1 + if ifdefs == implIfDefs: + implIfDefs = -1 + m = includesParser.match( line ) + if m: + header = m.group(1) + headerPath, sep, headerFile = header.rpartition( "/" ) + if not headerFile in seenHeaders: + if headerFile != "tbc_text_format.h" and headerFile != "clara.h": + seenHeaders.add( headerFile ) + write( "// #included from: {0}\n".format( header ) ) + if headerPath == "internal" and path.endswith("internal/"): + headerPath = "" + sep = "" + if os.path.exists( path + headerPath + sep + headerFile ): + parseFile( path + headerPath + sep, headerFile ) + else: + parseFile( rootPath + headerPath + sep, headerFile ) + else: + if ifImplParser.match(line): + implIfDefs = ifdefs + if (not guardParser.match( line ) or defineParser.match( line ) ) and not commentParser1.match( line )and not commentParser2.match( line ): + if blankParser.match( line ): + blanks = blanks + 1 + else: + blanks = 0 + if blanks < 2: + write( line.rstrip() + "\n" ) + + +v = Version() +out.write( "/*\n" ) +out.write( " * Catch v{0}\n".format( v.getVersionString() ) ) +out.write( " * Generated: {0}\n".format( datetime.datetime.now() ) ) +out.write( " * ----------------------------------------------------------\n" ) +out.write( " * This file has been merged from multiple headers. Please don't edit it directly\n" ) +out.write( " * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.\n" ) +out.write( " *\n" ) +out.write( " * Distributed under the Boost Software License, Version 1.0. (See accompanying\n" ) +out.write( " * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n" ) +out.write( " */\n" ) +out.write( "#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" ) +out.write( "#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" ) + +parseFile( rootPath, 'catch.hpp' ) + +out.write( "#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n" ) + +print ("Generated single include for Catch v{0}\n".format( v.getVersionString() ) ) diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/majorRelease.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/majorRelease.py new file mode 100644 index 0000000..f367506 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/majorRelease.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +from __future__ import print_function +from releaseCommon import Version + +v = Version() +v.incrementMajorVersion() +v.updateVersionFile() +v.updateReadmeFile() + +print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) ) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/minorRelease.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/minorRelease.py new file mode 100644 index 0000000..ac36df9 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/minorRelease.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +from __future__ import print_function +from releaseCommon import Version + +v = Version() +v.incrementMinorVersion() +v.updateVersionFile() +v.updateReadmeFile() + +print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) ) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/patchRelease.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/patchRelease.py new file mode 100644 index 0000000..878662f --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/patchRelease.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +from __future__ import print_function +from releaseCommon import Version + +v = Version() +v.incrementPatchNumber() +v.updateVersionFile() +v.updateReadmeFile() + +print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) ) \ No newline at end of file diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/releaseCommon.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/releaseCommon.py new file mode 100644 index 0000000..91a9062 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/releaseCommon.py @@ -0,0 +1,88 @@ +from __future__ import print_function + +import os +import sys +import re +import string + +from scriptCommon import catchPath + +versionParser = re.compile( r'(\s*Version\slibraryVersion)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*,\s*(.*)\s*\).*' ) +rootPath = os.path.join( catchPath, 'include/' ) +versionPath = os.path.join( rootPath, "internal/catch_version.hpp" ) +readmePath = os.path.join( catchPath, "README.md" ) + +class Version: + def __init__(self): + f = open( versionPath, 'r' ) + for line in f: + m = versionParser.match( line ) + if m: + self.variableDecl = m.group(1) + self.majorVersion = int(m.group(2)) + self.minorVersion = int(m.group(3)) + self.patchNumber = int(m.group(4)) + self.branchName = m.group(5) + self.buildNumber = int(m.group(6)) + f.close() + + def nonDevelopRelease(self): + if self.branchName != "": + self.branchName = "" + self.buildNumber = 0 + def developBuild(self): + if self.branchName == "": + self.branchName = "develop" + self.buildNumber = 0 + + def incrementBuildNumber(self): + self.developBuild() + self.buildNumber = self.buildNumber+1 + + def incrementPatchNumber(self): + self.nonDevelopRelease() + self.patchNumber = self.patchNumber+1 + + def incrementMinorVersion(self): + self.nonDevelopRelease() + self.patchNumber = 0 + self.minorVersion = self.minorVersion+1 + + def incrementMajorVersion(self): + self.nonDevelopRelease() + self.patchNumber = 0 + self.minorVersion = 0 + self.majorVersion = self.majorVersion+1 + + def getVersionString(self): + versionString = '{0}.{1}.{2}'.format( self.majorVersion, self.minorVersion, self.patchNumber ) + if self.branchName != "": + versionString = versionString + '-{0}.{1}'.format( self.branchName, self.buildNumber ) + return versionString + + def updateVersionFile(self): + f = open( versionPath, 'r' ) + lines = [] + for line in f: + m = versionParser.match( line ) + if m: + lines.append( '{0}( {1}, {2}, {3}, "{4}", {5} );'.format( self.variableDecl, self.majorVersion, self.minorVersion, self.patchNumber, self.branchName, self.buildNumber ) ) + else: + lines.append( line.rstrip() ) + f.close() + f = open( versionPath, 'w' ) + for line in lines: + f.write( line + "\n" ) + + def updateReadmeFile(self): + downloadParser = re.compile( r'' ) + f = open( readmePath, 'r' ) + lines = [] + for line in f: + lines.append( line.rstrip() ) + f.close() + f = open( readmePath, 'w' ) + for line in lines: + line = downloadParser.sub( r''.format(self.getVersionString()) , line) + f.write( line + "\n" ) + diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/releaseNotes.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/releaseNotes.py new file mode 100644 index 0000000..80fffbf --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/releaseNotes.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +import os +import re +import urllib2 +import json + +from scriptCommon import catchPath +from scriptCommon import runAndCapture + +issueNumberRe = re.compile( r'(.*?)#([0-9]*)([^0-9]?.*)' ) + +rootPath = os.path.join( catchPath, 'include/' ) +versionPath = os.path.join( rootPath, "internal/catch_version.hpp" ) + + +hashes = runAndCapture( ['git', 'log', '-2', '--format="%H"', versionPath] ) +lines = runAndCapture( ['git', 'log', hashes[1] + ".." + hashes[0], catchPath] ) + +prevLine = "" +messages = [] +dates = [] +issues = {} + +def getIssueTitle( issueNumber ): + try: + s = urllib2.urlopen("https://api.github.com/repos/philsquared/catch/issues/" + issueNumber ).read() + except: + return "#HTTP Error#" + + try: + j = json.loads( s ) + return j["title"] + except: + return "#JSON Error#" + +for line in lines: + if line.startswith( "commit"): + pass + elif line.startswith( "Author:"): + pass + elif line.startswith( "Date:"): + dates.append( line[5:].lstrip() ) + pass + elif line == "" and prevLine == "": + pass + else: + prevLine = line + match = issueNumberRe.match( line ) + line2 = "" + while match: + issueNumber = match.group(2) + issue = '#{0} ("{1}")'.format( issueNumber, getIssueTitle( issueNumber ) ) + line2 = line2 + match.group(1) + issue + match = issueNumberRe.match( match.group(3) ) + if line2 == "": + messages.append( line ) + else: + messages.append( line2 ) + +print "All changes between {0} and {1}:\n".format( dates[-1], dates[0] ) + +for line in messages: + print line diff --git a/libraries/Lora_Serialization/test/lib/Catch/scripts/scriptCommon.py b/libraries/Lora_Serialization/test/lib/Catch/scripts/scriptCommon.py new file mode 100644 index 0000000..9adadb6 --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/scripts/scriptCommon.py @@ -0,0 +1,26 @@ +import os +import sys +import subprocess + + +catchPath = os.path.dirname(os.path.realpath( os.path.dirname(sys.argv[0]))) + +def getBuildExecutable(): + dir = os.environ.get('CATCH_DEV_OUT_DIR', "cmake-build-debug/SelfTest") + return dir + +def runAndCapture( args ): + child = subprocess.Popen(" ".join( args ), shell=True, stdout=subprocess.PIPE) + lines = [] + line = "" + while True: + out = child.stdout.read(1) + if out == '' and child.poll() != None: + break + if out != '': + if out == '\n': + lines.append( line ) + line = "" + else: + line = line + out + return lines diff --git a/libraries/Lora_Serialization/test/lib/Catch/single_include/catch.hpp b/libraries/Lora_Serialization/test/lib/Catch/single_include/catch.hpp new file mode 100644 index 0000000..6f9334b --- /dev/null +++ b/libraries/Lora_Serialization/test/lib/Catch/single_include/catch.hpp @@ -0,0 +1,11282 @@ +/* + * Catch v1.8.1 + * Generated: 2017-03-01 16:04:19.016511 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED + +#define TWOBLUECUBES_CATCH_HPP_INCLUDED + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// #included from: internal/catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic ignored "-Wglobal-constructors" +# pragma clang diagnostic ignored "-Wvariadic-macros" +# pragma clang diagnostic ignored "-Wc99-extensions" +# pragma clang diagnostic ignored "-Wunused-variable" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wc++98-compat" +# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic ignored "-Wvariadic-macros" +# pragma GCC diagnostic ignored "-Wunused-variable" + + // For newer version we can use __Pragma to disable the warnings locally +# if __GNUC__ == 4 && __GNUC_MINOR__ >= 4 && __GNUC_MINOR__ <= 7 +# pragma GCC diagnostic ignored "-Wparentheses" +# endif + +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +#endif + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// #included from: internal/catch_notimplemented_exception.h +#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED + +// #included from: catch_common.h +#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED + +// #included from: catch_compiler_capabilities.h +#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED + +// Detect a number of compiler features - mostly C++11/14 conformance - by compiler +// The following features are defined: +// +// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? +// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? +// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods +// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? +// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported +// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported? +// CATCH_CONFIG_CPP11_OVERRIDE : is override supported? +// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) +// CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported? +// CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported? + +// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? + +// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 + +#ifdef __cplusplus + +# if __cplusplus >= 201103L +# define CATCH_CPP11_OR_GREATER +# endif + +# if __cplusplus >= 201402L +# define CATCH_CPP14_OR_GREATER +# endif + +#endif + +#ifdef __clang__ + +# if __has_feature(cxx_nullptr) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# if __has_feature(cxx_noexcept) +# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# endif + +# if defined(CATCH_CPP11_OR_GREATER) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic push" ) \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic pop" ) +# endif + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +# if !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# endif + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE + +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Borland +#ifdef __BORLANDC__ + +#endif // __BORLANDC__ + +//////////////////////////////////////////////////////////////////////////////// +// EDG +#ifdef __EDG_VERSION__ + +#endif // __EDG_VERSION__ + +//////////////////////////////////////////////////////////////////////////////// +// Digital Mars +#ifdef __DMC__ + +#endif // __DMC__ + +//////////////////////////////////////////////////////////////////////////////// +// GCC +#ifdef __GNUC__ + +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +# define CATCH_GCC_HAS_NEW_PRAGMA +# endif + +# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_GCC_HAS_NEW_PRAGMA) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "GCC diagnostic push" ) \ + _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" ) +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "GCC diagnostic pop" ) +# endif + +// - otherwise more recent versions define __cplusplus >= 201103L +// and will get picked up below + +#endif // __GNUC__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH + +#if (_MSC_VER >= 1600) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) +#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE +#define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS +#endif + +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// + +// Use variadic macros if the compiler supports them +#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ + ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ + ( defined __GNUC__ && __GNUC__ >= 3 ) || \ + ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) + +#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS + +#endif + +// Use __COUNTER__ if the compiler supports it +#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ + ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \ + ( defined __clang__ && __clang_major__ >= 3 ) + +#define CATCH_INTERNAL_CONFIG_COUNTER + +#endif + +//////////////////////////////////////////////////////////////////////////////// +// C++ language feature support + +// catch all support for C++11 +#if defined(CATCH_CPP11_OR_GREATER) + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM +# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE +# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE +# endif + +# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS +# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS +# endif + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) +# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG +# endif + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) +# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE +# endif +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) +# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +# endif +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) +# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE +# endif +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) +# define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS +# endif + +#endif // __cplusplus >= 201103L + +// Now set the actual defines based on the above + anything the user has configured +#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_NULLPTR +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_NOEXCEPT +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_GENERATED_METHODS +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_IS_ENUM +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_TUPLE +#endif +#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) +# define CATCH_CONFIG_VARIADIC_MACROS +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_LONG_LONG +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_OVERRIDE +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_UNIQUE_PTR +#endif +// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for +// analytics) because, at time of writing, __COUNTER__ is not properly handled by it. +// This does not affect compilation +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_SHUFFLE +#endif +# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_TYPE_TRAITS +# endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS +#endif + +// noexcept support: +#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) +# define CATCH_NOEXCEPT noexcept +# define CATCH_NOEXCEPT_IS(x) noexcept(x) +#else +# define CATCH_NOEXCEPT throw() +# define CATCH_NOEXCEPT_IS(x) +#endif + +// nullptr support +#ifdef CATCH_CONFIG_CPP11_NULLPTR +# define CATCH_NULL nullptr +#else +# define CATCH_NULL NULL +#endif + +// override support +#ifdef CATCH_CONFIG_CPP11_OVERRIDE +# define CATCH_OVERRIDE override +#else +# define CATCH_OVERRIDE +#endif + +// unique_ptr support +#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR +# define CATCH_AUTO_PTR( T ) std::unique_ptr +#else +# define CATCH_AUTO_PTR( T ) std::auto_ptr +#endif + +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr +#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) + +#include +#include + +namespace Catch { + + struct IConfig; + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { +#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; +#else + NonCopyable( NonCopyable const& info ); + NonCopyable& operator = ( NonCopyable const& ); +#endif + + protected: + NonCopyable() {} + virtual ~NonCopyable(); + }; + + class SafeBool { + public: + typedef void (SafeBool::*type)() const; + + static type makeSafe( bool value ) { + return value ? &SafeBool::trueValue : 0; + } + private: + void trueValue() const {} + }; + + template + inline void deleteAll( ContainerT& container ) { + typename ContainerT::const_iterator it = container.begin(); + typename ContainerT::const_iterator itEnd = container.end(); + for(; it != itEnd; ++it ) + delete *it; + } + template + inline void deleteAllValues( AssociativeContainerT& container ) { + typename AssociativeContainerT::const_iterator it = container.begin(); + typename AssociativeContainerT::const_iterator itEnd = container.end(); + for(; it != itEnd; ++it ) + delete it->second; + } + + bool startsWith( std::string const& s, std::string const& prefix ); + bool startsWith( std::string const& s, char prefix ); + bool endsWith( std::string const& s, std::string const& suffix ); + bool endsWith( std::string const& s, char suffix ); + bool contains( std::string const& s, std::string const& infix ); + void toLowerInPlace( std::string& s ); + std::string toLower( std::string const& s ); + std::string trim( std::string const& str ); + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); + + struct pluralise { + pluralise( std::size_t count, std::string const& label ); + + friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); + + std::size_t m_count; + std::string m_label; + }; + + struct SourceLineInfo { + + SourceLineInfo(); + SourceLineInfo( char const* _file, std::size_t _line ); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + SourceLineInfo(SourceLineInfo const& other) = default; + SourceLineInfo( SourceLineInfo && ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo& operator = ( SourceLineInfo && ) = default; +# endif + bool empty() const; + bool operator == ( SourceLineInfo const& other ) const; + bool operator < ( SourceLineInfo const& other ) const; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // This is just here to avoid compiler warnings with macro constants and boolean literals + inline bool isTrue( bool value ){ return value; } + inline bool alwaysTrue() { return true; } + inline bool alwaysFalse() { return false; } + + void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); + + void seedRng( IConfig const& config ); + unsigned int rngSeed(); + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() { + return std::string(); + } + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) +#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); + +namespace Catch { + + class NotImplementedException : public std::exception + { + public: + NotImplementedException( SourceLineInfo const& lineInfo ); + NotImplementedException( NotImplementedException const& ) {} + + virtual ~NotImplementedException() CATCH_NOEXCEPT {} + + virtual const char* what() const CATCH_NOEXCEPT; + + private: + std::string m_what; + SourceLineInfo m_lineInfo; + }; + +} // end namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) + +// #included from: internal/catch_context.h +#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED + +// #included from: catch_interfaces_generators.h +#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED + +#include + +namespace Catch { + + struct IGeneratorInfo { + virtual ~IGeneratorInfo(); + virtual bool moveNext() = 0; + virtual std::size_t getCurrentIndex() const = 0; + }; + + struct IGeneratorsForTest { + virtual ~IGeneratorsForTest(); + + virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; + virtual bool moveNext() = 0; + }; + + IGeneratorsForTest* createGeneratorsForTest(); + +} // end namespace Catch + +// #included from: catch_ptr.hpp +#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + // An intrusive reference counting smart pointer. + // T must implement addRef() and release() methods + // typically implementing the IShared interface + template + class Ptr { + public: + Ptr() : m_p( CATCH_NULL ){} + Ptr( T* p ) : m_p( p ){ + if( m_p ) + m_p->addRef(); + } + Ptr( Ptr const& other ) : m_p( other.m_p ){ + if( m_p ) + m_p->addRef(); + } + ~Ptr(){ + if( m_p ) + m_p->release(); + } + void reset() { + if( m_p ) + m_p->release(); + m_p = CATCH_NULL; + } + Ptr& operator = ( T* p ){ + Ptr temp( p ); + swap( temp ); + return *this; + } + Ptr& operator = ( Ptr const& other ){ + Ptr temp( other ); + swap( temp ); + return *this; + } + void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } + T* get() const{ return m_p; } + T& operator*() const { return *m_p; } + T* operator->() const { return m_p; } + bool operator !() const { return m_p == CATCH_NULL; } + operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } + + private: + T* m_p; + }; + + struct IShared : NonCopyable { + virtual ~IShared(); + virtual void addRef() const = 0; + virtual void release() const = 0; + }; + + template + struct SharedImpl : T { + + SharedImpl() : m_rc( 0 ){} + + virtual void addRef() const { + ++m_rc; + } + virtual void release() const { + if( --m_rc == 0 ) + delete this; + } + + mutable unsigned int m_rc; + }; + +} // end namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +namespace Catch { + + class TestCase; + class Stream; + struct IResultCapture; + struct IRunner; + struct IGeneratorsForTest; + struct IConfig; + + struct IContext + { + virtual ~IContext(); + + virtual IResultCapture* getResultCapture() = 0; + virtual IRunner* getRunner() = 0; + virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; + virtual bool advanceGeneratorsForCurrentTest() = 0; + virtual Ptr getConfig() const = 0; + }; + + struct IMutableContext : IContext + { + virtual ~IMutableContext(); + virtual void setResultCapture( IResultCapture* resultCapture ) = 0; + virtual void setRunner( IRunner* runner ) = 0; + virtual void setConfig( Ptr const& config ) = 0; + }; + + IContext& getCurrentContext(); + IMutableContext& getCurrentMutableContext(); + void cleanUpContext(); + Stream createStream( std::string const& streamName ); + +} + +// #included from: internal/catch_test_registry.hpp +#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED + +// #included from: catch_interfaces_testcase.h +#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED + +#include + +namespace Catch { + + class TestSpec; + + struct ITestCase : IShared { + virtual void invoke () const = 0; + protected: + virtual ~ITestCase(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +namespace Catch { + +template +class MethodTestCase : public SharedImpl { + +public: + MethodTestCase( void (C::*method)() ) : m_method( method ) {} + + virtual void invoke() const { + C obj; + (obj.*m_method)(); + } + +private: + virtual ~MethodTestCase() {} + + void (C::*m_method)(); +}; + +typedef void(*TestFunction)(); + +struct NameAndDesc { + NameAndDesc( const char* _name = "", const char* _description= "" ) + : name( _name ), description( _description ) + {} + + const char* name; + const char* description; +}; + +void registerTestCase + ( ITestCase* testCase, + char const* className, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ); + +struct AutoReg { + + AutoReg + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ); + + template + AutoReg + ( void (C::*method)(), + char const* className, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ) { + + registerTestCase + ( new MethodTestCase( method ), + className, + nameAndDesc, + lineInfo ); + } + + ~AutoReg(); + +private: + AutoReg( AutoReg const& ); + void operator= ( AutoReg const& ); +}; + +void registerTestCaseFunction + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ); + +} // end namespace Catch + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ + static void TestName(); \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( ... ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ + namespace{ \ + struct TestName : ClassName{ \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \ + } \ + void TestName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ + Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); + +#else + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \ + static void TestName(); \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\ + namespace{ \ + struct TestCaseName : ClassName{ \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \ + } \ + void TestCaseName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \ + Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); +#endif + +// #included from: internal/catch_capture.hpp +#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED + +// #included from: catch_result_builder.h +#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED + +// #included from: catch_result_type.h +#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED + +namespace Catch { + + // ResultWas::OfType enum + struct ResultWas { enum OfType { + Unknown = -1, + Ok = 0, + Info = 1, + Warning = 2, + + FailureBit = 0x10, + + ExpressionFailed = FailureBit | 1, + ExplicitFailure = FailureBit | 2, + + Exception = 0x100 | FailureBit, + + ThrewException = Exception | 1, + DidntThrowException = Exception | 2, + + FatalErrorCondition = 0x200 | FailureBit + + }; }; + + inline bool isOk( ResultWas::OfType resultType ) { + return ( resultType & ResultWas::FailureBit ) == 0; + } + inline bool isJustInfo( int flags ) { + return flags == ResultWas::Info; + } + + // ResultDisposition::Flags enum + struct ResultDisposition { enum Flags { + Normal = 0x01, + + ContinueOnFailure = 0x02, // Failures fail test, but execution continues + FalseTest = 0x04, // Prefix expression with ! + SuppressFail = 0x08 // Failures are reported but do not fail the test + }; }; + + inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { + return static_cast( static_cast( lhs ) | static_cast( rhs ) ); + } + + inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } + inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } + inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } + +} // end namespace Catch + +// #included from: catch_assertionresult.h +#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED + +#include + +namespace Catch { + + struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; + + struct DecomposedExpression + { + virtual ~DecomposedExpression() {} + virtual bool isBinaryExpression() const { + return false; + } + virtual void reconstructExpression( std::string& dest ) const = 0; + + // Only simple binary comparisons can be decomposed. + // If more complex check is required then wrap sub-expressions in parentheses. + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& ); + + private: + DecomposedExpression& operator = (DecomposedExpression const&); + }; + + struct AssertionInfo + { + AssertionInfo() {} + AssertionInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + std::string const& _capturedExpression, + ResultDisposition::Flags _resultDisposition ); + + std::string macroName; + SourceLineInfo lineInfo; + std::string capturedExpression; + ResultDisposition::Flags resultDisposition; + }; + + struct AssertionResultData + { + AssertionResultData() : decomposedExpression( CATCH_NULL ) + , resultType( ResultWas::Unknown ) + , negated( false ) + , parenthesized( false ) {} + + void negate( bool parenthesize ) { + negated = !negated; + parenthesized = parenthesize; + if( resultType == ResultWas::Ok ) + resultType = ResultWas::ExpressionFailed; + else if( resultType == ResultWas::ExpressionFailed ) + resultType = ResultWas::Ok; + } + + std::string const& reconstructExpression() const { + if( decomposedExpression != CATCH_NULL ) { + decomposedExpression->reconstructExpression( reconstructedExpression ); + if( parenthesized ) { + reconstructedExpression.insert( 0, 1, '(' ); + reconstructedExpression.append( 1, ')' ); + } + if( negated ) { + reconstructedExpression.insert( 0, 1, '!' ); + } + decomposedExpression = CATCH_NULL; + } + return reconstructedExpression; + } + + mutable DecomposedExpression const* decomposedExpression; + mutable std::string reconstructedExpression; + std::string message; + ResultWas::OfType resultType; + bool negated; + bool parenthesized; + }; + + class AssertionResult { + public: + AssertionResult(); + AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); + ~AssertionResult(); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + AssertionResult( AssertionResult const& ) = default; + AssertionResult( AssertionResult && ) = default; + AssertionResult& operator = ( AssertionResult const& ) = default; + AssertionResult& operator = ( AssertionResult && ) = default; +# endif + + bool isOk() const; + bool succeeded() const; + ResultWas::OfType getResultType() const; + bool hasExpression() const; + bool hasMessage() const; + std::string getExpression() const; + std::string getExpressionInMacro() const; + bool hasExpandedExpression() const; + std::string getExpandedExpression() const; + std::string getMessage() const; + SourceLineInfo getSourceInfo() const; + std::string getTestMacroName() const; + void discardDecomposedExpression() const; + void expandDecomposedExpression() const; + + protected: + AssertionInfo m_info; + AssertionResultData m_resultData; + }; + +} // end namespace Catch + +// #included from: catch_matchers.hpp +#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED + +namespace Catch { +namespace Matchers { + namespace Impl { + + template struct MatchAllOf; + template struct MatchAnyOf; + template struct MatchNotOf; + + class MatcherUntypedBase { + public: + std::string toString() const { + if( m_cachedToString.empty() ) + m_cachedToString = describe(); + return m_cachedToString; + } + + protected: + virtual std::string describe() const = 0; + mutable std::string m_cachedToString; + private: + MatcherUntypedBase& operator = ( MatcherUntypedBase const& ); + }; + + template + struct MatcherBase : MatcherUntypedBase { + + virtual bool match( ObjectT const& arg ) const = 0; + + MatchAllOf operator && ( MatcherBase const& other ) const; + MatchAnyOf operator || ( MatcherBase const& other ) const; + MatchNotOf operator ! () const; + }; + + template + struct MatchAllOf : MatcherBase { + virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if (!m_matchers[i]->match(arg)) + return false; + } + return true; + } + virtual std::string describe() const CATCH_OVERRIDE { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if( i != 0 ) + description += " and "; + description += m_matchers[i]->toString(); + } + description += " )"; + return description; + } + + MatchAllOf& operator && ( MatcherBase const& other ) { + m_matchers.push_back( &other ); + return *this; + } + + std::vector const*> m_matchers; + }; + template + struct MatchAnyOf : MatcherBase { + + virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if (m_matchers[i]->match(arg)) + return true; + } + return false; + } + virtual std::string describe() const CATCH_OVERRIDE { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if( i != 0 ) + description += " or "; + description += m_matchers[i]->toString(); + } + description += " )"; + return description; + } + + MatchAnyOf& operator || ( MatcherBase const& other ) { + m_matchers.push_back( &other ); + return *this; + } + + std::vector const*> m_matchers; + }; + + template + struct MatchNotOf : MatcherBase { + + MatchNotOf( MatcherBase const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} + + virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { + return !m_underlyingMatcher.match( arg ); + } + + virtual std::string describe() const CATCH_OVERRIDE { + return "not " + m_underlyingMatcher.toString(); + } + MatcherBase const& m_underlyingMatcher; + }; + + template + MatchAllOf MatcherBase::operator && ( MatcherBase const& other ) const { + return MatchAllOf() && *this && other; + } + template + MatchAnyOf MatcherBase::operator || ( MatcherBase const& other ) const { + return MatchAnyOf() || *this || other; + } + template + MatchNotOf MatcherBase::operator ! () const { + return MatchNotOf( *this ); + } + + } // namespace Impl + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + // - deprecated: prefer ||, && and ! + template + inline Impl::MatchNotOf Not( Impl::MatcherBase const& underlyingMatcher ) { + return Impl::MatchNotOf( underlyingMatcher ); + } + template + inline Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { + return Impl::MatchAllOf() && m1 && m2; + } + template + inline Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { + return Impl::MatchAllOf() && m1 && m2 && m3; + } + template + inline Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { + return Impl::MatchAnyOf() || m1 || m2; + } + template + inline Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { + return Impl::MatchAnyOf() || m1 || m2 || m3; + } + +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch + +namespace Catch { + + struct TestFailureException{}; + + template class ExpressionLhs; + + struct CopyableStream { + CopyableStream() {} + CopyableStream( CopyableStream const& other ) { + oss << other.oss.str(); + } + CopyableStream& operator=( CopyableStream const& other ) { + oss.str(std::string()); + oss << other.oss.str(); + return *this; + } + std::ostringstream oss; + }; + + class ResultBuilder : public DecomposedExpression { + public: + ResultBuilder( char const* macroName, + SourceLineInfo const& lineInfo, + char const* capturedExpression, + ResultDisposition::Flags resultDisposition, + char const* secondArg = "" ); + + template + ExpressionLhs operator <= ( T const& operand ); + ExpressionLhs operator <= ( bool value ); + + template + ResultBuilder& operator << ( T const& value ) { + m_stream.oss << value; + return *this; + } + + ResultBuilder& setResultType( ResultWas::OfType result ); + ResultBuilder& setResultType( bool result ); + + void endExpression( DecomposedExpression const& expr ); + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE; + + AssertionResult build() const; + AssertionResult build( DecomposedExpression const& expr ) const; + + void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); + void captureResult( ResultWas::OfType resultType ); + void captureExpression(); + void captureExpectedException( std::string const& expectedMessage ); + void captureExpectedException( Matchers::Impl::MatcherBase const& matcher ); + void handleResult( AssertionResult const& result ); + void react(); + bool shouldDebugBreak() const; + bool allowThrows() const; + + template + void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ); + + private: + AssertionInfo m_assertionInfo; + AssertionResultData m_data; + CopyableStream m_stream; + + bool m_shouldDebugBreak; + bool m_shouldThrow; + }; + +} // namespace Catch + +// Include after due to circular dependency: +// #included from: catch_expression_lhs.hpp +#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED + +// #included from: catch_evaluate.hpp +#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4389) // '==' : signed/unsigned mismatch +#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) +#endif + +#include + +namespace Catch { +namespace Internal { + + enum Operator { + IsEqualTo, + IsNotEqualTo, + IsLessThan, + IsGreaterThan, + IsLessThanOrEqualTo, + IsGreaterThanOrEqualTo + }; + + template struct OperatorTraits { static const char* getName(){ return "*error*"; } }; + template<> struct OperatorTraits { static const char* getName(){ return "=="; } }; + template<> struct OperatorTraits { static const char* getName(){ return "!="; } }; + template<> struct OperatorTraits { static const char* getName(){ return "<"; } }; + template<> struct OperatorTraits { static const char* getName(){ return ">"; } }; + template<> struct OperatorTraits { static const char* getName(){ return "<="; } }; + template<> struct OperatorTraits{ static const char* getName(){ return ">="; } }; + + template + inline T& opCast(T const& t) { return const_cast(t); } + +// nullptr_t support based on pull request #154 from Konstantin Baumann +#ifdef CATCH_CONFIG_CPP11_NULLPTR + inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } +#endif // CATCH_CONFIG_CPP11_NULLPTR + + // So the compare overloads can be operator agnostic we convey the operator as a template + // enum, which is used to specialise an Evaluator for doing the comparison. + template + class Evaluator{}; + + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs) { + return bool( opCast( lhs ) == opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) != opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) < opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) > opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) >= opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) <= opCast( rhs ) ); + } + }; + + template + bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, rhs ); + } + + // This level of indirection allows us to specialise for integer types + // to avoid signed/ unsigned warnings + + // "base" overload + template + bool compare( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, rhs ); + } + + // unsigned X to int + template bool compare( unsigned int lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned long lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned char lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + + // unsigned X to long + template bool compare( unsigned int lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned long lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned char lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + + // int to unsigned X + template bool compare( int lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( int lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( int lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // long to unsigned X + template bool compare( long lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // pointer to long (when comparing against NULL) + template bool compare( long lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, long rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } + + // pointer to int (when comparing against NULL) + template bool compare( int lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, int rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG + // long long to unsigned X + template bool compare( long long lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned long long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // unsigned long long to X + template bool compare( unsigned long long lhs, int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, long long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // pointer to long long (when comparing against NULL) + template bool compare( long long lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, long long rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } +#endif // CATCH_CONFIG_CPP11_LONG_LONG + +#ifdef CATCH_CONFIG_CPP11_NULLPTR + // pointer to nullptr_t (when comparing against nullptr) + template bool compare( std::nullptr_t, T* rhs ) { + return Evaluator::evaluate( nullptr, rhs ); + } + template bool compare( T* lhs, std::nullptr_t ) { + return Evaluator::evaluate( lhs, nullptr ); + } +#endif // CATCH_CONFIG_CPP11_NULLPTR + +} // end of namespace Internal +} // end of namespace Catch + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// #included from: catch_tostring.h +#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED + +#include +#include +#include +#include +#include + +#ifdef __OBJC__ +// #included from: catch_objc_arc.hpp +#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED + +#import + +#ifdef __has_feature +#define CATCH_ARC_ENABLED __has_feature(objc_arc) +#else +#define CATCH_ARC_ENABLED 0 +#endif + +void arcSafeRelease( NSObject* obj ); +id performOptionalSelector( id obj, SEL sel ); + +#if !CATCH_ARC_ENABLED +inline void arcSafeRelease( NSObject* obj ) { + [obj release]; +} +inline id performOptionalSelector( id obj, SEL sel ) { + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; + return nil; +} +#define CATCH_UNSAFE_UNRETAINED +#define CATCH_ARC_STRONG +#else +inline void arcSafeRelease( NSObject* ){} +inline id performOptionalSelector( id obj, SEL sel ) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#endif + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + return nil; +} +#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained +#define CATCH_ARC_STRONG __strong +#endif + +#endif + +#ifdef CATCH_CONFIG_CPP11_TUPLE +#include +#endif + +#ifdef CATCH_CONFIG_CPP11_IS_ENUM +#include +#endif + +namespace Catch { + +// Why we're here. +template +std::string toString( T const& value ); + +// Built in overloads + +std::string toString( std::string const& value ); +std::string toString( std::wstring const& value ); +std::string toString( const char* const value ); +std::string toString( char* const value ); +std::string toString( const wchar_t* const value ); +std::string toString( wchar_t* const value ); +std::string toString( int value ); +std::string toString( unsigned long value ); +std::string toString( unsigned int value ); +std::string toString( const double value ); +std::string toString( const float value ); +std::string toString( bool value ); +std::string toString( char value ); +std::string toString( signed char value ); +std::string toString( unsigned char value ); + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG +std::string toString( long long value ); +std::string toString( unsigned long long value ); +#endif + +#ifdef CATCH_CONFIG_CPP11_NULLPTR +std::string toString( std::nullptr_t ); +#endif + +#ifdef __OBJC__ + std::string toString( NSString const * const& nsstring ); + std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ); + std::string toString( NSObject* const& nsObject ); +#endif + +namespace Detail { + + extern const std::string unprintableString; + + struct BorgType { + template BorgType( T const& ); + }; + + struct TrueType { char sizer[1]; }; + struct FalseType { char sizer[2]; }; + + TrueType& testStreamable( std::ostream& ); + FalseType testStreamable( FalseType ); + + FalseType operator<<( std::ostream const&, BorgType const& ); + + template + struct IsStreamInsertable { + static std::ostream &s; + static T const&t; + enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; + }; + +#if defined(CATCH_CONFIG_CPP11_IS_ENUM) + template::value + > + struct EnumStringMaker + { + static std::string convert( T const& ) { return unprintableString; } + }; + + template + struct EnumStringMaker + { + static std::string convert( T const& v ) + { + return ::Catch::toString( + static_cast::type>(v) + ); + } + }; +#endif + template + struct StringMakerBase { +#if defined(CATCH_CONFIG_CPP11_IS_ENUM) + template + static std::string convert( T const& v ) + { + return EnumStringMaker::convert( v ); + } +#else + template + static std::string convert( T const& ) { return unprintableString; } +#endif + }; + + template<> + struct StringMakerBase { + template + static std::string convert( T const& _value ) { + std::ostringstream oss; + oss << _value; + return oss.str(); + } + }; + + std::string rawMemoryToString( const void *object, std::size_t size ); + + template + inline std::string rawMemoryToString( const T& object ) { + return rawMemoryToString( &object, sizeof(object) ); + } + +} // end namespace Detail + +template +struct StringMaker : + Detail::StringMakerBase::value> {}; + +template +struct StringMaker { + template + static std::string convert( U* p ) { + if( !p ) + return "NULL"; + else + return Detail::rawMemoryToString( p ); + } +}; + +template +struct StringMaker { + static std::string convert( R C::* p ) { + if( !p ) + return "NULL"; + else + return Detail::rawMemoryToString( p ); + } +}; + +namespace Detail { + template + std::string rangeToString( InputIterator first, InputIterator last ); +} + +//template +//struct StringMaker > { +// static std::string convert( std::vector const& v ) { +// return Detail::rangeToString( v.begin(), v.end() ); +// } +//}; + +template +std::string toString( std::vector const& v ) { + return Detail::rangeToString( v.begin(), v.end() ); +} + +#ifdef CATCH_CONFIG_CPP11_TUPLE + +// toString for tuples +namespace TupleDetail { + template< + typename Tuple, + std::size_t N = 0, + bool = (N < std::tuple_size::value) + > + struct ElementPrinter { + static void print( const Tuple& tuple, std::ostream& os ) + { + os << ( N ? ", " : " " ) + << Catch::toString(std::get(tuple)); + ElementPrinter::print(tuple,os); + } + }; + + template< + typename Tuple, + std::size_t N + > + struct ElementPrinter { + static void print( const Tuple&, std::ostream& ) {} + }; + +} + +template +struct StringMaker> { + + static std::string convert( const std::tuple& tuple ) + { + std::ostringstream os; + os << '{'; + TupleDetail::ElementPrinter>::print( tuple, os ); + os << " }"; + return os.str(); + } +}; +#endif // CATCH_CONFIG_CPP11_TUPLE + +namespace Detail { + template + std::string makeString( T const& value ) { + return StringMaker::convert( value ); + } +} // end namespace Detail + +/// \brief converts any type to a string +/// +/// The default template forwards on to ostringstream - except when an +/// ostringstream overload does not exist - in which case it attempts to detect +/// that and writes {?}. +/// Overload (not specialise) this template for custom typs that you don't want +/// to provide an ostream overload for. +template +std::string toString( T const& value ) { + return StringMaker::convert( value ); +} + + namespace Detail { + template + std::string rangeToString( InputIterator first, InputIterator last ) { + std::ostringstream oss; + oss << "{ "; + if( first != last ) { + oss << Catch::toString( *first ); + for( ++first ; first != last ; ++first ) + oss << ", " << Catch::toString( *first ); + } + oss << " }"; + return oss.str(); + } +} + +} // end namespace Catch + +namespace Catch { + +template +class BinaryExpression; + +template +class MatchExpression; + +// Wraps the LHS of an expression and overloads comparison operators +// for also capturing those and RHS (if any) +template +class ExpressionLhs : public DecomposedExpression { +public: + ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {} + + ExpressionLhs& operator = ( const ExpressionLhs& ); + + template + BinaryExpression + operator == ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator != ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator < ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator > ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator <= ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator >= ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + BinaryExpression operator == ( bool rhs ) { + return captureExpression( rhs ); + } + + BinaryExpression operator != ( bool rhs ) { + return captureExpression( rhs ); + } + + void endExpression() { + m_truthy = m_lhs ? true : false; + m_rb + .setResultType( m_truthy ) + .endExpression( *this ); + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + dest = Catch::toString( m_truthy ); + } + +private: + template + BinaryExpression captureExpression( RhsT& rhs ) const { + return BinaryExpression( m_rb, m_lhs, rhs ); + } + + template + BinaryExpression captureExpression( bool rhs ) const { + return BinaryExpression( m_rb, m_lhs, rhs ); + } + +private: + ResultBuilder& m_rb; + T m_lhs; + bool m_truthy; +}; + +template +class BinaryExpression : public DecomposedExpression { +public: + BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs ) + : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {} + + BinaryExpression& operator = ( BinaryExpression& ); + + void endExpression() const { + m_rb + .setResultType( Internal::compare( m_lhs, m_rhs ) ) + .endExpression( *this ); + } + + virtual bool isBinaryExpression() const CATCH_OVERRIDE { + return true; + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + std::string lhs = Catch::toString( m_lhs ); + std::string rhs = Catch::toString( m_rhs ); + char delim = lhs.size() + rhs.size() < 40 && + lhs.find('\n') == std::string::npos && + rhs.find('\n') == std::string::npos ? ' ' : '\n'; + dest.reserve( 7 + lhs.size() + rhs.size() ); + // 2 for spaces around operator + // 2 for operator + // 2 for parentheses (conditionally added later) + // 1 for negation (conditionally added later) + dest = lhs; + dest += delim; + dest += Internal::OperatorTraits::getName(); + dest += delim; + dest += rhs; + } + +private: + ResultBuilder& m_rb; + LhsT m_lhs; + RhsT m_rhs; +}; + +template +class MatchExpression : public DecomposedExpression { +public: + MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString ) + : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {} + + virtual bool isBinaryExpression() const CATCH_OVERRIDE { + return true; + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + std::string matcherAsString = m_matcher.toString(); + dest = Catch::toString( m_arg ); + dest += ' '; + if( matcherAsString == Detail::unprintableString ) + dest += m_matcherString; + else + dest += matcherAsString; + } + +private: + ArgT m_arg; + MatcherT m_matcher; + char const* m_matcherString; +}; + +} // end namespace Catch + + +namespace Catch { + + template + inline ExpressionLhs ResultBuilder::operator <= ( T const& operand ) { + return ExpressionLhs( *this, operand ); + } + + inline ExpressionLhs ResultBuilder::operator <= ( bool value ) { + return ExpressionLhs( *this, value ); + } + + template + inline void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher, + char const* matcherString ) { + MatchExpression expr( arg, matcher, matcherString ); + setResultType( matcher.match( arg ) ); + endExpression( expr ); + } + +} // namespace Catch + +// #included from: catch_message.h +#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED + +#include + +namespace Catch { + + struct MessageInfo { + MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + std::string macroName; + SourceLineInfo lineInfo; + ResultWas::OfType type; + std::string message; + unsigned int sequence; + + bool operator == ( MessageInfo const& other ) const { + return sequence == other.sequence; + } + bool operator < ( MessageInfo const& other ) const { + return sequence < other.sequence; + } + private: + static unsigned int globalCount; + }; + + struct MessageBuilder { + MessageBuilder( std::string const& macroName, + SourceLineInfo const& lineInfo, + ResultWas::OfType type ) + : m_info( macroName, lineInfo, type ) + {} + + template + MessageBuilder& operator << ( T const& value ) { + m_stream << value; + return *this; + } + + MessageInfo m_info; + std::ostringstream m_stream; + }; + + class ScopedMessage { + public: + ScopedMessage( MessageBuilder const& builder ); + ScopedMessage( ScopedMessage const& other ); + ~ScopedMessage(); + + MessageInfo m_info; + }; + +} // end namespace Catch + +// #included from: catch_interfaces_capture.h +#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED + +#include + +namespace Catch { + + class TestCase; + class AssertionResult; + struct AssertionInfo; + struct SectionInfo; + struct SectionEndInfo; + struct MessageInfo; + class ScopedMessageBuilder; + struct Counts; + + struct IResultCapture { + + virtual ~IResultCapture(); + + virtual void assertionEnded( AssertionResult const& result ) = 0; + virtual bool sectionStarted( SectionInfo const& sectionInfo, + Counts& assertions ) = 0; + virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; + virtual void pushScopedMessage( MessageInfo const& message ) = 0; + virtual void popScopedMessage( MessageInfo const& message ) = 0; + + virtual std::string getCurrentTestName() const = 0; + virtual const AssertionResult* getLastResult() const = 0; + + virtual void handleFatalErrorCondition( std::string const& message ) = 0; + }; + + IResultCapture& getResultCapture(); +} + +// #included from: catch_debugger.h +#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED + +// #included from: catch_platform.h +#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED + +#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +# define CATCH_PLATFORM_MAC +#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +# define CATCH_PLATFORM_IPHONE +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +# define CATCH_PLATFORM_WINDOWS +# if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) +# define CATCH_DEFINES_NOMINMAX +# endif +# if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) +# define CATCH_DEFINES_WIN32_LEAN_AND_MEAN +# endif +#endif + +#include + +namespace Catch{ + + bool isDebuggerActive(); + void writeToDebugConsole( std::string const& text ); +} + +#ifdef CATCH_PLATFORM_MAC + + // The following code snippet based on: + // http://cocoawithlove.com/2008/03/break-into-debugger.html + #if defined(__ppc64__) || defined(__ppc__) + #define CATCH_TRAP() \ + __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ + : : : "memory","r0","r3","r4" ) + #else + #define CATCH_TRAP() __asm__("int $3\n" : : ) + #endif + +#elif defined(CATCH_PLATFORM_LINUX) + // If we can use inline assembler, do it because this allows us to break + // directly at the location of the failing check instead of breaking inside + // raise() called from it, i.e. one stack frame below. + #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) + #define CATCH_TRAP() asm volatile ("int $3") + #else // Fall back to the generic way. + #include + + #define CATCH_TRAP() raise(SIGTRAP) + #endif +#elif defined(_MSC_VER) + #define CATCH_TRAP() __debugbreak() +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) void __stdcall DebugBreak(); + #define CATCH_TRAP() DebugBreak() +#endif + +#ifdef CATCH_TRAP + #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } +#else + #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); +#endif + +// #included from: catch_interfaces_runner.h +#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED + +namespace Catch { + class TestCase; + + struct IRunner { + virtual ~IRunner(); + virtual bool aborting() const = 0; + }; +} + +// #included from: catch_type_traits.hpp +#define TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) +#include +#endif + +namespace Catch { + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) + + template + using add_lvalue_reference = std::add_lvalue_reference; + + template + using add_const = std::add_const; + +#else + + template + struct add_const { + typedef const T type; + }; + + template + struct add_lvalue_reference { + typedef T& type; + }; + template + struct add_lvalue_reference { + typedef T& type; + }; + // No && overload, because that is C++11, in which case we have + // proper type_traits implementation from the standard library + +#endif + +} + +#if defined(CATCH_CONFIG_FAST_COMPILE) +/////////////////////////////////////////////////////////////////////////////// +// We can speedup compilation significantly by breaking into debugger lower in +// the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER +// macro in each assertion +#define INTERNAL_CATCH_REACT( resultBuilder ) \ + resultBuilder.react(); +#else +/////////////////////////////////////////////////////////////////////////////// +// In the event of a failure works out if the debugger needs to be invoked +// and/or an exception thrown and takes appropriate action. +// This needs to be done as a macro so the debugger will stop in the user +// source code rather than in Catch library code +#define INTERNAL_CATCH_REACT( resultBuilder ) \ + if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ + resultBuilder.react(); +#endif + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ + try { \ + CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + ( __catchResult <= expr ).endExpression(); \ + CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look + // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ + INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ + if( Catch::getResultCapture().getLastResult()->succeeded() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ + INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ + if( !Catch::getResultCapture().getLastResult()->succeeded() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ + try { \ + static_cast(expr); \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \ + if( __catchResult.allowThrows() ) \ + try { \ + static_cast(expr); \ + __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ + } \ + catch( ... ) { \ + __catchResult.captureExpectedException( matcher ); \ + } \ + else \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr ", " #exceptionType, resultDisposition ); \ + if( __catchResult.allowThrows() ) \ + try { \ + static_cast(expr); \ + __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ + } \ + catch( Catch::add_const::type>::type ) { \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + else \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ + __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ + __catchResult.captureResult( messageType ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) +#else + #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ + __catchResult << log + ::Catch::StreamEndStop(); \ + __catchResult.captureResult( messageType ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) +#endif + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_INFO( log, macroName ) \ + Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \ + try { \ + __catchResult.captureMatch( arg, matcher, #matcher ); \ + } catch( ... ) { \ + __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +// #included from: internal/catch_section.h +#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED + +// #included from: catch_section_info.h +#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED + +// #included from: catch_totals.hpp +#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED + +#include + +namespace Catch { + + struct Counts { + Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} + + Counts operator - ( Counts const& other ) const { + Counts diff; + diff.passed = passed - other.passed; + diff.failed = failed - other.failed; + diff.failedButOk = failedButOk - other.failedButOk; + return diff; + } + Counts& operator += ( Counts const& other ) { + passed += other.passed; + failed += other.failed; + failedButOk += other.failedButOk; + return *this; + } + + std::size_t total() const { + return passed + failed + failedButOk; + } + bool allPassed() const { + return failed == 0 && failedButOk == 0; + } + bool allOk() const { + return failed == 0; + } + + std::size_t passed; + std::size_t failed; + std::size_t failedButOk; + }; + + struct Totals { + + Totals operator - ( Totals const& other ) const { + Totals diff; + diff.assertions = assertions - other.assertions; + diff.testCases = testCases - other.testCases; + return diff; + } + + Totals delta( Totals const& prevTotals ) const { + Totals diff = *this - prevTotals; + if( diff.assertions.failed > 0 ) + ++diff.testCases.failed; + else if( diff.assertions.failedButOk > 0 ) + ++diff.testCases.failedButOk; + else + ++diff.testCases.passed; + return diff; + } + + Totals& operator += ( Totals const& other ) { + assertions += other.assertions; + testCases += other.testCases; + return *this; + } + + Counts assertions; + Counts testCases; + }; +} + +#include + +namespace Catch { + + struct SectionInfo { + SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description = std::string() ); + + std::string name; + std::string description; + SourceLineInfo lineInfo; + }; + + struct SectionEndInfo { + SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ) + : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) + {} + + SectionInfo sectionInfo; + Counts prevAssertions; + double durationInSeconds; + }; + +} // end namespace Catch + +// #included from: catch_timer.h +#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED + +#ifdef CATCH_PLATFORM_WINDOWS +typedef unsigned long long uint64_t; +#else +#include +#endif + +namespace Catch { + + class Timer { + public: + Timer() : m_ticks( 0 ) {} + void start(); + unsigned int getElapsedMicroseconds() const; + unsigned int getElapsedMilliseconds() const; + double getElapsedSeconds() const; + + private: + uint64_t m_ticks; + }; + +} // namespace Catch + +#include + +namespace Catch { + + class Section : NonCopyable { + public: + Section( SectionInfo const& info ); + ~Section(); + + // This indicates whether the section should be executed or not + operator bool() const; + + private: + SectionInfo m_info; + + std::string m_name; + Counts m_assertions; + bool m_sectionIncluded; + Timer m_timer; + }; + +} // end namespace Catch + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define INTERNAL_CATCH_SECTION( ... ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) +#else + #define INTERNAL_CATCH_SECTION( name, desc ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) +#endif + +// #included from: internal/catch_generators.hpp +#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED + +#include +#include +#include +#include + +namespace Catch { + +template +struct IGenerator { + virtual ~IGenerator() {} + virtual T getValue( std::size_t index ) const = 0; + virtual std::size_t size () const = 0; +}; + +template +class BetweenGenerator : public IGenerator { +public: + BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} + + virtual T getValue( std::size_t index ) const { + return m_from+static_cast( index ); + } + + virtual std::size_t size() const { + return static_cast( 1+m_to-m_from ); + } + +private: + + T m_from; + T m_to; +}; + +template +class ValuesGenerator : public IGenerator { +public: + ValuesGenerator(){} + + void add( T value ) { + m_values.push_back( value ); + } + + virtual T getValue( std::size_t index ) const { + return m_values[index]; + } + + virtual std::size_t size() const { + return m_values.size(); + } + +private: + std::vector m_values; +}; + +template +class CompositeGenerator { +public: + CompositeGenerator() : m_totalSize( 0 ) {} + + // *** Move semantics, similar to auto_ptr *** + CompositeGenerator( CompositeGenerator& other ) + : m_fileInfo( other.m_fileInfo ), + m_totalSize( 0 ) + { + move( other ); + } + + CompositeGenerator& setFileInfo( const char* fileInfo ) { + m_fileInfo = fileInfo; + return *this; + } + + ~CompositeGenerator() { + deleteAll( m_composed ); + } + + operator T () const { + size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); + + typename std::vector*>::const_iterator it = m_composed.begin(); + typename std::vector*>::const_iterator itEnd = m_composed.end(); + for( size_t index = 0; it != itEnd; ++it ) + { + const IGenerator* generator = *it; + if( overallIndex >= index && overallIndex < index + generator->size() ) + { + return generator->getValue( overallIndex-index ); + } + index += generator->size(); + } + CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); + return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so + } + + void add( const IGenerator* generator ) { + m_totalSize += generator->size(); + m_composed.push_back( generator ); + } + + CompositeGenerator& then( CompositeGenerator& other ) { + move( other ); + return *this; + } + + CompositeGenerator& then( T value ) { + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( value ); + add( valuesGen ); + return *this; + } + +private: + + void move( CompositeGenerator& other ) { + std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) ); + m_totalSize += other.m_totalSize; + other.m_composed.clear(); + } + + std::vector*> m_composed; + std::string m_fileInfo; + size_t m_totalSize; +}; + +namespace Generators +{ + template + CompositeGenerator between( T from, T to ) { + CompositeGenerator generators; + generators.add( new BetweenGenerator( from, to ) ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2 ) { + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + generators.add( valuesGen ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2, T val3 ){ + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + valuesGen->add( val3 ); + generators.add( valuesGen ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2, T val3, T val4 ) { + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + valuesGen->add( val3 ); + valuesGen->add( val4 ); + generators.add( valuesGen ); + return generators; + } + +} // end namespace Generators + +using namespace Generators; + +} // end namespace Catch + +#define INTERNAL_CATCH_LINESTR2( line ) #line +#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) + +#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) + +// #included from: internal/catch_interfaces_exception.h +#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED + +#include +#include + +// #included from: catch_interfaces_registry_hub.h +#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED + +#include + +namespace Catch { + + class TestCase; + struct ITestCaseRegistry; + struct IExceptionTranslatorRegistry; + struct IExceptionTranslator; + struct IReporterRegistry; + struct IReporterFactory; + + struct IRegistryHub { + virtual ~IRegistryHub(); + + virtual IReporterRegistry const& getReporterRegistry() const = 0; + virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; + virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; + }; + + struct IMutableRegistryHub { + virtual ~IMutableRegistryHub(); + virtual void registerReporter( std::string const& name, Ptr const& factory ) = 0; + virtual void registerListener( Ptr const& factory ) = 0; + virtual void registerTest( TestCase const& testInfo ) = 0; + virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; + }; + + IRegistryHub& getRegistryHub(); + IMutableRegistryHub& getMutableRegistryHub(); + void cleanUp(); + std::string translateActiveException(); + +} + +namespace Catch { + + typedef std::string(*exceptionTranslateFunction)(); + + struct IExceptionTranslator; + typedef std::vector ExceptionTranslators; + + struct IExceptionTranslator { + virtual ~IExceptionTranslator(); + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; + }; + + struct IExceptionTranslatorRegistry { + virtual ~IExceptionTranslatorRegistry(); + + virtual std::string translateActiveException() const = 0; + }; + + class ExceptionTranslatorRegistrar { + template + class ExceptionTranslator : public IExceptionTranslator { + public: + + ExceptionTranslator( std::string(*translateFunction)( T& ) ) + : m_translateFunction( translateFunction ) + {} + + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE { + try { + if( it == itEnd ) + throw; + else + return (*it)->translate( it+1, itEnd ); + } + catch( T& ex ) { + return m_translateFunction( ex ); + } + } + + protected: + std::string(*m_translateFunction)( T& ); + }; + + public: + template + ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { + getMutableRegistryHub().registerTranslator + ( new ExceptionTranslator( translateFunction ) ); + } + }; +} + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ + static std::string translatorName( signature ); \ + namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\ + static std::string translatorName( signature ) + +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) + +// #included from: internal/catch_approx.hpp +#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED + +#include +#include + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) +#include +#endif + +namespace Catch { +namespace Detail { + + class Approx { + public: + explicit Approx ( double value ) + : m_epsilon( std::numeric_limits::epsilon()*100 ), + m_margin( 0.0 ), + m_scale( 1.0 ), + m_value( value ) + {} + + Approx( Approx const& other ) + : m_epsilon( other.m_epsilon ), + m_margin( other.m_margin ), + m_scale( other.m_scale ), + m_value( other.m_value ) + {} + + static Approx custom() { + return Approx( 0 ); + } + + Approx operator()( double value ) { + Approx approx( value ); + approx.epsilon( m_epsilon ); + approx.margin( m_margin ); + approx.scale( m_scale ); + return approx; + } + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) + template ::value>::type> + friend bool operator == ( const T& lhs, Approx const& rhs ) { + // Thanks to Richard Harris for his help refining this formula + auto lhs_v = double(lhs); + bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value))); + if (relativeOK) { + return true; + } + return std::fabs(lhs_v - rhs.m_value) < rhs.m_margin; + } + + template ::value>::type> + friend bool operator == ( Approx const& lhs, const T& rhs ) { + return operator==( rhs, lhs ); + } + + template ::value>::type> + friend bool operator != ( T lhs, Approx const& rhs ) { + return !operator==( lhs, rhs ); + } + + template ::value>::type> + friend bool operator != ( Approx const& lhs, T rhs ) { + return !operator==( rhs, lhs ); + } + + template ::value>::type> + friend bool operator <= ( T lhs, Approx const& rhs ) + { + return double(lhs) < rhs.m_value || lhs == rhs; + } + + template ::value>::type> + friend bool operator <= ( Approx const& lhs, T rhs ) + { + return lhs.m_value < double(rhs) || lhs == rhs; + } + + template ::value>::type> + friend bool operator >= ( T lhs, Approx const& rhs ) + { + return double(lhs) > rhs.m_value || lhs == rhs; + } + + template ::value>::type> + friend bool operator >= ( Approx const& lhs, T rhs ) + { + return lhs.m_value > double(rhs) || lhs == rhs; + } +#else + friend bool operator == ( double lhs, Approx const& rhs ) { + // Thanks to Richard Harris for his help refining this formula + bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) ); + if (relativeOK) { + return true; + } + return std::fabs(lhs - rhs.m_value) < rhs.m_margin; + } + + friend bool operator == ( Approx const& lhs, double rhs ) { + return operator==( rhs, lhs ); + } + + friend bool operator != ( double lhs, Approx const& rhs ) { + return !operator==( lhs, rhs ); + } + + friend bool operator != ( Approx const& lhs, double rhs ) { + return !operator==( rhs, lhs ); + } + + friend bool operator <= ( double lhs, Approx const& rhs ) + { + return lhs < rhs.m_value || lhs == rhs; + } + + friend bool operator <= ( Approx const& lhs, double rhs ) + { + return lhs.m_value < rhs || lhs == rhs; + } + + friend bool operator >= ( double lhs, Approx const& rhs ) + { + return lhs > rhs.m_value || lhs == rhs; + } + + friend bool operator >= ( Approx const& lhs, double rhs ) + { + return lhs.m_value > rhs || lhs == rhs; + } +#endif + + Approx& epsilon( double newEpsilon ) { + m_epsilon = newEpsilon; + return *this; + } + + Approx& margin( double newMargin ) { + m_margin = newMargin; + return *this; + } + + Approx& scale( double newScale ) { + m_scale = newScale; + return *this; + } + + std::string toString() const { + std::ostringstream oss; + oss << "Approx( " << Catch::toString( m_value ) << " )"; + return oss.str(); + } + + private: + double m_epsilon; + double m_margin; + double m_scale; + double m_value; + }; +} + +template<> +inline std::string toString( Detail::Approx const& value ) { + return value.toString(); +} + +} // end namespace Catch + +// #included from: internal/catch_matchers_string.h +#define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED + +namespace Catch { +namespace Matchers { + + namespace StdString { + + struct CasedString + { + CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ); + std::string adjustString( std::string const& str ) const; + std::string caseSensitivitySuffix() const; + + CaseSensitive::Choice m_caseSensitivity; + std::string m_str; + }; + + struct StringMatcherBase : MatcherBase { + StringMatcherBase( std::string operation, CasedString const& comparator ); + virtual std::string describe() const CATCH_OVERRIDE; + + CasedString m_comparator; + std::string m_operation; + }; + + struct EqualsMatcher : StringMatcherBase { + EqualsMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + struct ContainsMatcher : StringMatcherBase { + ContainsMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + struct StartsWithMatcher : StringMatcherBase { + StartsWithMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + struct EndsWithMatcher : StringMatcherBase { + EndsWithMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + + } // namespace StdString + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + +} // namespace Matchers +} // namespace Catch + +// #included from: internal/catch_matchers_vector.h +#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED + +namespace Catch { +namespace Matchers { + + namespace Vector { + + template + struct ContainsElementMatcher : MatcherBase, T> { + + ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} + + bool match(std::vector const &v) const CATCH_OVERRIDE { + return std::find(v.begin(), v.end(), m_comparator) != v.end(); + } + + virtual std::string describe() const CATCH_OVERRIDE { + return "Contains: " + Catch::toString( m_comparator ); + } + + T const& m_comparator; + }; + + template + struct ContainsMatcher : MatcherBase, std::vector > { + + ContainsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector const &v) const CATCH_OVERRIDE { + // !TBD: see note in EqualsMatcher + if (m_comparator.size() > v.size()) + return false; + for (size_t i = 0; i < m_comparator.size(); ++i) + if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end()) + return false; + return true; + } + virtual std::string describe() const CATCH_OVERRIDE { + return "Contains: " + Catch::toString( m_comparator ); + } + + std::vector const& m_comparator; + }; + + template + struct EqualsMatcher : MatcherBase, std::vector > { + + EqualsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector const &v) const CATCH_OVERRIDE { + // !TBD: This currently works if all elements can be compared using != + // - a more general approach would be via a compare template that defaults + // to using !=. but could be specialised for, e.g. std::vector etc + // - then just call that directly + if (m_comparator.size() != v.size()) + return false; + for (size_t i = 0; i < v.size(); ++i) + if (m_comparator[i] != v[i]) + return false; + return true; + } + virtual std::string describe() const CATCH_OVERRIDE { + return "Equals: " + Catch::toString( m_comparator ); + } + std::vector const& m_comparator; + }; + + } // namespace Vector + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + template + Vector::ContainsMatcher Contains( std::vector const& comparator ) { + return Vector::ContainsMatcher( comparator ); + } + + template + Vector::ContainsElementMatcher VectorContains( T const& comparator ) { + return Vector::ContainsElementMatcher( comparator ); + } + + template + Vector::EqualsMatcher Equals( std::vector const& comparator ) { + return Vector::EqualsMatcher( comparator ); + } + +} // namespace Matchers +} // namespace Catch + +// #included from: internal/catch_interfaces_tag_alias_registry.h +#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED + +// #included from: catch_tag_alias.h +#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED + +#include + +namespace Catch { + + struct TagAlias { + TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} + + std::string tag; + SourceLineInfo lineInfo; + }; + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } +// #included from: catch_option.hpp +#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED + +namespace Catch { + + // An optional type + template + class Option { + public: + Option() : nullableValue( CATCH_NULL ) {} + Option( T const& _value ) + : nullableValue( new( storage ) T( _value ) ) + {} + Option( Option const& _other ) + : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL ) + {} + + ~Option() { + reset(); + } + + Option& operator= ( Option const& _other ) { + if( &_other != this ) { + reset(); + if( _other ) + nullableValue = new( storage ) T( *_other ); + } + return *this; + } + Option& operator = ( T const& _value ) { + reset(); + nullableValue = new( storage ) T( _value ); + return *this; + } + + void reset() { + if( nullableValue ) + nullableValue->~T(); + nullableValue = CATCH_NULL; + } + + T& operator*() { return *nullableValue; } + T const& operator*() const { return *nullableValue; } + T* operator->() { return nullableValue; } + const T* operator->() const { return nullableValue; } + + T valueOr( T const& defaultValue ) const { + return nullableValue ? *nullableValue : defaultValue; + } + + bool some() const { return nullableValue != CATCH_NULL; } + bool none() const { return nullableValue == CATCH_NULL; } + + bool operator !() const { return nullableValue == CATCH_NULL; } + operator SafeBool::type() const { + return SafeBool::makeSafe( some() ); + } + + private: + T* nullableValue; + char storage[sizeof(T)]; + }; + +} // end namespace Catch + +namespace Catch { + + struct ITagAliasRegistry { + virtual ~ITagAliasRegistry(); + virtual Option find( std::string const& alias ) const = 0; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; + + static ITagAliasRegistry const& get(); + }; + +} // end namespace Catch + +// These files are included here so the single_include script doesn't put them +// in the conditionally compiled sections +// #included from: internal/catch_test_case_info.h +#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED + +#include +#include + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + struct ITestCase; + + struct TestCaseInfo { + enum SpecialProperties{ + None = 0, + IsHidden = 1 << 1, + ShouldFail = 1 << 2, + MayFail = 1 << 3, + Throws = 1 << 4, + NonPortable = 1 << 5 + }; + + TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::set const& _tags, + SourceLineInfo const& _lineInfo ); + + TestCaseInfo( TestCaseInfo const& other ); + + friend void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ); + + bool isHidden() const; + bool throws() const; + bool okToFail() const; + bool expectedToFail() const; + + std::string name; + std::string className; + std::string description; + std::set tags; + std::set lcaseTags; + std::string tagsAsString; + SourceLineInfo lineInfo; + SpecialProperties properties; + }; + + class TestCase : public TestCaseInfo { + public: + + TestCase( ITestCase* testCase, TestCaseInfo const& info ); + TestCase( TestCase const& other ); + + TestCase withName( std::string const& _newName ) const; + + void invoke() const; + + TestCaseInfo const& getTestCaseInfo() const; + + void swap( TestCase& other ); + bool operator == ( TestCase const& other ) const; + bool operator < ( TestCase const& other ) const; + TestCase& operator = ( TestCase const& other ); + + private: + Ptr test; + }; + + TestCase makeTestCase( ITestCase* testCase, + std::string const& className, + std::string const& name, + std::string const& description, + SourceLineInfo const& lineInfo ); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + +#ifdef __OBJC__ +// #included from: internal/catch_objc.hpp +#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED + +#import + +#include + +// NB. Any general catch headers included here must be included +// in catch.hpp first to make sure they are included by the single +// header for non obj-usage + +/////////////////////////////////////////////////////////////////////////////// +// This protocol is really only here for (self) documenting purposes, since +// all its methods are optional. +@protocol OcFixture + +@optional + +-(void) setUp; +-(void) tearDown; + +@end + +namespace Catch { + + class OcMethod : public SharedImpl { + + public: + OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} + + virtual void invoke() const { + id obj = [[m_cls alloc] init]; + + performOptionalSelector( obj, @selector(setUp) ); + performOptionalSelector( obj, m_sel ); + performOptionalSelector( obj, @selector(tearDown) ); + + arcSafeRelease( obj ); + } + private: + virtual ~OcMethod() {} + + Class m_cls; + SEL m_sel; + }; + + namespace Detail{ + + inline std::string getAnnotation( Class cls, + std::string const& annotationName, + std::string const& testCaseName ) { + NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; + SEL sel = NSSelectorFromString( selStr ); + arcSafeRelease( selStr ); + id value = performOptionalSelector( cls, sel ); + if( value ) + return [(NSString*)value UTF8String]; + return ""; + } + } + + inline size_t registerTestMethods() { + size_t noTestMethods = 0; + int noClasses = objc_getClassList( CATCH_NULL, 0 ); + + Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); + objc_getClassList( classes, noClasses ); + + for( int c = 0; c < noClasses; c++ ) { + Class cls = classes[c]; + { + u_int count; + Method* methods = class_copyMethodList( cls, &count ); + for( u_int m = 0; m < count ; m++ ) { + SEL selector = method_getName(methods[m]); + std::string methodName = sel_getName(selector); + if( startsWith( methodName, "Catch_TestCase_" ) ) { + std::string testCaseName = methodName.substr( 15 ); + std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); + std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); + const char* className = class_getName( cls ); + + getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); + noTestMethods++; + } + } + free(methods); + } + } + return noTestMethods; + } + + namespace Matchers { + namespace Impl { + namespace NSStringMatchers { + + template + struct StringHolder : MatcherImpl{ + StringHolder( NSString* substr ) : m_substr( [substr copy] ){} + StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} + StringHolder() { + arcSafeRelease( m_substr ); + } + + NSString* m_substr; + }; + + struct Equals : StringHolder { + Equals( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str isEqualToString:m_substr]; + } + + virtual std::string toString() const { + return "equals string: " + Catch::toString( m_substr ); + } + }; + + struct Contains : StringHolder { + Contains( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location != NSNotFound; + } + + virtual std::string toString() const { + return "contains string: " + Catch::toString( m_substr ); + } + }; + + struct StartsWith : StringHolder { + StartsWith( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == 0; + } + + virtual std::string toString() const { + return "starts with: " + Catch::toString( m_substr ); + } + }; + struct EndsWith : StringHolder { + EndsWith( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == [str length] - [m_substr length]; + } + + virtual std::string toString() const { + return "ends with: " + Catch::toString( m_substr ); + } + }; + + } // namespace NSStringMatchers + } // namespace Impl + + inline Impl::NSStringMatchers::Equals + Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } + + inline Impl::NSStringMatchers::Contains + Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } + + inline Impl::NSStringMatchers::StartsWith + StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } + + inline Impl::NSStringMatchers::EndsWith + EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } + + } // namespace Matchers + + using namespace Matchers; + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define OC_TEST_CASE( name, desc )\ ++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ +{\ +return @ name; \ +}\ ++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ +{ \ +return @ desc; \ +} \ +-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) + +#endif + +#ifdef CATCH_IMPL + +// !TBD: Move the leak detector code into a separate header +#ifdef CATCH_CONFIG_WINDOWS_CRTDBG +#include +class LeakDetector { +public: + LeakDetector() { + int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + flag |= _CRTDBG_LEAK_CHECK_DF; + flag |= _CRTDBG_ALLOC_MEM_DF; + _CrtSetDbgFlag(flag); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + // Change this to leaking allocation's number to break there + _CrtSetBreakAlloc(-1); + } +}; +#else +class LeakDetector {}; +#endif + +LeakDetector leakDetector; + +// #included from: internal/catch_impl.hpp +#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED + +// Collect all the implementation files together here +// These are the equivalent of what would usually be cpp files + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#endif + +// #included from: ../catch_session.hpp +#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED + +// #included from: internal/catch_commandline.hpp +#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED + +// #included from: catch_config.hpp +#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED + +// #included from: catch_test_spec_parser.hpp +#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// #included from: catch_test_spec.hpp +#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// #included from: catch_wildcard_pattern.hpp +#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED + +#include + +namespace Catch +{ + class WildcardPattern { + enum WildcardPosition { + NoWildcard = 0, + WildcardAtStart = 1, + WildcardAtEnd = 2, + WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd + }; + + public: + + WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_wildcard( NoWildcard ), + m_pattern( adjustCase( pattern ) ) + { + if( startsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 1 ); + m_wildcard = WildcardAtStart; + } + if( endsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); + m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); + } + } + virtual ~WildcardPattern(); + virtual bool matches( std::string const& str ) const { + switch( m_wildcard ) { + case NoWildcard: + return m_pattern == adjustCase( str ); + case WildcardAtStart: + return endsWith( adjustCase( str ), m_pattern ); + case WildcardAtEnd: + return startsWith( adjustCase( str ), m_pattern ); + case WildcardAtBothEnds: + return contains( adjustCase( str ), m_pattern ); + } + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" +#endif + throw std::logic_error( "Unknown enum" ); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + } + private: + std::string adjustCase( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; + } + CaseSensitive::Choice m_caseSensitivity; + WildcardPosition m_wildcard; + std::string m_pattern; + }; +} + +#include +#include + +namespace Catch { + + class TestSpec { + struct Pattern : SharedImpl<> { + virtual ~Pattern(); + virtual bool matches( TestCaseInfo const& testCase ) const = 0; + }; + class NamePattern : public Pattern { + public: + NamePattern( std::string const& name ) + : m_wildcardPattern( toLower( name ), CaseSensitive::No ) + {} + virtual ~NamePattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { + return m_wildcardPattern.matches( toLower( testCase.name ) ); + } + private: + WildcardPattern m_wildcardPattern; + }; + + class TagPattern : public Pattern { + public: + TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} + virtual ~TagPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { + return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); + } + private: + std::string m_tag; + }; + + class ExcludedPattern : public Pattern { + public: + ExcludedPattern( Ptr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} + virtual ~ExcludedPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } + private: + Ptr m_underlyingPattern; + }; + + struct Filter { + std::vector > m_patterns; + + bool matches( TestCaseInfo const& testCase ) const { + // All patterns in a filter must match for the filter to be a match + for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) { + if( !(*it)->matches( testCase ) ) + return false; + } + return true; + } + }; + + public: + bool hasFilters() const { + return !m_filters.empty(); + } + bool matches( TestCaseInfo const& testCase ) const { + // A TestSpec matches if any filter matches + for( std::vector::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) + if( it->matches( testCase ) ) + return true; + return false; + } + + private: + std::vector m_filters; + + friend class TestSpecParser; + }; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +namespace Catch { + + class TestSpecParser { + enum Mode{ None, Name, QuotedName, Tag, EscapedName }; + Mode m_mode; + bool m_exclusion; + std::size_t m_start, m_pos; + std::string m_arg; + std::vector m_escapeChars; + TestSpec::Filter m_currentFilter; + TestSpec m_testSpec; + ITagAliasRegistry const* m_tagAliases; + + public: + TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} + + TestSpecParser& parse( std::string const& arg ) { + m_mode = None; + m_exclusion = false; + m_start = std::string::npos; + m_arg = m_tagAliases->expandAliases( arg ); + m_escapeChars.clear(); + for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) + visitChar( m_arg[m_pos] ); + if( m_mode == Name ) + addPattern(); + return *this; + } + TestSpec testSpec() { + addFilter(); + return m_testSpec; + } + private: + void visitChar( char c ) { + if( m_mode == None ) { + switch( c ) { + case ' ': return; + case '~': m_exclusion = true; return; + case '[': return startNewMode( Tag, ++m_pos ); + case '"': return startNewMode( QuotedName, ++m_pos ); + case '\\': return escape(); + default: startNewMode( Name, m_pos ); break; + } + } + if( m_mode == Name ) { + if( c == ',' ) { + addPattern(); + addFilter(); + } + else if( c == '[' ) { + if( subString() == "exclude:" ) + m_exclusion = true; + else + addPattern(); + startNewMode( Tag, ++m_pos ); + } + else if( c == '\\' ) + escape(); + } + else if( m_mode == EscapedName ) + m_mode = Name; + else if( m_mode == QuotedName && c == '"' ) + addPattern(); + else if( m_mode == Tag && c == ']' ) + addPattern(); + } + void startNewMode( Mode mode, std::size_t start ) { + m_mode = mode; + m_start = start; + } + void escape() { + if( m_mode == None ) + m_start = m_pos; + m_mode = EscapedName; + m_escapeChars.push_back( m_pos ); + } + std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } + template + void addPattern() { + std::string token = subString(); + for( size_t i = 0; i < m_escapeChars.size(); ++i ) + token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 ); + m_escapeChars.clear(); + if( startsWith( token, "exclude:" ) ) { + m_exclusion = true; + token = token.substr( 8 ); + } + if( !token.empty() ) { + Ptr pattern = new T( token ); + if( m_exclusion ) + pattern = new TestSpec::ExcludedPattern( pattern ); + m_currentFilter.m_patterns.push_back( pattern ); + } + m_exclusion = false; + m_mode = None; + } + void addFilter() { + if( !m_currentFilter.m_patterns.empty() ) { + m_testSpec.m_filters.push_back( m_currentFilter ); + m_currentFilter = TestSpec::Filter(); + } + } + }; + inline TestSpec parseTestSpec( std::string const& arg ) { + return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); + } + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// #included from: catch_interfaces_config.h +#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED + +#include +#include +#include + +namespace Catch { + + struct Verbosity { enum Level { + NoOutput = 0, + Quiet, + Normal + }; }; + + struct WarnAbout { enum What { + Nothing = 0x00, + NoAssertions = 0x01 + }; }; + + struct ShowDurations { enum OrNot { + DefaultForReporter, + Always, + Never + }; }; + struct RunTests { enum InWhatOrder { + InDeclarationOrder, + InLexicographicalOrder, + InRandomOrder + }; }; + struct UseColour { enum YesOrNo { + Auto, + Yes, + No + }; }; + + class TestSpec; + + struct IConfig : IShared { + + virtual ~IConfig(); + + virtual bool allowThrows() const = 0; + virtual std::ostream& stream() const = 0; + virtual std::string name() const = 0; + virtual bool includeSuccessfulResults() const = 0; + virtual bool shouldDebugBreak() const = 0; + virtual bool warnAboutMissingAssertions() const = 0; + virtual int abortAfter() const = 0; + virtual bool showInvisibles() const = 0; + virtual ShowDurations::OrNot showDurations() const = 0; + virtual TestSpec const& testSpec() const = 0; + virtual RunTests::InWhatOrder runOrder() const = 0; + virtual unsigned int rngSeed() const = 0; + virtual UseColour::YesOrNo useColour() const = 0; + virtual std::vector const& getSectionsToRun() const = 0; + + }; +} + +// #included from: catch_stream.h +#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED + +// #included from: catch_streambuf.h +#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED + +#include + +namespace Catch { + + class StreamBufBase : public std::streambuf { + public: + virtual ~StreamBufBase() CATCH_NOEXCEPT; + }; +} + +#include +#include +#include +#include + +namespace Catch { + + std::ostream& cout(); + std::ostream& cerr(); + + struct IStream { + virtual ~IStream() CATCH_NOEXCEPT; + virtual std::ostream& stream() const = 0; + }; + + class FileStream : public IStream { + mutable std::ofstream m_ofs; + public: + FileStream( std::string const& filename ); + virtual ~FileStream() CATCH_NOEXCEPT; + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; + + class CoutStream : public IStream { + mutable std::ostream m_os; + public: + CoutStream(); + virtual ~CoutStream() CATCH_NOEXCEPT; + + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; + + class DebugOutStream : public IStream { + CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf; + mutable std::ostream m_os; + public: + DebugOutStream(); + virtual ~DebugOutStream() CATCH_NOEXCEPT; + + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; +} + +#include +#include +#include +#include + +#ifndef CATCH_CONFIG_CONSOLE_WIDTH +#define CATCH_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { + + struct ConfigData { + + ConfigData() + : listTests( false ), + listTags( false ), + listReporters( false ), + listTestNamesOnly( false ), + showSuccessfulTests( false ), + shouldDebugBreak( false ), + noThrow( false ), + showHelp( false ), + showInvisibles( false ), + filenamesAsTags( false ), + abortAfter( -1 ), + rngSeed( 0 ), + verbosity( Verbosity::Normal ), + warnings( WarnAbout::Nothing ), + showDurations( ShowDurations::DefaultForReporter ), + runOrder( RunTests::InDeclarationOrder ), + useColour( UseColour::Auto ) + {} + + bool listTests; + bool listTags; + bool listReporters; + bool listTestNamesOnly; + + bool showSuccessfulTests; + bool shouldDebugBreak; + bool noThrow; + bool showHelp; + bool showInvisibles; + bool filenamesAsTags; + + int abortAfter; + unsigned int rngSeed; + + Verbosity::Level verbosity; + WarnAbout::What warnings; + ShowDurations::OrNot showDurations; + RunTests::InWhatOrder runOrder; + UseColour::YesOrNo useColour; + + std::string outputFilename; + std::string name; + std::string processName; + + std::vector reporterNames; + std::vector testsOrTags; + std::vector sectionsToRun; + }; + + class Config : public SharedImpl { + private: + Config( Config const& other ); + Config& operator = ( Config const& other ); + virtual void dummy(); + public: + + Config() + {} + + Config( ConfigData const& data ) + : m_data( data ), + m_stream( openStream() ) + { + if( !data.testsOrTags.empty() ) { + TestSpecParser parser( ITagAliasRegistry::get() ); + for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) + parser.parse( data.testsOrTags[i] ); + m_testSpec = parser.testSpec(); + } + } + + virtual ~Config() {} + + std::string const& getFilename() const { + return m_data.outputFilename ; + } + + bool listTests() const { return m_data.listTests; } + bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } + bool listTags() const { return m_data.listTags; } + bool listReporters() const { return m_data.listReporters; } + + std::string getProcessName() const { return m_data.processName; } + + std::vector const& getReporterNames() const { return m_data.reporterNames; } + std::vector const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; } + + virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; } + + bool showHelp() const { return m_data.showHelp; } + + // IConfig interface + virtual bool allowThrows() const CATCH_OVERRIDE { return !m_data.noThrow; } + virtual std::ostream& stream() const CATCH_OVERRIDE { return m_stream->stream(); } + virtual std::string name() const CATCH_OVERRIDE { return m_data.name.empty() ? m_data.processName : m_data.name; } + virtual bool includeSuccessfulResults() const CATCH_OVERRIDE { return m_data.showSuccessfulTests; } + virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE { return m_data.warnings & WarnAbout::NoAssertions; } + virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; } + virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE { return m_data.runOrder; } + virtual unsigned int rngSeed() const CATCH_OVERRIDE { return m_data.rngSeed; } + virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE { return m_data.useColour; } + virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; } + virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; } + virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; } + + private: + + IStream const* openStream() { + if( m_data.outputFilename.empty() ) + return new CoutStream(); + else if( m_data.outputFilename[0] == '%' ) { + if( m_data.outputFilename == "%debug" ) + return new DebugOutStream(); + else + throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename ); + } + else + return new FileStream( m_data.outputFilename ); + } + ConfigData m_data; + + CATCH_AUTO_PTR( IStream const ) m_stream; + TestSpec m_testSpec; + }; + +} // end namespace Catch + +// #included from: catch_clara.h +#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED + +// Use Catch's value for console width (store Clara's off to the side, if present) +#ifdef CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH +#undef CLARA_CONFIG_CONSOLE_WIDTH +#endif +#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH + +// Declare Clara inside the Catch namespace +#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { +// #included from: ../external/clara.h + +// Version 0.0.2.4 + +// Only use header guard if we are not using an outer namespace +#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) + +#ifndef STITCH_CLARA_OPEN_NAMESPACE +#define TWOBLUECUBES_CLARA_H_INCLUDED +#define STITCH_CLARA_OPEN_NAMESPACE +#define STITCH_CLARA_CLOSE_NAMESPACE +#else +#define STITCH_CLARA_CLOSE_NAMESPACE } +#endif + +#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE + +// ----------- #included from tbc_text_format.h ----------- + +// Only use header guard if we are not using an outer namespace +#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) +#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +#define TBC_TEXT_FORMAT_H_INCLUDED +#endif + +#include +#include +#include +#include + +// Use optional outer namespace +#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { +#endif + +namespace Tbc { + +#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH + const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + struct TextAttributes { + TextAttributes() + : initialIndent( std::string::npos ), + indent( 0 ), + width( consoleWidth-1 ), + tabChar( '\t' ) + {} + + TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } + TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } + TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } + TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } + + std::size_t initialIndent; // indent of first line, or npos + std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos + std::size_t width; // maximum width of text, including indent. Longer text will wrap + char tabChar; // If this char is seen the indent is changed to current pos + }; + + class Text { + public: + Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) + : attr( _attr ) + { + std::string wrappableChars = " [({.,/|\\-"; + std::size_t indent = _attr.initialIndent != std::string::npos + ? _attr.initialIndent + : _attr.indent; + std::string remainder = _str; + + while( !remainder.empty() ) { + if( lines.size() >= 1000 ) { + lines.push_back( "... message truncated due to excessive size" ); + return; + } + std::size_t tabPos = std::string::npos; + std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); + std::size_t pos = remainder.find_first_of( '\n' ); + if( pos <= width ) { + width = pos; + } + pos = remainder.find_last_of( _attr.tabChar, width ); + if( pos != std::string::npos ) { + tabPos = pos; + if( remainder[width] == '\n' ) + width--; + remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); + } + + if( width == remainder.size() ) { + spliceLine( indent, remainder, width ); + } + else if( remainder[width] == '\n' ) { + spliceLine( indent, remainder, width ); + if( width <= 1 || remainder.size() != 1 ) + remainder = remainder.substr( 1 ); + indent = _attr.indent; + } + else { + pos = remainder.find_last_of( wrappableChars, width ); + if( pos != std::string::npos && pos > 0 ) { + spliceLine( indent, remainder, pos ); + if( remainder[0] == ' ' ) + remainder = remainder.substr( 1 ); + } + else { + spliceLine( indent, remainder, width-1 ); + lines.back() += "-"; + } + if( lines.size() == 1 ) + indent = _attr.indent; + if( tabPos != std::string::npos ) + indent += tabPos; + } + } + } + + void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { + lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); + _remainder = _remainder.substr( _pos ); + } + + typedef std::vector::const_iterator const_iterator; + + const_iterator begin() const { return lines.begin(); } + const_iterator end() const { return lines.end(); } + std::string const& last() const { return lines.back(); } + std::size_t size() const { return lines.size(); } + std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } + std::string toString() const { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + + inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { + for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); + it != itEnd; ++it ) { + if( it != _text.begin() ) + _stream << "\n"; + _stream << *it; + } + return _stream; + } + + private: + std::string str; + TextAttributes attr; + std::vector lines; + }; + +} // end namespace Tbc + +#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +} // end outer namespace +#endif + +#endif // TBC_TEXT_FORMAT_H_INCLUDED + +// ----------- end of #include from tbc_text_format.h ----------- +// ........... back in clara.h + +#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE + +// ----------- #included from clara_compilers.h ----------- + +#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED +#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED + +// Detect a number of compiler features - mostly C++11/14 conformance - by compiler +// The following features are defined: +// +// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported? +// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported? +// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods +// CLARA_CONFIG_CPP11_OVERRIDE : is override supported? +// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) + +// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported? + +// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported? + +// In general each macro has a _NO_ form +// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11 + +#ifdef __clang__ + +#if __has_feature(cxx_nullptr) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +#if __has_feature(cxx_noexcept) +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#endif + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// GCC +#ifdef __GNUC__ + +#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +// - otherwise more recent versions define __cplusplus >= 201103L +// and will get picked up below + +#endif // __GNUC__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +#if (_MSC_VER >= 1600) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#endif + +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// +// C++ language feature support + +// catch all support for C++11 +#if defined(__cplusplus) && __cplusplus >= 201103L + +#define CLARA_CPP11_OR_GREATER + +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#endif + +#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#endif + +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) +#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE +#endif +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) +#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#endif // __cplusplus >= 201103L + +// Now set the actual defines based on the above + anything the user has configured +#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_NULLPTR +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_NOEXCEPT +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_GENERATED_METHODS +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_OVERRIDE +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_UNIQUE_PTR +#endif + +// noexcept support: +#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT) +#define CLARA_NOEXCEPT noexcept +# define CLARA_NOEXCEPT_IS(x) noexcept(x) +#else +#define CLARA_NOEXCEPT throw() +# define CLARA_NOEXCEPT_IS(x) +#endif + +// nullptr support +#ifdef CLARA_CONFIG_CPP11_NULLPTR +#define CLARA_NULL nullptr +#else +#define CLARA_NULL NULL +#endif + +// override support +#ifdef CLARA_CONFIG_CPP11_OVERRIDE +#define CLARA_OVERRIDE override +#else +#define CLARA_OVERRIDE +#endif + +// unique_ptr support +#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR +# define CLARA_AUTO_PTR( T ) std::unique_ptr +#else +# define CLARA_AUTO_PTR( T ) std::auto_ptr +#endif + +#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED + +// ----------- end of #include from clara_compilers.h ----------- +// ........... back in clara.h + +#include +#include +#include + +#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +#define CLARA_PLATFORM_WINDOWS +#endif + +// Use optional outer namespace +#ifdef STITCH_CLARA_OPEN_NAMESPACE +STITCH_CLARA_OPEN_NAMESPACE +#endif + +namespace Clara { + + struct UnpositionalTag {}; + + extern UnpositionalTag _; + +#ifdef CLARA_CONFIG_MAIN + UnpositionalTag _; +#endif + + namespace Detail { + +#ifdef CLARA_CONSOLE_WIDTH + const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + using namespace Tbc; + + inline bool startsWith( std::string const& str, std::string const& prefix ) { + return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; + } + + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + + template struct IsBool { static const bool value = false; }; + template<> struct IsBool { static const bool value = true; }; + + template + void convertInto( std::string const& _source, T& _dest ) { + std::stringstream ss; + ss << _source; + ss >> _dest; + if( ss.fail() ) + throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); + } + inline void convertInto( std::string const& _source, std::string& _dest ) { + _dest = _source; + } + char toLowerCh(char c) { + return static_cast( ::tolower( c ) ); + } + inline void convertInto( std::string const& _source, bool& _dest ) { + std::string sourceLC = _source; + std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh ); + if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) + _dest = true; + else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) + _dest = false; + else + throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); + } + + template + struct IArgFunction { + virtual ~IArgFunction() {} +#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS + IArgFunction() = default; + IArgFunction( IArgFunction const& ) = default; +#endif + virtual void set( ConfigT& config, std::string const& value ) const = 0; + virtual bool takesArg() const = 0; + virtual IArgFunction* clone() const = 0; + }; + + template + class BoundArgFunction { + public: + BoundArgFunction() : functionObj( CLARA_NULL ) {} + BoundArgFunction( IArgFunction* _functionObj ) : functionObj( _functionObj ) {} + BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {} + BoundArgFunction& operator = ( BoundArgFunction const& other ) { + IArgFunction* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL; + delete functionObj; + functionObj = newFunctionObj; + return *this; + } + ~BoundArgFunction() { delete functionObj; } + + void set( ConfigT& config, std::string const& value ) const { + functionObj->set( config, value ); + } + bool takesArg() const { return functionObj->takesArg(); } + + bool isSet() const { + return functionObj != CLARA_NULL; + } + private: + IArgFunction* functionObj; + }; + + template + struct NullBinder : IArgFunction{ + virtual void set( C&, std::string const& ) const {} + virtual bool takesArg() const { return true; } + virtual IArgFunction* clone() const { return new NullBinder( *this ); } + }; + + template + struct BoundDataMember : IArgFunction{ + BoundDataMember( M C::* _member ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + convertInto( stringValue, p.*member ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundDataMember( *this ); } + M C::* member; + }; + template + struct BoundUnaryMethod : IArgFunction{ + BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + typename RemoveConstRef::type value; + convertInto( stringValue, value ); + (p.*member)( value ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundUnaryMethod( *this ); } + void (C::*member)( M ); + }; + template + struct BoundNullaryMethod : IArgFunction{ + BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + bool value; + convertInto( stringValue, value ); + if( value ) + (p.*member)(); + } + virtual bool takesArg() const { return false; } + virtual IArgFunction* clone() const { return new BoundNullaryMethod( *this ); } + void (C::*member)(); + }; + + template + struct BoundUnaryFunction : IArgFunction{ + BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} + virtual void set( C& obj, std::string const& stringValue ) const { + bool value; + convertInto( stringValue, value ); + if( value ) + function( obj ); + } + virtual bool takesArg() const { return false; } + virtual IArgFunction* clone() const { return new BoundUnaryFunction( *this ); } + void (*function)( C& ); + }; + + template + struct BoundBinaryFunction : IArgFunction{ + BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} + virtual void set( C& obj, std::string const& stringValue ) const { + typename RemoveConstRef::type value; + convertInto( stringValue, value ); + function( obj, value ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundBinaryFunction( *this ); } + void (*function)( C&, T ); + }; + + } // namespace Detail + + inline std::vector argsToVector( int argc, char const* const* const argv ) { + std::vector args( static_cast( argc ) ); + for( std::size_t i = 0; i < static_cast( argc ); ++i ) + args[i] = argv[i]; + + return args; + } + + class Parser { + enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional }; + Mode mode; + std::size_t from; + bool inQuotes; + public: + + struct Token { + enum Type { Positional, ShortOpt, LongOpt }; + Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} + Type type; + std::string data; + }; + + Parser() : mode( None ), from( 0 ), inQuotes( false ){} + + void parseIntoTokens( std::vector const& args, std::vector& tokens ) { + const std::string doubleDash = "--"; + for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i ) + parseIntoTokens( args[i], tokens); + } + + void parseIntoTokens( std::string const& arg, std::vector& tokens ) { + for( std::size_t i = 0; i <= arg.size(); ++i ) { + char c = arg[i]; + if( c == '"' ) + inQuotes = !inQuotes; + mode = handleMode( i, c, arg, tokens ); + } + } + Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + switch( mode ) { + case None: return handleNone( i, c ); + case MaybeShortOpt: return handleMaybeShortOpt( i, c ); + case ShortOpt: + case LongOpt: + case SlashOpt: return handleOpt( i, c, arg, tokens ); + case Positional: return handlePositional( i, c, arg, tokens ); + default: throw std::logic_error( "Unknown mode" ); + } + } + + Mode handleNone( std::size_t i, char c ) { + if( inQuotes ) { + from = i; + return Positional; + } + switch( c ) { + case '-': return MaybeShortOpt; +#ifdef CLARA_PLATFORM_WINDOWS + case '/': from = i+1; return SlashOpt; +#endif + default: from = i; return Positional; + } + } + Mode handleMaybeShortOpt( std::size_t i, char c ) { + switch( c ) { + case '-': from = i+1; return LongOpt; + default: from = i; return ShortOpt; + } + } + Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + if( std::string( ":=\0", 3 ).find( c ) == std::string::npos ) + return mode; + + std::string optName = arg.substr( from, i-from ); + if( mode == ShortOpt ) + for( std::size_t j = 0; j < optName.size(); ++j ) + tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) ); + else if( mode == SlashOpt && optName.size() == 1 ) + tokens.push_back( Token( Token::ShortOpt, optName ) ); + else + tokens.push_back( Token( Token::LongOpt, optName ) ); + return None; + } + Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos ) + return mode; + + std::string data = arg.substr( from, i-from ); + tokens.push_back( Token( Token::Positional, data ) ); + return None; + } + }; + + template + struct CommonArgProperties { + CommonArgProperties() {} + CommonArgProperties( Detail::BoundArgFunction const& _boundField ) : boundField( _boundField ) {} + + Detail::BoundArgFunction boundField; + std::string description; + std::string detail; + std::string placeholder; // Only value if boundField takes an arg + + bool takesArg() const { + return !placeholder.empty(); + } + void validate() const { + if( !boundField.isSet() ) + throw std::logic_error( "option not bound" ); + } + }; + struct OptionArgProperties { + std::vector shortNames; + std::string longName; + + bool hasShortName( std::string const& shortName ) const { + return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end(); + } + bool hasLongName( std::string const& _longName ) const { + return _longName == longName; + } + }; + struct PositionalArgProperties { + PositionalArgProperties() : position( -1 ) {} + int position; // -1 means non-positional (floating) + + bool isFixedPositional() const { + return position != -1; + } + }; + + template + class CommandLine { + + struct Arg : CommonArgProperties, OptionArgProperties, PositionalArgProperties { + Arg() {} + Arg( Detail::BoundArgFunction const& _boundField ) : CommonArgProperties( _boundField ) {} + + using CommonArgProperties::placeholder; // !TBD + + std::string dbgName() const { + if( !longName.empty() ) + return "--" + longName; + if( !shortNames.empty() ) + return "-" + shortNames[0]; + return "positional args"; + } + std::string commands() const { + std::ostringstream oss; + bool first = true; + std::vector::const_iterator it = shortNames.begin(), itEnd = shortNames.end(); + for(; it != itEnd; ++it ) { + if( first ) + first = false; + else + oss << ", "; + oss << "-" << *it; + } + if( !longName.empty() ) { + if( !first ) + oss << ", "; + oss << "--" << longName; + } + if( !placeholder.empty() ) + oss << " <" << placeholder << ">"; + return oss.str(); + } + }; + + typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr; + + friend void addOptName( Arg& arg, std::string const& optName ) + { + if( optName.empty() ) + return; + if( Detail::startsWith( optName, "--" ) ) { + if( !arg.longName.empty() ) + throw std::logic_error( "Only one long opt may be specified. '" + + arg.longName + + "' already specified, now attempting to add '" + + optName + "'" ); + arg.longName = optName.substr( 2 ); + } + else if( Detail::startsWith( optName, "-" ) ) + arg.shortNames.push_back( optName.substr( 1 ) ); + else + throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" ); + } + friend void setPositionalArg( Arg& arg, int position ) + { + arg.position = position; + } + + class ArgBuilder { + public: + ArgBuilder( Arg* arg ) : m_arg( arg ) {} + + // Bind a non-boolean data member (requires placeholder string) + template + void bind( M C::* field, std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundDataMember( field ); + m_arg->placeholder = placeholder; + } + // Bind a boolean data member (no placeholder required) + template + void bind( bool C::* field ) { + m_arg->boundField = new Detail::BoundDataMember( field ); + } + + // Bind a method taking a single, non-boolean argument (requires a placeholder string) + template + void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); + m_arg->placeholder = placeholder; + } + + // Bind a method taking a single, boolean argument (no placeholder string required) + template + void bind( void (C::* unaryMethod)( bool ) ) { + m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); + } + + // Bind a method that takes no arguments (will be called if opt is present) + template + void bind( void (C::* nullaryMethod)() ) { + m_arg->boundField = new Detail::BoundNullaryMethod( nullaryMethod ); + } + + // Bind a free function taking a single argument - the object to operate on (no placeholder string required) + template + void bind( void (* unaryFunction)( C& ) ) { + m_arg->boundField = new Detail::BoundUnaryFunction( unaryFunction ); + } + + // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) + template + void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundBinaryFunction( binaryFunction ); + m_arg->placeholder = placeholder; + } + + ArgBuilder& describe( std::string const& description ) { + m_arg->description = description; + return *this; + } + ArgBuilder& detail( std::string const& detail ) { + m_arg->detail = detail; + return *this; + } + + protected: + Arg* m_arg; + }; + + class OptBuilder : public ArgBuilder { + public: + OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} + OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} + + OptBuilder& operator[]( std::string const& optName ) { + addOptName( *ArgBuilder::m_arg, optName ); + return *this; + } + }; + + public: + + CommandLine() + : m_boundProcessName( new Detail::NullBinder() ), + m_highestSpecifiedArgPosition( 0 ), + m_throwOnUnrecognisedTokens( false ) + {} + CommandLine( CommandLine const& other ) + : m_boundProcessName( other.m_boundProcessName ), + m_options ( other.m_options ), + m_positionalArgs( other.m_positionalArgs ), + m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ), + m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens ) + { + if( other.m_floatingArg.get() ) + m_floatingArg.reset( new Arg( *other.m_floatingArg ) ); + } + + CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) { + m_throwOnUnrecognisedTokens = shouldThrow; + return *this; + } + + OptBuilder operator[]( std::string const& optName ) { + m_options.push_back( Arg() ); + addOptName( m_options.back(), optName ); + OptBuilder builder( &m_options.back() ); + return builder; + } + + ArgBuilder operator[]( int position ) { + m_positionalArgs.insert( std::make_pair( position, Arg() ) ); + if( position > m_highestSpecifiedArgPosition ) + m_highestSpecifiedArgPosition = position; + setPositionalArg( m_positionalArgs[position], position ); + ArgBuilder builder( &m_positionalArgs[position] ); + return builder; + } + + // Invoke this with the _ instance + ArgBuilder operator[]( UnpositionalTag ) { + if( m_floatingArg.get() ) + throw std::logic_error( "Only one unpositional argument can be added" ); + m_floatingArg.reset( new Arg() ); + ArgBuilder builder( m_floatingArg.get() ); + return builder; + } + + template + void bindProcessName( M C::* field ) { + m_boundProcessName = new Detail::BoundDataMember( field ); + } + template + void bindProcessName( void (C::*_unaryMethod)( M ) ) { + m_boundProcessName = new Detail::BoundUnaryMethod( _unaryMethod ); + } + + void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const { + typename std::vector::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it; + std::size_t maxWidth = 0; + for( it = itBegin; it != itEnd; ++it ) + maxWidth = (std::max)( maxWidth, it->commands().size() ); + + for( it = itBegin; it != itEnd; ++it ) { + Detail::Text usage( it->commands(), Detail::TextAttributes() + .setWidth( maxWidth+indent ) + .setIndent( indent ) ); + Detail::Text desc( it->description, Detail::TextAttributes() + .setWidth( width - maxWidth - 3 ) ); + + for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { + std::string usageCol = i < usage.size() ? usage[i] : ""; + os << usageCol; + + if( i < desc.size() && !desc[i].empty() ) + os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' ) + << desc[i]; + os << "\n"; + } + } + } + std::string optUsage() const { + std::ostringstream oss; + optUsage( oss ); + return oss.str(); + } + + void argSynopsis( std::ostream& os ) const { + for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) { + if( i > 1 ) + os << " "; + typename std::map::const_iterator it = m_positionalArgs.find( i ); + if( it != m_positionalArgs.end() ) + os << "<" << it->second.placeholder << ">"; + else if( m_floatingArg.get() ) + os << "<" << m_floatingArg->placeholder << ">"; + else + throw std::logic_error( "non consecutive positional arguments with no floating args" ); + } + // !TBD No indication of mandatory args + if( m_floatingArg.get() ) { + if( m_highestSpecifiedArgPosition > 1 ) + os << " "; + os << "[<" << m_floatingArg->placeholder << "> ...]"; + } + } + std::string argSynopsis() const { + std::ostringstream oss; + argSynopsis( oss ); + return oss.str(); + } + + void usage( std::ostream& os, std::string const& procName ) const { + validate(); + os << "usage:\n " << procName << " "; + argSynopsis( os ); + if( !m_options.empty() ) { + os << " [options]\n\nwhere options are: \n"; + optUsage( os, 2 ); + } + os << "\n"; + } + std::string usage( std::string const& procName ) const { + std::ostringstream oss; + usage( oss, procName ); + return oss.str(); + } + + ConfigT parse( std::vector const& args ) const { + ConfigT config; + parseInto( args, config ); + return config; + } + + std::vector parseInto( std::vector const& args, ConfigT& config ) const { + std::string processName = args[0]; + std::size_t lastSlash = processName.find_last_of( "/\\" ); + if( lastSlash != std::string::npos ) + processName = processName.substr( lastSlash+1 ); + m_boundProcessName.set( config, processName ); + std::vector tokens; + Parser parser; + parser.parseIntoTokens( args, tokens ); + return populate( tokens, config ); + } + + std::vector populate( std::vector const& tokens, ConfigT& config ) const { + validate(); + std::vector unusedTokens = populateOptions( tokens, config ); + unusedTokens = populateFixedArgs( unusedTokens, config ); + unusedTokens = populateFloatingArgs( unusedTokens, config ); + return unusedTokens; + } + + std::vector populateOptions( std::vector const& tokens, ConfigT& config ) const { + std::vector unusedTokens; + std::vector errors; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); + for(; it != itEnd; ++it ) { + Arg const& arg = *it; + + try { + if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) || + ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) { + if( arg.takesArg() ) { + if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional ) + errors.push_back( "Expected argument to option: " + token.data ); + else + arg.boundField.set( config, tokens[++i].data ); + } + else { + arg.boundField.set( config, "true" ); + } + break; + } + } + catch( std::exception& ex ) { + errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" ); + } + } + if( it == itEnd ) { + if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens ) + unusedTokens.push_back( token ); + else if( errors.empty() && m_throwOnUnrecognisedTokens ) + errors.push_back( "unrecognised option: " + token.data ); + } + } + if( !errors.empty() ) { + std::ostringstream oss; + for( std::vector::const_iterator it = errors.begin(), itEnd = errors.end(); + it != itEnd; + ++it ) { + if( it != errors.begin() ) + oss << "\n"; + oss << *it; + } + throw std::runtime_error( oss.str() ); + } + return unusedTokens; + } + std::vector populateFixedArgs( std::vector const& tokens, ConfigT& config ) const { + std::vector unusedTokens; + int position = 1; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + typename std::map::const_iterator it = m_positionalArgs.find( position ); + if( it != m_positionalArgs.end() ) + it->second.boundField.set( config, token.data ); + else + unusedTokens.push_back( token ); + if( token.type == Parser::Token::Positional ) + position++; + } + return unusedTokens; + } + std::vector populateFloatingArgs( std::vector const& tokens, ConfigT& config ) const { + if( !m_floatingArg.get() ) + return tokens; + std::vector unusedTokens; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + if( token.type == Parser::Token::Positional ) + m_floatingArg->boundField.set( config, token.data ); + else + unusedTokens.push_back( token ); + } + return unusedTokens; + } + + void validate() const + { + if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) + throw std::logic_error( "No options or arguments specified" ); + + for( typename std::vector::const_iterator it = m_options.begin(), + itEnd = m_options.end(); + it != itEnd; ++it ) + it->validate(); + } + + private: + Detail::BoundArgFunction m_boundProcessName; + std::vector m_options; + std::map m_positionalArgs; + ArgAutoPtr m_floatingArg; + int m_highestSpecifiedArgPosition; + bool m_throwOnUnrecognisedTokens; + }; + +} // end namespace Clara + +STITCH_CLARA_CLOSE_NAMESPACE +#undef STITCH_CLARA_OPEN_NAMESPACE +#undef STITCH_CLARA_CLOSE_NAMESPACE + +#endif // TWOBLUECUBES_CLARA_H_INCLUDED +#undef STITCH_CLARA_OPEN_NAMESPACE + +// Restore Clara's value for console width, if present +#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +#include +#include + +namespace Catch { + + inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } + inline void abortAfterX( ConfigData& config, int x ) { + if( x < 1 ) + throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" ); + config.abortAfter = x; + } + inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } + inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); } + inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); } + + inline void addWarning( ConfigData& config, std::string const& _warning ) { + if( _warning == "NoAssertions" ) + config.warnings = static_cast( config.warnings | WarnAbout::NoAssertions ); + else + throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' ); + } + inline void setOrder( ConfigData& config, std::string const& order ) { + if( startsWith( "declared", order ) ) + config.runOrder = RunTests::InDeclarationOrder; + else if( startsWith( "lexical", order ) ) + config.runOrder = RunTests::InLexicographicalOrder; + else if( startsWith( "random", order ) ) + config.runOrder = RunTests::InRandomOrder; + else + throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' ); + } + inline void setRngSeed( ConfigData& config, std::string const& seed ) { + if( seed == "time" ) { + config.rngSeed = static_cast( std::time(0) ); + } + else { + std::stringstream ss; + ss << seed; + ss >> config.rngSeed; + if( ss.fail() ) + throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" ); + } + } + inline void setVerbosity( ConfigData& config, int level ) { + // !TBD: accept strings? + config.verbosity = static_cast( level ); + } + inline void setShowDurations( ConfigData& config, bool _showDurations ) { + config.showDurations = _showDurations + ? ShowDurations::Always + : ShowDurations::Never; + } + inline void setUseColour( ConfigData& config, std::string const& value ) { + std::string mode = toLower( value ); + + if( mode == "yes" ) + config.useColour = UseColour::Yes; + else if( mode == "no" ) + config.useColour = UseColour::No; + else if( mode == "auto" ) + config.useColour = UseColour::Auto; + else + throw std::runtime_error( "colour mode must be one of: auto, yes or no" ); + } + inline void forceColour( ConfigData& config ) { + config.useColour = UseColour::Yes; + } + inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { + std::ifstream f( _filename.c_str() ); + if( !f.is_open() ) + throw std::domain_error( "Unable to load input file: " + _filename ); + + std::string line; + while( std::getline( f, line ) ) { + line = trim(line); + if( !line.empty() && !startsWith( line, '#' ) ) { + if( !startsWith( line, '"' ) ) + line = '"' + line + '"'; + addTestOrTags( config, line + ',' ); + } + } + } + + inline Clara::CommandLine makeCommandLineParser() { + + using namespace Clara; + CommandLine cli; + + cli.bindProcessName( &ConfigData::processName ); + + cli["-?"]["-h"]["--help"] + .describe( "display usage information" ) + .bind( &ConfigData::showHelp ); + + cli["-l"]["--list-tests"] + .describe( "list all/matching test cases" ) + .bind( &ConfigData::listTests ); + + cli["-t"]["--list-tags"] + .describe( "list all/matching tags" ) + .bind( &ConfigData::listTags ); + + cli["-s"]["--success"] + .describe( "include successful tests in output" ) + .bind( &ConfigData::showSuccessfulTests ); + + cli["-b"]["--break"] + .describe( "break into debugger on failure" ) + .bind( &ConfigData::shouldDebugBreak ); + + cli["-e"]["--nothrow"] + .describe( "skip exception tests" ) + .bind( &ConfigData::noThrow ); + + cli["-i"]["--invisibles"] + .describe( "show invisibles (tabs, newlines)" ) + .bind( &ConfigData::showInvisibles ); + + cli["-o"]["--out"] + .describe( "output filename" ) + .bind( &ConfigData::outputFilename, "filename" ); + + cli["-r"]["--reporter"] +// .placeholder( "name[:filename]" ) + .describe( "reporter to use (defaults to console)" ) + .bind( &addReporterName, "name" ); + + cli["-n"]["--name"] + .describe( "suite name" ) + .bind( &ConfigData::name, "name" ); + + cli["-a"]["--abort"] + .describe( "abort at first failure" ) + .bind( &abortAfterFirst ); + + cli["-x"]["--abortx"] + .describe( "abort after x failures" ) + .bind( &abortAfterX, "no. failures" ); + + cli["-w"]["--warn"] + .describe( "enable warnings" ) + .bind( &addWarning, "warning name" ); + +// - needs updating if reinstated +// cli.into( &setVerbosity ) +// .describe( "level of verbosity (0=no output)" ) +// .shortOpt( "v") +// .longOpt( "verbosity" ) +// .placeholder( "level" ); + + cli[_] + .describe( "which test or tests to use" ) + .bind( &addTestOrTags, "test name, pattern or tags" ); + + cli["-d"]["--durations"] + .describe( "show test durations" ) + .bind( &setShowDurations, "yes|no" ); + + cli["-f"]["--input-file"] + .describe( "load test names to run from a file" ) + .bind( &loadTestNamesFromFile, "filename" ); + + cli["-#"]["--filenames-as-tags"] + .describe( "adds a tag for the filename" ) + .bind( &ConfigData::filenamesAsTags ); + + cli["-c"]["--section"] + .describe( "specify section to run" ) + .bind( &addSectionToRun, "section name" ); + + // Less common commands which don't have a short form + cli["--list-test-names-only"] + .describe( "list all/matching test cases names only" ) + .bind( &ConfigData::listTestNamesOnly ); + + cli["--list-reporters"] + .describe( "list all reporters" ) + .bind( &ConfigData::listReporters ); + + cli["--order"] + .describe( "test case order (defaults to decl)" ) + .bind( &setOrder, "decl|lex|rand" ); + + cli["--rng-seed"] + .describe( "set a specific seed for random numbers" ) + .bind( &setRngSeed, "'time'|number" ); + + cli["--force-colour"] + .describe( "force colourised output (deprecated)" ) + .bind( &forceColour ); + + cli["--use-colour"] + .describe( "should output be colourised" ) + .bind( &setUseColour, "yes|no" ); + + return cli; + } + +} // end namespace Catch + +// #included from: internal/catch_list.hpp +#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED + +// #included from: catch_text.h +#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED + +#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH + +#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch +// #included from: ../external/tbc_text_format.h +// Only use header guard if we are not using an outer namespace +#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED +# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +# endif +# else +# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED +# endif +#endif +#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +#include +#include +#include + +// Use optional outer namespace +#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { +#endif + +namespace Tbc { + +#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH + const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + struct TextAttributes { + TextAttributes() + : initialIndent( std::string::npos ), + indent( 0 ), + width( consoleWidth-1 ) + {} + + TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } + TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } + TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } + + std::size_t initialIndent; // indent of first line, or npos + std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos + std::size_t width; // maximum width of text, including indent. Longer text will wrap + }; + + class Text { + public: + Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) + : attr( _attr ) + { + const std::string wrappableBeforeChars = "[({<\t"; + const std::string wrappableAfterChars = "])}>-,./|\\"; + const std::string wrappableInsteadOfChars = " \n\r"; + std::string indent = _attr.initialIndent != std::string::npos + ? std::string( _attr.initialIndent, ' ' ) + : std::string( _attr.indent, ' ' ); + + typedef std::string::const_iterator iterator; + iterator it = _str.begin(); + const iterator strEnd = _str.end(); + + while( it != strEnd ) { + + if( lines.size() >= 1000 ) { + lines.push_back( "... message truncated due to excessive size" ); + return; + } + + std::string suffix; + std::size_t width = (std::min)( static_cast( strEnd-it ), _attr.width-static_cast( indent.size() ) ); + iterator itEnd = it+width; + iterator itNext = _str.end(); + + iterator itNewLine = std::find( it, itEnd, '\n' ); + if( itNewLine != itEnd ) + itEnd = itNewLine; + + if( itEnd != strEnd ) { + bool foundWrapPoint = false; + iterator findIt = itEnd; + do { + if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) { + itEnd = findIt+1; + itNext = findIt+1; + foundWrapPoint = true; + } + else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) { + itEnd = findIt; + itNext = findIt; + foundWrapPoint = true; + } + else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) { + itNext = findIt+1; + itEnd = findIt; + foundWrapPoint = true; + } + if( findIt == it ) + break; + else + --findIt; + } + while( !foundWrapPoint ); + + if( !foundWrapPoint ) { + // No good wrap char, so we'll break mid word and add a hyphen + --itEnd; + itNext = itEnd; + suffix = "-"; + } + else { + while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos ) + --itEnd; + } + } + lines.push_back( indent + std::string( it, itEnd ) + suffix ); + + if( indent.size() != _attr.indent ) + indent = std::string( _attr.indent, ' ' ); + it = itNext; + } + } + + typedef std::vector::const_iterator const_iterator; + + const_iterator begin() const { return lines.begin(); } + const_iterator end() const { return lines.end(); } + std::string const& last() const { return lines.back(); } + std::size_t size() const { return lines.size(); } + std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } + std::string toString() const { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + + inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { + for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); + it != itEnd; ++it ) { + if( it != _text.begin() ) + _stream << "\n"; + _stream << *it; + } + return _stream; + } + + private: + std::string str; + TextAttributes attr; + std::vector lines; + }; + +} // end namespace Tbc + +#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +} // end outer namespace +#endif + +#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE + +namespace Catch { + using Tbc::Text; + using Tbc::TextAttributes; +} + +// #included from: catch_console_colour.hpp +#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED + +namespace Catch { + + struct Colour { + enum Code { + None = 0, + + White, + Red, + Green, + Blue, + Cyan, + Yellow, + Grey, + + Bright = 0x10, + + BrightRed = Bright | Red, + BrightGreen = Bright | Green, + LightGrey = Bright | Grey, + BrightWhite = Bright | White, + + // By intention + FileName = LightGrey, + Warning = Yellow, + ResultError = BrightRed, + ResultSuccess = BrightGreen, + ResultExpectedFailure = Warning, + + Error = BrightRed, + Success = Green, + + OriginalExpression = Cyan, + ReconstructedExpression = Yellow, + + SecondaryText = LightGrey, + Headers = White + }; + + // Use constructed object for RAII guard + Colour( Code _colourCode ); + Colour( Colour const& other ); + ~Colour(); + + // Use static method for one-shot changes + static void use( Code _colourCode ); + + private: + bool m_moved; + }; + + inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } + +} // end namespace Catch + +// #included from: catch_interfaces_reporter.h +#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED + +#include +#include +#include + +namespace Catch +{ + struct ReporterConfig { + explicit ReporterConfig( Ptr const& _fullConfig ) + : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} + + ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) + : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} + + std::ostream& stream() const { return *m_stream; } + Ptr fullConfig() const { return m_fullConfig; } + + private: + std::ostream* m_stream; + Ptr m_fullConfig; + }; + + struct ReporterPreferences { + ReporterPreferences() + : shouldRedirectStdOut( false ) + {} + + bool shouldRedirectStdOut; + }; + + template + struct LazyStat : Option { + LazyStat() : used( false ) {} + LazyStat& operator=( T const& _value ) { + Option::operator=( _value ); + used = false; + return *this; + } + void reset() { + Option::reset(); + used = false; + } + bool used; + }; + + struct TestRunInfo { + TestRunInfo( std::string const& _name ) : name( _name ) {} + std::string name; + }; + struct GroupInfo { + GroupInfo( std::string const& _name, + std::size_t _groupIndex, + std::size_t _groupsCount ) + : name( _name ), + groupIndex( _groupIndex ), + groupsCounts( _groupsCount ) + {} + + std::string name; + std::size_t groupIndex; + std::size_t groupsCounts; + }; + + struct AssertionStats { + AssertionStats( AssertionResult const& _assertionResult, + std::vector const& _infoMessages, + Totals const& _totals ) + : assertionResult( _assertionResult ), + infoMessages( _infoMessages ), + totals( _totals ) + { + if( assertionResult.hasMessage() ) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); + builder << assertionResult.getMessage(); + builder.m_info.message = builder.m_stream.str(); + + infoMessages.push_back( builder.m_info ); + } + } + virtual ~AssertionStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + AssertionStats( AssertionStats const& ) = default; + AssertionStats( AssertionStats && ) = default; + AssertionStats& operator = ( AssertionStats const& ) = default; + AssertionStats& operator = ( AssertionStats && ) = default; +# endif + + AssertionResult assertionResult; + std::vector infoMessages; + Totals totals; + }; + + struct SectionStats { + SectionStats( SectionInfo const& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ) + : sectionInfo( _sectionInfo ), + assertions( _assertions ), + durationInSeconds( _durationInSeconds ), + missingAssertions( _missingAssertions ) + {} + virtual ~SectionStats(); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + SectionStats( SectionStats const& ) = default; + SectionStats( SectionStats && ) = default; + SectionStats& operator = ( SectionStats const& ) = default; + SectionStats& operator = ( SectionStats && ) = default; +# endif + + SectionInfo sectionInfo; + Counts assertions; + double durationInSeconds; + bool missingAssertions; + }; + + struct TestCaseStats { + TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string const& _stdOut, + std::string const& _stdErr, + bool _aborting ) + : testInfo( _testInfo ), + totals( _totals ), + stdOut( _stdOut ), + stdErr( _stdErr ), + aborting( _aborting ) + {} + virtual ~TestCaseStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestCaseStats( TestCaseStats const& ) = default; + TestCaseStats( TestCaseStats && ) = default; + TestCaseStats& operator = ( TestCaseStats const& ) = default; + TestCaseStats& operator = ( TestCaseStats && ) = default; +# endif + + TestCaseInfo testInfo; + Totals totals; + std::string stdOut; + std::string stdErr; + bool aborting; + }; + + struct TestGroupStats { + TestGroupStats( GroupInfo const& _groupInfo, + Totals const& _totals, + bool _aborting ) + : groupInfo( _groupInfo ), + totals( _totals ), + aborting( _aborting ) + {} + TestGroupStats( GroupInfo const& _groupInfo ) + : groupInfo( _groupInfo ), + aborting( false ) + {} + virtual ~TestGroupStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestGroupStats( TestGroupStats const& ) = default; + TestGroupStats( TestGroupStats && ) = default; + TestGroupStats& operator = ( TestGroupStats const& ) = default; + TestGroupStats& operator = ( TestGroupStats && ) = default; +# endif + + GroupInfo groupInfo; + Totals totals; + bool aborting; + }; + + struct TestRunStats { + TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ) + : runInfo( _runInfo ), + totals( _totals ), + aborting( _aborting ) + {} + virtual ~TestRunStats(); + +# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestRunStats( TestRunStats const& _other ) + : runInfo( _other.runInfo ), + totals( _other.totals ), + aborting( _other.aborting ) + {} +# else + TestRunStats( TestRunStats const& ) = default; + TestRunStats( TestRunStats && ) = default; + TestRunStats& operator = ( TestRunStats const& ) = default; + TestRunStats& operator = ( TestRunStats && ) = default; +# endif + + TestRunInfo runInfo; + Totals totals; + bool aborting; + }; + + class MultipleReporters; + + struct IStreamingReporter : IShared { + virtual ~IStreamingReporter(); + + // Implementing class must also provide the following static method: + // static std::string getDescription(); + + virtual ReporterPreferences getPreferences() const = 0; + + virtual void noMatchingTestCases( std::string const& spec ) = 0; + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; + virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; + virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; + + virtual void sectionEnded( SectionStats const& sectionStats ) = 0; + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; + virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; + + virtual void skipTest( TestCaseInfo const& testInfo ) = 0; + + virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; } + }; + + struct IReporterFactory : IShared { + virtual ~IReporterFactory(); + virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; + virtual std::string getDescription() const = 0; + }; + + struct IReporterRegistry { + typedef std::map > FactoryMap; + typedef std::vector > Listeners; + + virtual ~IReporterRegistry(); + virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; + virtual FactoryMap const& getFactories() const = 0; + virtual Listeners const& getListeners() const = 0; + }; + + Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ); + +} + +#include +#include + +namespace Catch { + + inline std::size_t listTests( Config const& config ) { + + TestSpec testSpec = config.testSpec(); + if( config.testSpec().hasFilters() ) + Catch::cout() << "Matching test cases:\n"; + else { + Catch::cout() << "All available test cases:\n"; + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + } + + std::size_t matchedTests = 0; + TextAttributes nameAttr, tagsAttr; + nameAttr.setInitialIndent( 2 ).setIndent( 4 ); + tagsAttr.setIndent( 6 ); + + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + matchedTests++; + TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); + Colour::Code colour = testCaseInfo.isHidden() + ? Colour::SecondaryText + : Colour::None; + Colour colourGuard( colour ); + + Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; + if( !testCaseInfo.tags.empty() ) + Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; + } + + if( !config.testSpec().hasFilters() ) + Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl; + else + Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl; + return matchedTests; + } + + inline std::size_t listTestsNamesOnly( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( !config.testSpec().hasFilters() ) + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + std::size_t matchedTests = 0; + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + matchedTests++; + TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); + if( startsWith( testCaseInfo.name, '#' ) ) + Catch::cout() << '"' << testCaseInfo.name << '"' << std::endl; + else + Catch::cout() << testCaseInfo.name << std::endl; + } + return matchedTests; + } + + struct TagInfo { + TagInfo() : count ( 0 ) {} + void add( std::string const& spelling ) { + ++count; + spellings.insert( spelling ); + } + std::string all() const { + std::string out; + for( std::set::const_iterator it = spellings.begin(), itEnd = spellings.end(); + it != itEnd; + ++it ) + out += "[" + *it + "]"; + return out; + } + std::set spellings; + std::size_t count; + }; + + inline std::size_t listTags( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( config.testSpec().hasFilters() ) + Catch::cout() << "Tags for matching test cases:\n"; + else { + Catch::cout() << "All available tags:\n"; + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + } + + std::map tagCounts; + + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + for( std::set::const_iterator tagIt = it->getTestCaseInfo().tags.begin(), + tagItEnd = it->getTestCaseInfo().tags.end(); + tagIt != tagItEnd; + ++tagIt ) { + std::string tagName = *tagIt; + std::string lcaseTagName = toLower( tagName ); + std::map::iterator countIt = tagCounts.find( lcaseTagName ); + if( countIt == tagCounts.end() ) + countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; + countIt->second.add( tagName ); + } + } + + for( std::map::const_iterator countIt = tagCounts.begin(), + countItEnd = tagCounts.end(); + countIt != countItEnd; + ++countIt ) { + std::ostringstream oss; + oss << " " << std::setw(2) << countIt->second.count << " "; + Text wrapper( countIt->second.all(), TextAttributes() + .setInitialIndent( 0 ) + .setIndent( oss.str().size() ) + .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); + Catch::cout() << oss.str() << wrapper << '\n'; + } + Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; + return tagCounts.size(); + } + + inline std::size_t listReporters( Config const& /*config*/ ) { + Catch::cout() << "Available reporters:\n"; + IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); + IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; + std::size_t maxNameLen = 0; + for(it = itBegin; it != itEnd; ++it ) + maxNameLen = (std::max)( maxNameLen, it->first.size() ); + + for(it = itBegin; it != itEnd; ++it ) { + Text wrapper( it->second->getDescription(), TextAttributes() + .setInitialIndent( 0 ) + .setIndent( 7+maxNameLen ) + .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); + Catch::cout() << " " + << it->first + << ':' + << std::string( maxNameLen - it->first.size() + 2, ' ' ) + << wrapper << '\n'; + } + Catch::cout() << std::endl; + return factories.size(); + } + + inline Option list( Config const& config ) { + Option listedCount; + if( config.listTests() ) + listedCount = listedCount.valueOr(0) + listTests( config ); + if( config.listTestNamesOnly() ) + listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); + if( config.listTags() ) + listedCount = listedCount.valueOr(0) + listTags( config ); + if( config.listReporters() ) + listedCount = listedCount.valueOr(0) + listReporters( config ); + return listedCount; + } + +} // end namespace Catch + +// #included from: internal/catch_run_context.hpp +#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED + +// #included from: catch_test_case_tracker.hpp +#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +namespace Catch { +namespace TestCaseTracking { + + struct NameAndLocation { + std::string name; + SourceLineInfo location; + + NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) + : name( _name ), + location( _location ) + {} + }; + + struct ITracker : SharedImpl<> { + virtual ~ITracker(); + + // static queries + virtual NameAndLocation const& nameAndLocation() const = 0; + + // dynamic queries + virtual bool isComplete() const = 0; // Successfully completed or failed + virtual bool isSuccessfullyCompleted() const = 0; + virtual bool isOpen() const = 0; // Started but not complete + virtual bool hasChildren() const = 0; + + virtual ITracker& parent() = 0; + + // actions + virtual void close() = 0; // Successfully complete + virtual void fail() = 0; + virtual void markAsNeedingAnotherRun() = 0; + + virtual void addChild( Ptr const& child ) = 0; + virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0; + virtual void openChild() = 0; + + // Debug/ checking + virtual bool isSectionTracker() const = 0; + virtual bool isIndexTracker() const = 0; + }; + + class TrackerContext { + + enum RunState { + NotStarted, + Executing, + CompletedCycle + }; + + Ptr m_rootTracker; + ITracker* m_currentTracker; + RunState m_runState; + + public: + + static TrackerContext& instance() { + static TrackerContext s_instance; + return s_instance; + } + + TrackerContext() + : m_currentTracker( CATCH_NULL ), + m_runState( NotStarted ) + {} + + ITracker& startRun(); + + void endRun() { + m_rootTracker.reset(); + m_currentTracker = CATCH_NULL; + m_runState = NotStarted; + } + + void startCycle() { + m_currentTracker = m_rootTracker.get(); + m_runState = Executing; + } + void completeCycle() { + m_runState = CompletedCycle; + } + + bool completedCycle() const { + return m_runState == CompletedCycle; + } + ITracker& currentTracker() { + return *m_currentTracker; + } + void setCurrentTracker( ITracker* tracker ) { + m_currentTracker = tracker; + } + }; + + class TrackerBase : public ITracker { + protected: + enum CycleState { + NotStarted, + Executing, + ExecutingChildren, + NeedsAnotherRun, + CompletedSuccessfully, + Failed + }; + class TrackerHasName { + NameAndLocation m_nameAndLocation; + public: + TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {} + bool operator ()( Ptr const& tracker ) { + return + tracker->nameAndLocation().name == m_nameAndLocation.name && + tracker->nameAndLocation().location == m_nameAndLocation.location; + } + }; + typedef std::vector > Children; + NameAndLocation m_nameAndLocation; + TrackerContext& m_ctx; + ITracker* m_parent; + Children m_children; + CycleState m_runState; + public: + TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : m_nameAndLocation( nameAndLocation ), + m_ctx( ctx ), + m_parent( parent ), + m_runState( NotStarted ) + {} + virtual ~TrackerBase(); + + virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE { + return m_nameAndLocation; + } + virtual bool isComplete() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully || m_runState == Failed; + } + virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully; + } + virtual bool isOpen() const CATCH_OVERRIDE { + return m_runState != NotStarted && !isComplete(); + } + virtual bool hasChildren() const CATCH_OVERRIDE { + return !m_children.empty(); + } + + virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { + m_children.push_back( child ); + } + + virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE { + Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) ); + return( it != m_children.end() ) + ? it->get() + : CATCH_NULL; + } + virtual ITracker& parent() CATCH_OVERRIDE { + assert( m_parent ); // Should always be non-null except for root + return *m_parent; + } + + virtual void openChild() CATCH_OVERRIDE { + if( m_runState != ExecutingChildren ) { + m_runState = ExecutingChildren; + if( m_parent ) + m_parent->openChild(); + } + } + + virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; } + virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; } + + void open() { + m_runState = Executing; + moveToThis(); + if( m_parent ) + m_parent->openChild(); + } + + virtual void close() CATCH_OVERRIDE { + + // Close any still open children (e.g. generators) + while( &m_ctx.currentTracker() != this ) + m_ctx.currentTracker().close(); + + switch( m_runState ) { + case NotStarted: + case CompletedSuccessfully: + case Failed: + throw std::logic_error( "Illogical state" ); + + case NeedsAnotherRun: + break;; + + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if( m_children.empty() || m_children.back()->isComplete() ) + m_runState = CompletedSuccessfully; + break; + + default: + throw std::logic_error( "Unexpected state" ); + } + moveToParent(); + m_ctx.completeCycle(); + } + virtual void fail() CATCH_OVERRIDE { + m_runState = Failed; + if( m_parent ) + m_parent->markAsNeedingAnotherRun(); + moveToParent(); + m_ctx.completeCycle(); + } + virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { + m_runState = NeedsAnotherRun; + } + private: + void moveToParent() { + assert( m_parent ); + m_ctx.setCurrentTracker( m_parent ); + } + void moveToThis() { + m_ctx.setCurrentTracker( this ); + } + }; + + class SectionTracker : public TrackerBase { + std::vector m_filters; + public: + SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( nameAndLocation, ctx, parent ) + { + if( parent ) { + while( !parent->isSectionTracker() ) + parent = &parent->parent(); + + SectionTracker& parentSection = static_cast( *parent ); + addNextFilters( parentSection.m_filters ); + } + } + virtual ~SectionTracker(); + + virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; } + + static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { + SectionTracker* section = CATCH_NULL; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isSectionTracker() ); + section = static_cast( childTracker ); + } + else { + section = new SectionTracker( nameAndLocation, ctx, ¤tTracker ); + currentTracker.addChild( section ); + } + if( !ctx.completedCycle() ) + section->tryOpen(); + return *section; + } + + void tryOpen() { + if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) ) + open(); + } + + void addInitialFilters( std::vector const& filters ) { + if( !filters.empty() ) { + m_filters.push_back(""); // Root - should never be consulted + m_filters.push_back(""); // Test Case - not a section filter + std::copy( filters.begin(), filters.end(), std::back_inserter( m_filters ) ); + } + } + void addNextFilters( std::vector const& filters ) { + if( filters.size() > 1 ) + std::copy( filters.begin()+1, filters.end(), std::back_inserter( m_filters ) ); + } + }; + + class IndexTracker : public TrackerBase { + int m_size; + int m_index; + public: + IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ) + : TrackerBase( nameAndLocation, ctx, parent ), + m_size( size ), + m_index( -1 ) + {} + virtual ~IndexTracker(); + + virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; } + + static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) { + IndexTracker* tracker = CATCH_NULL; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isIndexTracker() ); + tracker = static_cast( childTracker ); + } + else { + tracker = new IndexTracker( nameAndLocation, ctx, ¤tTracker, size ); + currentTracker.addChild( tracker ); + } + + if( !ctx.completedCycle() && !tracker->isComplete() ) { + if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) + tracker->moveNext(); + tracker->open(); + } + + return *tracker; + } + + int index() const { return m_index; } + + void moveNext() { + m_index++; + m_children.clear(); + } + + virtual void close() CATCH_OVERRIDE { + TrackerBase::close(); + if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) + m_runState = Executing; + } + }; + + inline ITracker& TrackerContext::startRun() { + m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL ); + m_currentTracker = CATCH_NULL; + m_runState = Executing; + return *m_rootTracker; + } + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +} // namespace Catch + +// #included from: catch_fatal_condition.hpp +#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED + +namespace Catch { + + // Report the error condition + inline void reportFatal( std::string const& message ) { + IContext& context = Catch::getCurrentContext(); + IResultCapture* resultCapture = context.getResultCapture(); + resultCapture->handleFatalErrorCondition( message ); + } + +} // namespace Catch + +#if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// +// #included from: catch_windows_h_proxy.h + +#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED + +#ifdef CATCH_DEFINES_NOMINMAX +# define NOMINMAX +#endif +#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#ifdef __AFXDLL +#include +#else +#include +#endif + +#ifdef CATCH_DEFINES_NOMINMAX +# undef NOMINMAX +#endif +#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN +# undef WIN32_LEAN_AND_MEAN +#endif + + +# if !defined ( CATCH_CONFIG_WINDOWS_SEH ) + +namespace Catch { + struct FatalConditionHandler { + void reset() {} + }; +} + +# else // CATCH_CONFIG_WINDOWS_SEH is defined + +namespace Catch { + + struct SignalDefs { DWORD id; const char* name; }; + extern SignalDefs signalDefs[]; + // There is no 1-1 mapping between signals and windows exceptions. + // Windows can easily distinguish between SO and SigSegV, + // but SigInt, SigTerm, etc are handled differently. + SignalDefs signalDefs[] = { + { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" }, + { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, + { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, + { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, + }; + + struct FatalConditionHandler { + + static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { + for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { + reset(); + reportFatal(signalDefs[i].name); + } + } + // If its not an exception we care about, pass it along. + // This stops us from eating debugger breaks etc. + return EXCEPTION_CONTINUE_SEARCH; + } + + FatalConditionHandler() { + isSet = true; + // 32k seems enough for Catch to handle stack overflow, + // but the value was found experimentally, so there is no strong guarantee + guaranteeSize = 32 * 1024; + exceptionHandlerHandle = CATCH_NULL; + // Register as first handler in current chain + exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); + // Pass in guarantee size to be filled + SetThreadStackGuarantee(&guaranteeSize); + } + + static void reset() { + if (isSet) { + // Unregister handler and restore the old guarantee + RemoveVectoredExceptionHandler(exceptionHandlerHandle); + SetThreadStackGuarantee(&guaranteeSize); + exceptionHandlerHandle = CATCH_NULL; + isSet = false; + } + } + + ~FatalConditionHandler() { + reset(); + } + private: + static bool isSet; + static ULONG guaranteeSize; + static PVOID exceptionHandlerHandle; + }; + + bool FatalConditionHandler::isSet = false; + ULONG FatalConditionHandler::guaranteeSize = 0; + PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL; + +} // namespace Catch + +# endif // CATCH_CONFIG_WINDOWS_SEH + +#else // Not Windows - assumed to be POSIX compatible ////////////////////////// + +# if !defined(CATCH_CONFIG_POSIX_SIGNALS) + +namespace Catch { + struct FatalConditionHandler { + void reset() {} + }; +} + +# else // CATCH_CONFIG_POSIX_SIGNALS is defined + +#include + +namespace Catch { + + struct SignalDefs { + int id; + const char* name; + }; + extern SignalDefs signalDefs[]; + SignalDefs signalDefs[] = { + { SIGINT, "SIGINT - Terminal interrupt signal" }, + { SIGILL, "SIGILL - Illegal instruction signal" }, + { SIGFPE, "SIGFPE - Floating point error signal" }, + { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, + { SIGTERM, "SIGTERM - Termination request signal" }, + { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } + }; + + struct FatalConditionHandler { + + static bool isSet; + static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)]; + static stack_t oldSigStack; + static char altStackMem[SIGSTKSZ]; + + static void handleSignal( int sig ) { + std::string name = ""; + for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + SignalDefs &def = signalDefs[i]; + if (sig == def.id) { + name = def.name; + break; + } + } + reset(); + reportFatal(name); + raise( sig ); + } + + FatalConditionHandler() { + isSet = true; + stack_t sigStack; + sigStack.ss_sp = altStackMem; + sigStack.ss_size = SIGSTKSZ; + sigStack.ss_flags = 0; + sigaltstack(&sigStack, &oldSigStack); + struct sigaction sa = { 0 }; + + sa.sa_handler = handleSignal; + sa.sa_flags = SA_ONSTACK; + for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); + } + } + + ~FatalConditionHandler() { + reset(); + } + static void reset() { + if( isSet ) { + // Set signals back to previous values -- hopefully nobody overwrote them in the meantime + for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { + sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL); + } + // Return the old stack + sigaltstack(&oldSigStack, CATCH_NULL); + isSet = false; + } + } + }; + + bool FatalConditionHandler::isSet = false; + struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; + stack_t FatalConditionHandler::oldSigStack = {}; + char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; + +} // namespace Catch + +# endif // CATCH_CONFIG_POSIX_SIGNALS + +#endif // not Windows + +#include +#include + +namespace Catch { + + class StreamRedirect { + + public: + StreamRedirect( std::ostream& stream, std::string& targetString ) + : m_stream( stream ), + m_prevBuf( stream.rdbuf() ), + m_targetString( targetString ) + { + stream.rdbuf( m_oss.rdbuf() ); + } + + ~StreamRedirect() { + m_targetString += m_oss.str(); + m_stream.rdbuf( m_prevBuf ); + } + + private: + std::ostream& m_stream; + std::streambuf* m_prevBuf; + std::ostringstream m_oss; + std::string& m_targetString; + }; + + /////////////////////////////////////////////////////////////////////////// + + class RunContext : public IResultCapture, public IRunner { + + RunContext( RunContext const& ); + void operator =( RunContext const& ); + + public: + + explicit RunContext( Ptr const& _config, Ptr const& reporter ) + : m_runInfo( _config->name() ), + m_context( getCurrentMutableContext() ), + m_activeTestCase( CATCH_NULL ), + m_config( _config ), + m_reporter( reporter ) + { + m_context.setRunner( this ); + m_context.setConfig( m_config ); + m_context.setResultCapture( this ); + m_reporter->testRunStarting( m_runInfo ); + } + + virtual ~RunContext() { + m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); + } + + void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { + m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) ); + } + void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) { + m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); + } + + Totals runTest( TestCase const& testCase ) { + Totals prevTotals = m_totals; + + std::string redirectedCout; + std::string redirectedCerr; + + TestCaseInfo testInfo = testCase.getTestCaseInfo(); + + m_reporter->testCaseStarting( testInfo ); + + m_activeTestCase = &testCase; + + do { + ITracker& rootTracker = m_trackerContext.startRun(); + assert( rootTracker.isSectionTracker() ); + static_cast( rootTracker ).addInitialFilters( m_config->getSectionsToRun() ); + do { + m_trackerContext.startCycle(); + m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) ); + runCurrentTest( redirectedCout, redirectedCerr ); + } + while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); + } + // !TBD: deprecated - this will be replaced by indexed trackers + while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); + + Totals deltaTotals = m_totals.delta( prevTotals ); + if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) { + deltaTotals.assertions.failed++; + deltaTotals.testCases.passed--; + deltaTotals.testCases.failed++; + } + m_totals.testCases += deltaTotals.testCases; + m_reporter->testCaseEnded( TestCaseStats( testInfo, + deltaTotals, + redirectedCout, + redirectedCerr, + aborting() ) ); + + m_activeTestCase = CATCH_NULL; + m_testCaseTracker = CATCH_NULL; + + return deltaTotals; + } + + Ptr config() const { + return m_config; + } + + private: // IResultCapture + + virtual void assertionEnded( AssertionResult const& result ) { + if( result.getResultType() == ResultWas::Ok ) { + m_totals.assertions.passed++; + } + else if( !result.isOk() ) { + m_totals.assertions.failed++; + } + + if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) ) + m_messages.clear(); + + // Reset working state + m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); + m_lastResult = result; + } + + virtual bool sectionStarted ( + SectionInfo const& sectionInfo, + Counts& assertions + ) + { + ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) ); + if( !sectionTracker.isOpen() ) + return false; + m_activeSections.push_back( §ionTracker ); + + m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; + + m_reporter->sectionStarting( sectionInfo ); + + assertions = m_totals.assertions; + + return true; + } + bool testForMissingAssertions( Counts& assertions ) { + if( assertions.total() != 0 ) + return false; + if( !m_config->warnAboutMissingAssertions() ) + return false; + if( m_trackerContext.currentTracker().hasChildren() ) + return false; + m_totals.assertions.failed++; + assertions.failed++; + return true; + } + + virtual void sectionEnded( SectionEndInfo const& endInfo ) { + Counts assertions = m_totals.assertions - endInfo.prevAssertions; + bool missingAssertions = testForMissingAssertions( assertions ); + + if( !m_activeSections.empty() ) { + m_activeSections.back()->close(); + m_activeSections.pop_back(); + } + + m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) ); + m_messages.clear(); + } + + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) { + if( m_unfinishedSections.empty() ) + m_activeSections.back()->fail(); + else + m_activeSections.back()->close(); + m_activeSections.pop_back(); + + m_unfinishedSections.push_back( endInfo ); + } + + virtual void pushScopedMessage( MessageInfo const& message ) { + m_messages.push_back( message ); + } + + virtual void popScopedMessage( MessageInfo const& message ) { + m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() ); + } + + virtual std::string getCurrentTestName() const { + return m_activeTestCase + ? m_activeTestCase->getTestCaseInfo().name + : std::string(); + } + + virtual const AssertionResult* getLastResult() const { + return &m_lastResult; + } + + virtual void handleFatalErrorCondition( std::string const& message ) { + ResultBuilder resultBuilder = makeUnexpectedResultBuilder(); + resultBuilder.setResultType( ResultWas::FatalErrorCondition ); + resultBuilder << message; + resultBuilder.captureExpression(); + + handleUnfinishedSections(); + + // Recreate section for test case (as we will lose the one that was in scope) + TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); + + Counts assertions; + assertions.failed = 1; + SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); + m_reporter->sectionEnded( testCaseSectionStats ); + + TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); + + Totals deltaTotals; + deltaTotals.testCases.failed = 1; + m_reporter->testCaseEnded( TestCaseStats( testInfo, + deltaTotals, + std::string(), + std::string(), + false ) ); + m_totals.testCases.failed++; + testGroupEnded( std::string(), m_totals, 1, 1 ); + m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); + } + + public: + // !TBD We need to do this another way! + bool aborting() const { + return m_totals.assertions.failed == static_cast( m_config->abortAfter() ); + } + + private: + + void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { + TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); + m_reporter->sectionStarting( testCaseSection ); + Counts prevAssertions = m_totals.assertions; + double duration = 0; + try { + m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, std::string(), ResultDisposition::Normal ); + + seedRng( *m_config ); + + Timer timer; + timer.start(); + if( m_reporter->getPreferences().shouldRedirectStdOut ) { + StreamRedirect coutRedir( Catch::cout(), redirectedCout ); + StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr ); + invokeActiveTestCase(); + } + else { + invokeActiveTestCase(); + } + duration = timer.getElapsedSeconds(); + } + catch( TestFailureException& ) { + // This just means the test was aborted due to failure + } + catch(...) { + makeUnexpectedResultBuilder().useActiveException(); + } + m_testCaseTracker->close(); + handleUnfinishedSections(); + m_messages.clear(); + + Counts assertions = m_totals.assertions - prevAssertions; + bool missingAssertions = testForMissingAssertions( assertions ); + + if( testCaseInfo.okToFail() ) { + std::swap( assertions.failedButOk, assertions.failed ); + m_totals.assertions.failed -= assertions.failedButOk; + m_totals.assertions.failedButOk += assertions.failedButOk; + } + + SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions ); + m_reporter->sectionEnded( testCaseSectionStats ); + } + + void invokeActiveTestCase() { + FatalConditionHandler fatalConditionHandler; // Handle signals + m_activeTestCase->invoke(); + fatalConditionHandler.reset(); + } + + private: + + ResultBuilder makeUnexpectedResultBuilder() const { + return ResultBuilder( m_lastAssertionInfo.macroName.c_str(), + m_lastAssertionInfo.lineInfo, + m_lastAssertionInfo.capturedExpression.c_str(), + m_lastAssertionInfo.resultDisposition ); + } + + void handleUnfinishedSections() { + // If sections ended prematurely due to an exception we stored their + // infos here so we can tear them down outside the unwind process. + for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), + itEnd = m_unfinishedSections.rend(); + it != itEnd; + ++it ) + sectionEnded( *it ); + m_unfinishedSections.clear(); + } + + TestRunInfo m_runInfo; + IMutableContext& m_context; + TestCase const* m_activeTestCase; + ITracker* m_testCaseTracker; + ITracker* m_currentSectionTracker; + AssertionResult m_lastResult; + + Ptr m_config; + Totals m_totals; + Ptr m_reporter; + std::vector m_messages; + AssertionInfo m_lastAssertionInfo; + std::vector m_unfinishedSections; + std::vector m_activeSections; + TrackerContext m_trackerContext; + }; + + IResultCapture& getResultCapture() { + if( IResultCapture* capture = getCurrentContext().getResultCapture() ) + return *capture; + else + throw std::logic_error( "No result capture instance" ); + } + +} // end namespace Catch + +// #included from: internal/catch_version.h +#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED + +namespace Catch { + + // Versioning information + struct Version { + Version( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + std::string const& _branchName, + unsigned int _buildNumber ); + + unsigned int const majorVersion; + unsigned int const minorVersion; + unsigned int const patchNumber; + + // buildNumber is only used if branchName is not null + std::string const branchName; + unsigned int const buildNumber; + + friend std::ostream& operator << ( std::ostream& os, Version const& version ); + + private: + void operator=( Version const& ); + }; + + extern Version libraryVersion; +} + +#include +#include +#include + +namespace Catch { + + Ptr createReporter( std::string const& reporterName, Ptr const& config ) { + Ptr reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() ); + if( !reporter ) { + std::ostringstream oss; + oss << "No reporter registered with name: '" << reporterName << "'"; + throw std::domain_error( oss.str() ); + } + return reporter; + } + + Ptr makeReporter( Ptr const& config ) { + std::vector reporters = config->getReporterNames(); + if( reporters.empty() ) + reporters.push_back( "console" ); + + Ptr reporter; + for( std::vector::const_iterator it = reporters.begin(), itEnd = reporters.end(); + it != itEnd; + ++it ) + reporter = addReporter( reporter, createReporter( *it, config ) ); + return reporter; + } + Ptr addListeners( Ptr const& config, Ptr reporters ) { + IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners(); + for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end(); + it != itEnd; + ++it ) + reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) ); + return reporters; + } + + Totals runTests( Ptr const& config ) { + + Ptr iconfig = config.get(); + + Ptr reporter = makeReporter( config ); + reporter = addListeners( iconfig, reporter ); + + RunContext context( iconfig, reporter ); + + Totals totals; + + context.testGroupStarting( config->name(), 1, 1 ); + + TestSpec testSpec = config->testSpec(); + if( !testSpec.hasFilters() ) + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests + + std::vector const& allTestCases = getAllTestCasesSorted( *iconfig ); + for( std::vector::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end(); + it != itEnd; + ++it ) { + if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) ) + totals += context.runTest( *it ); + else + reporter->skipTest( *it ); + } + + context.testGroupEnded( iconfig->name(), totals, 1, 1 ); + return totals; + } + + void applyFilenamesAsTags( IConfig const& config ) { + std::vector const& tests = getAllTestCasesSorted( config ); + for(std::size_t i = 0; i < tests.size(); ++i ) { + TestCase& test = const_cast( tests[i] ); + std::set tags = test.tags; + + std::string filename = test.lineInfo.file; + std::string::size_type lastSlash = filename.find_last_of( "\\/" ); + if( lastSlash != std::string::npos ) + filename = filename.substr( lastSlash+1 ); + + std::string::size_type lastDot = filename.find_last_of( "." ); + if( lastDot != std::string::npos ) + filename = filename.substr( 0, lastDot ); + + tags.insert( "#" + filename ); + setTags( test, tags ); + } + } + + class Session : NonCopyable { + static bool alreadyInstantiated; + + public: + + struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; + + Session() + : m_cli( makeCommandLineParser() ) { + if( alreadyInstantiated ) { + std::string msg = "Only one instance of Catch::Session can ever be used"; + Catch::cerr() << msg << std::endl; + throw std::logic_error( msg ); + } + alreadyInstantiated = true; + } + ~Session() { + Catch::cleanUp(); + } + + void showHelp( std::string const& processName ) { + Catch::cout() << "\nCatch v" << libraryVersion << "\n"; + + m_cli.usage( Catch::cout(), processName ); + Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; + } + + int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { + try { + m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); + m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData ); + if( m_configData.showHelp ) + showHelp( m_configData.processName ); + m_config.reset(); + } + catch( std::exception& ex ) { + { + Colour colourGuard( Colour::Red ); + Catch::cerr() + << "\nError(s) in input:\n" + << Text( ex.what(), TextAttributes().setIndent(2) ) + << "\n\n"; + } + m_cli.usage( Catch::cout(), m_configData.processName ); + return (std::numeric_limits::max)(); + } + return 0; + } + + void useConfigData( ConfigData const& _configData ) { + m_configData = _configData; + m_config.reset(); + } + + int run( int argc, char const* const* const argv ) { + + int returnCode = applyCommandLine( argc, argv ); + if( returnCode == 0 ) + returnCode = run(); + return returnCode; + } + + int run() { + if( m_configData.showHelp ) + return 0; + + try + { + config(); // Force config to be constructed + + seedRng( *m_config ); + + if( m_configData.filenamesAsTags ) + applyFilenamesAsTags( *m_config ); + + // Handle list request + if( Option listed = list( config() ) ) + return static_cast( *listed ); + + return static_cast( runTests( m_config ).assertions.failed ); + } + catch( std::exception& ex ) { + Catch::cerr() << ex.what() << std::endl; + return (std::numeric_limits::max)(); + } + } + + Clara::CommandLine const& cli() const { + return m_cli; + } + std::vector const& unusedTokens() const { + return m_unusedTokens; + } + ConfigData& configData() { + return m_configData; + } + Config& config() { + if( !m_config ) + m_config = new Config( m_configData ); + return *m_config; + } + private: + Clara::CommandLine m_cli; + std::vector m_unusedTokens; + ConfigData m_configData; + Ptr m_config; + }; + + bool Session::alreadyInstantiated = false; + +} // end namespace Catch + +// #included from: catch_registry_hub.hpp +#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED + +// #included from: catch_test_case_registry_impl.hpp +#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED + +#include +#include +#include +#include + +namespace Catch { + + struct RandomNumberGenerator { + typedef std::ptrdiff_t result_type; + + result_type operator()( result_type n ) const { return std::rand() % n; } + +#ifdef CATCH_CONFIG_CPP11_SHUFFLE + static constexpr result_type min() { return 0; } + static constexpr result_type max() { return 1000000; } + result_type operator()() const { return std::rand() % max(); } +#endif + template + static void shuffle( V& vector ) { + RandomNumberGenerator rng; +#ifdef CATCH_CONFIG_CPP11_SHUFFLE + std::shuffle( vector.begin(), vector.end(), rng ); +#else + std::random_shuffle( vector.begin(), vector.end(), rng ); +#endif + } + }; + + inline std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) { + + std::vector sorted = unsortedTestCases; + + switch( config.runOrder() ) { + case RunTests::InLexicographicalOrder: + std::sort( sorted.begin(), sorted.end() ); + break; + case RunTests::InRandomOrder: + { + seedRng( config ); + RandomNumberGenerator::shuffle( sorted ); + } + break; + case RunTests::InDeclarationOrder: + // already in declaration order + break; + } + return sorted; + } + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { + return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); + } + + void enforceNoDuplicateTestCases( std::vector const& functions ) { + std::set seenFunctions; + for( std::vector::const_iterator it = functions.begin(), itEnd = functions.end(); + it != itEnd; + ++it ) { + std::pair::const_iterator, bool> prev = seenFunctions.insert( *it ); + if( !prev.second ) { + std::ostringstream ss; + + ss << Colour( Colour::Red ) + << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n" + << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n' + << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl; + + throw std::runtime_error(ss.str()); + } + } + } + + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) { + std::vector filtered; + filtered.reserve( testCases.size() ); + for( std::vector::const_iterator it = testCases.begin(), itEnd = testCases.end(); + it != itEnd; + ++it ) + if( matchTest( *it, testSpec, config ) ) + filtered.push_back( *it ); + return filtered; + } + std::vector const& getAllTestCasesSorted( IConfig const& config ) { + return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); + } + + class TestRegistry : public ITestCaseRegistry { + public: + TestRegistry() + : m_currentSortOrder( RunTests::InDeclarationOrder ), + m_unnamedCount( 0 ) + {} + virtual ~TestRegistry(); + + virtual void registerTest( TestCase const& testCase ) { + std::string name = testCase.getTestCaseInfo().name; + if( name.empty() ) { + std::ostringstream oss; + oss << "Anonymous test case " << ++m_unnamedCount; + return registerTest( testCase.withName( oss.str() ) ); + } + m_functions.push_back( testCase ); + } + + virtual std::vector const& getAllTests() const { + return m_functions; + } + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const { + if( m_sortedFunctions.empty() ) + enforceNoDuplicateTestCases( m_functions ); + + if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { + m_sortedFunctions = sortTests( config, m_functions ); + m_currentSortOrder = config.runOrder(); + } + return m_sortedFunctions; + } + + private: + std::vector m_functions; + mutable RunTests::InWhatOrder m_currentSortOrder; + mutable std::vector m_sortedFunctions; + size_t m_unnamedCount; + std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised + }; + + /////////////////////////////////////////////////////////////////////////// + + class FreeFunctionTestCase : public SharedImpl { + public: + + FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} + + virtual void invoke() const { + m_fun(); + } + + private: + virtual ~FreeFunctionTestCase(); + + TestFunction m_fun; + }; + + inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { + std::string className = classOrQualifiedMethodName; + if( startsWith( className, '&' ) ) + { + std::size_t lastColons = className.rfind( "::" ); + std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); + if( penultimateColons == std::string::npos ) + penultimateColons = 1; + className = className.substr( penultimateColons, lastColons-penultimateColons ); + } + return className; + } + + void registerTestCase + ( ITestCase* testCase, + char const* classOrQualifiedMethodName, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ) { + + getMutableRegistryHub().registerTest + ( makeTestCase + ( testCase, + extractClassName( classOrQualifiedMethodName ), + nameAndDesc.name, + nameAndDesc.description, + lineInfo ) ); + } + void registerTestCaseFunction + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ) { + registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); + } + + /////////////////////////////////////////////////////////////////////////// + + AutoReg::AutoReg + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ) { + registerTestCaseFunction( function, lineInfo, nameAndDesc ); + } + + AutoReg::~AutoReg() {} + +} // end namespace Catch + +// #included from: catch_reporter_registry.hpp +#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED + +#include + +namespace Catch { + + class ReporterRegistry : public IReporterRegistry { + + public: + + virtual ~ReporterRegistry() CATCH_OVERRIDE {} + + virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const CATCH_OVERRIDE { + FactoryMap::const_iterator it = m_factories.find( name ); + if( it == m_factories.end() ) + return CATCH_NULL; + return it->second->create( ReporterConfig( config ) ); + } + + void registerReporter( std::string const& name, Ptr const& factory ) { + m_factories.insert( std::make_pair( name, factory ) ); + } + void registerListener( Ptr const& factory ) { + m_listeners.push_back( factory ); + } + + virtual FactoryMap const& getFactories() const CATCH_OVERRIDE { + return m_factories; + } + virtual Listeners const& getListeners() const CATCH_OVERRIDE { + return m_listeners; + } + + private: + FactoryMap m_factories; + Listeners m_listeners; + }; +} + +// #included from: catch_exception_translator_registry.hpp +#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED + +#ifdef __OBJC__ +#import "Foundation/Foundation.h" +#endif + +namespace Catch { + + class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { + public: + ~ExceptionTranslatorRegistry() { + deleteAll( m_translators ); + } + + virtual void registerTranslator( const IExceptionTranslator* translator ) { + m_translators.push_back( translator ); + } + + virtual std::string translateActiveException() const { + try { +#ifdef __OBJC__ + // In Objective-C try objective-c exceptions first + @try { + return tryTranslators(); + } + @catch (NSException *exception) { + return Catch::toString( [exception description] ); + } +#else + return tryTranslators(); +#endif + } + catch( TestFailureException& ) { + throw; + } + catch( std::exception& ex ) { + return ex.what(); + } + catch( std::string& msg ) { + return msg; + } + catch( const char* msg ) { + return msg; + } + catch(...) { + return "Unknown exception"; + } + } + + std::string tryTranslators() const { + if( m_translators.empty() ) + throw; + else + return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); + } + + private: + std::vector m_translators; + }; +} + +namespace Catch { + + namespace { + + class RegistryHub : public IRegistryHub, public IMutableRegistryHub { + + RegistryHub( RegistryHub const& ); + void operator=( RegistryHub const& ); + + public: // IRegistryHub + RegistryHub() { + } + virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE { + return m_reporterRegistry; + } + virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE { + return m_testCaseRegistry; + } + virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE { + return m_exceptionTranslatorRegistry; + } + + public: // IMutableRegistryHub + virtual void registerReporter( std::string const& name, Ptr const& factory ) CATCH_OVERRIDE { + m_reporterRegistry.registerReporter( name, factory ); + } + virtual void registerListener( Ptr const& factory ) CATCH_OVERRIDE { + m_reporterRegistry.registerListener( factory ); + } + virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE { + m_testCaseRegistry.registerTest( testInfo ); + } + virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE { + m_exceptionTranslatorRegistry.registerTranslator( translator ); + } + + private: + TestRegistry m_testCaseRegistry; + ReporterRegistry m_reporterRegistry; + ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; + }; + + // Single, global, instance + inline RegistryHub*& getTheRegistryHub() { + static RegistryHub* theRegistryHub = CATCH_NULL; + if( !theRegistryHub ) + theRegistryHub = new RegistryHub(); + return theRegistryHub; + } + } + + IRegistryHub& getRegistryHub() { + return *getTheRegistryHub(); + } + IMutableRegistryHub& getMutableRegistryHub() { + return *getTheRegistryHub(); + } + void cleanUp() { + delete getTheRegistryHub(); + getTheRegistryHub() = CATCH_NULL; + cleanUpContext(); + } + std::string translateActiveException() { + return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); + } + +} // end namespace Catch + +// #included from: catch_notimplemented_exception.hpp +#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED + +#include + +namespace Catch { + + NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) + : m_lineInfo( lineInfo ) { + std::ostringstream oss; + oss << lineInfo << ": function "; + oss << "not implemented"; + m_what = oss.str(); + } + + const char* NotImplementedException::what() const CATCH_NOEXCEPT { + return m_what.c_str(); + } + +} // end namespace Catch + +// #included from: catch_context_impl.hpp +#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED + +// #included from: catch_stream.hpp +#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED + +#include +#include +#include + +namespace Catch { + + template + class StreamBufImpl : public StreamBufBase { + char data[bufferSize]; + WriterF m_writer; + + public: + StreamBufImpl() { + setp( data, data + sizeof(data) ); + } + + ~StreamBufImpl() CATCH_NOEXCEPT { + sync(); + } + + private: + int overflow( int c ) { + sync(); + + if( c != EOF ) { + if( pbase() == epptr() ) + m_writer( std::string( 1, static_cast( c ) ) ); + else + sputc( static_cast( c ) ); + } + return 0; + } + + int sync() { + if( pbase() != pptr() ) { + m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) ); + setp( pbase(), epptr() ); + } + return 0; + } + }; + + /////////////////////////////////////////////////////////////////////////// + + FileStream::FileStream( std::string const& filename ) { + m_ofs.open( filename.c_str() ); + if( m_ofs.fail() ) { + std::ostringstream oss; + oss << "Unable to open file: '" << filename << '\''; + throw std::domain_error( oss.str() ); + } + } + + std::ostream& FileStream::stream() const { + return m_ofs; + } + + struct OutputDebugWriter { + + void operator()( std::string const&str ) { + writeToDebugConsole( str ); + } + }; + + DebugOutStream::DebugOutStream() + : m_streamBuf( new StreamBufImpl() ), + m_os( m_streamBuf.get() ) + {} + + std::ostream& DebugOutStream::stream() const { + return m_os; + } + + // Store the streambuf from cout up-front because + // cout may get redirected when running tests + CoutStream::CoutStream() + : m_os( Catch::cout().rdbuf() ) + {} + + std::ostream& CoutStream::stream() const { + return m_os; + } + +#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions + std::ostream& cout() { + return std::cout; + } + std::ostream& cerr() { + return std::cerr; + } +#endif +} + +namespace Catch { + + class Context : public IMutableContext { + + Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {} + Context( Context const& ); + void operator=( Context const& ); + + public: + virtual ~Context() { + deleteAllValues( m_generatorsByTestName ); + } + + public: // IContext + virtual IResultCapture* getResultCapture() { + return m_resultCapture; + } + virtual IRunner* getRunner() { + return m_runner; + } + virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { + return getGeneratorsForCurrentTest() + .getGeneratorInfo( fileInfo, totalSize ) + .getCurrentIndex(); + } + virtual bool advanceGeneratorsForCurrentTest() { + IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); + return generators && generators->moveNext(); + } + + virtual Ptr getConfig() const { + return m_config; + } + + public: // IMutableContext + virtual void setResultCapture( IResultCapture* resultCapture ) { + m_resultCapture = resultCapture; + } + virtual void setRunner( IRunner* runner ) { + m_runner = runner; + } + virtual void setConfig( Ptr const& config ) { + m_config = config; + } + + friend IMutableContext& getCurrentMutableContext(); + + private: + IGeneratorsForTest* findGeneratorsForCurrentTest() { + std::string testName = getResultCapture()->getCurrentTestName(); + + std::map::const_iterator it = + m_generatorsByTestName.find( testName ); + return it != m_generatorsByTestName.end() + ? it->second + : CATCH_NULL; + } + + IGeneratorsForTest& getGeneratorsForCurrentTest() { + IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); + if( !generators ) { + std::string testName = getResultCapture()->getCurrentTestName(); + generators = createGeneratorsForTest(); + m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); + } + return *generators; + } + + private: + Ptr m_config; + IRunner* m_runner; + IResultCapture* m_resultCapture; + std::map m_generatorsByTestName; + }; + + namespace { + Context* currentContext = CATCH_NULL; + } + IMutableContext& getCurrentMutableContext() { + if( !currentContext ) + currentContext = new Context(); + return *currentContext; + } + IContext& getCurrentContext() { + return getCurrentMutableContext(); + } + + void cleanUpContext() { + delete currentContext; + currentContext = CATCH_NULL; + } +} + +// #included from: catch_console_colour_impl.hpp +#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED + +namespace Catch { + namespace { + + struct IColourImpl { + virtual ~IColourImpl() {} + virtual void use( Colour::Code _colourCode ) = 0; + }; + + struct NoColourImpl : IColourImpl { + void use( Colour::Code ) {} + + static IColourImpl* instance() { + static NoColourImpl s_instance; + return &s_instance; + } + }; + + } // anon namespace +} // namespace Catch + +#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) +# ifdef CATCH_PLATFORM_WINDOWS +# define CATCH_CONFIG_COLOUR_WINDOWS +# else +# define CATCH_CONFIG_COLOUR_ANSI +# endif +#endif + +#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// + +namespace Catch { +namespace { + + class Win32ColourImpl : public IColourImpl { + public: + Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) + { + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); + originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); + originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); + } + + virtual void use( Colour::Code _colourCode ) { + switch( _colourCode ) { + case Colour::None: return setTextAttribute( originalForegroundAttributes ); + case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + case Colour::Red: return setTextAttribute( FOREGROUND_RED ); + case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); + case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); + case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); + case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); + case Colour::Grey: return setTextAttribute( 0 ); + + case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); + case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); + case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); + case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + + case Colour::Bright: throw std::logic_error( "not a colour" ); + } + } + + private: + void setTextAttribute( WORD _textAttribute ) { + SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); + } + HANDLE stdoutHandle; + WORD originalForegroundAttributes; + WORD originalBackgroundAttributes; + }; + + IColourImpl* platformColourInstance() { + static Win32ColourImpl s_instance; + + Ptr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = !isDebuggerActive() + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? &s_instance + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// + +#include + +namespace Catch { +namespace { + + // use POSIX/ ANSI console terminal codes + // Thanks to Adam Strzelecki for original contribution + // (http://github.com/nanoant) + // https://github.com/philsquared/Catch/pull/131 + class PosixColourImpl : public IColourImpl { + public: + virtual void use( Colour::Code _colourCode ) { + switch( _colourCode ) { + case Colour::None: + case Colour::White: return setColour( "[0m" ); + case Colour::Red: return setColour( "[0;31m" ); + case Colour::Green: return setColour( "[0;32m" ); + case Colour::Blue: return setColour( "[0;34m" ); + case Colour::Cyan: return setColour( "[0;36m" ); + case Colour::Yellow: return setColour( "[0;33m" ); + case Colour::Grey: return setColour( "[1;30m" ); + + case Colour::LightGrey: return setColour( "[0;37m" ); + case Colour::BrightRed: return setColour( "[1;31m" ); + case Colour::BrightGreen: return setColour( "[1;32m" ); + case Colour::BrightWhite: return setColour( "[1;37m" ); + + case Colour::Bright: throw std::logic_error( "not a colour" ); + } + } + static IColourImpl* instance() { + static PosixColourImpl s_instance; + return &s_instance; + } + + private: + void setColour( const char* _escapeCode ) { + Catch::cout() << '\033' << _escapeCode; + } + }; + + IColourImpl* platformColourInstance() { + Ptr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) ) + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? PosixColourImpl::instance() + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#else // not Windows or ANSI /////////////////////////////////////////////// + +namespace Catch { + + static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } + +} // end namespace Catch + +#endif // Windows/ ANSI/ None + +namespace Catch { + + Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } + Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast( _other ).m_moved = true; } + Colour::~Colour(){ if( !m_moved ) use( None ); } + + void Colour::use( Code _colourCode ) { + static IColourImpl* impl = platformColourInstance(); + impl->use( _colourCode ); + } + +} // end namespace Catch + +// #included from: catch_generators_impl.hpp +#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED + +#include +#include +#include + +namespace Catch { + + struct GeneratorInfo : IGeneratorInfo { + + GeneratorInfo( std::size_t size ) + : m_size( size ), + m_currentIndex( 0 ) + {} + + bool moveNext() { + if( ++m_currentIndex == m_size ) { + m_currentIndex = 0; + return false; + } + return true; + } + + std::size_t getCurrentIndex() const { + return m_currentIndex; + } + + std::size_t m_size; + std::size_t m_currentIndex; + }; + + /////////////////////////////////////////////////////////////////////////// + + class GeneratorsForTest : public IGeneratorsForTest { + + public: + ~GeneratorsForTest() { + deleteAll( m_generatorsInOrder ); + } + + IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { + std::map::const_iterator it = m_generatorsByName.find( fileInfo ); + if( it == m_generatorsByName.end() ) { + IGeneratorInfo* info = new GeneratorInfo( size ); + m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); + m_generatorsInOrder.push_back( info ); + return *info; + } + return *it->second; + } + + bool moveNext() { + std::vector::const_iterator it = m_generatorsInOrder.begin(); + std::vector::const_iterator itEnd = m_generatorsInOrder.end(); + for(; it != itEnd; ++it ) { + if( (*it)->moveNext() ) + return true; + } + return false; + } + + private: + std::map m_generatorsByName; + std::vector m_generatorsInOrder; + }; + + IGeneratorsForTest* createGeneratorsForTest() + { + return new GeneratorsForTest(); + } + +} // end namespace Catch + +// #included from: catch_assertionresult.hpp +#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED + +namespace Catch { + + AssertionInfo::AssertionInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + std::string const& _capturedExpression, + ResultDisposition::Flags _resultDisposition ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + capturedExpression( _capturedExpression ), + resultDisposition( _resultDisposition ) + {} + + AssertionResult::AssertionResult() {} + + AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) + : m_info( info ), + m_resultData( data ) + {} + + AssertionResult::~AssertionResult() {} + + // Result was a success + bool AssertionResult::succeeded() const { + return Catch::isOk( m_resultData.resultType ); + } + + // Result was a success, or failure is suppressed + bool AssertionResult::isOk() const { + return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); + } + + ResultWas::OfType AssertionResult::getResultType() const { + return m_resultData.resultType; + } + + bool AssertionResult::hasExpression() const { + return !m_info.capturedExpression.empty(); + } + + bool AssertionResult::hasMessage() const { + return !m_resultData.message.empty(); + } + + std::string AssertionResult::getExpression() const { + if( isFalseTest( m_info.resultDisposition ) ) + return '!' + m_info.capturedExpression; + else + return m_info.capturedExpression; + } + std::string AssertionResult::getExpressionInMacro() const { + if( m_info.macroName.empty() ) + return m_info.capturedExpression; + else + return m_info.macroName + "( " + m_info.capturedExpression + " )"; + } + + bool AssertionResult::hasExpandedExpression() const { + return hasExpression() && getExpandedExpression() != getExpression(); + } + + std::string AssertionResult::getExpandedExpression() const { + return m_resultData.reconstructExpression(); + } + + std::string AssertionResult::getMessage() const { + return m_resultData.message; + } + SourceLineInfo AssertionResult::getSourceInfo() const { + return m_info.lineInfo; + } + + std::string AssertionResult::getTestMacroName() const { + return m_info.macroName; + } + + void AssertionResult::discardDecomposedExpression() const { + m_resultData.decomposedExpression = CATCH_NULL; + } + + void AssertionResult::expandDecomposedExpression() const { + m_resultData.reconstructExpression(); + } + +} // end namespace Catch + +// #included from: catch_test_case_info.hpp +#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED + +#include + +namespace Catch { + + inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { + if( startsWith( tag, '.' ) || + tag == "hide" || + tag == "!hide" ) + return TestCaseInfo::IsHidden; + else if( tag == "!throws" ) + return TestCaseInfo::Throws; + else if( tag == "!shouldfail" ) + return TestCaseInfo::ShouldFail; + else if( tag == "!mayfail" ) + return TestCaseInfo::MayFail; + else if( tag == "!nonportable" ) + return TestCaseInfo::NonPortable; + else + return TestCaseInfo::None; + } + inline bool isReservedTag( std::string const& tag ) { + return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] ); + } + inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { + if( isReservedTag( tag ) ) { + { + Colour colourGuard( Colour::Red ); + Catch::cerr() + << "Tag name [" << tag << "] not allowed.\n" + << "Tag names starting with non alpha-numeric characters are reserved\n"; + } + { + Colour colourGuard( Colour::FileName ); + Catch::cerr() << _lineInfo << std::endl; + } + exit(1); + } + } + + TestCase makeTestCase( ITestCase* _testCase, + std::string const& _className, + std::string const& _name, + std::string const& _descOrTags, + SourceLineInfo const& _lineInfo ) + { + bool isHidden( startsWith( _name, "./" ) ); // Legacy support + + // Parse out tags + std::set tags; + std::string desc, tag; + bool inTag = false; + for( std::size_t i = 0; i < _descOrTags.size(); ++i ) { + char c = _descOrTags[i]; + if( !inTag ) { + if( c == '[' ) + inTag = true; + else + desc += c; + } + else { + if( c == ']' ) { + TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); + if( prop == TestCaseInfo::IsHidden ) + isHidden = true; + else if( prop == TestCaseInfo::None ) + enforceNotReservedTag( tag, _lineInfo ); + + tags.insert( tag ); + tag.clear(); + inTag = false; + } + else + tag += c; + } + } + if( isHidden ) { + tags.insert( "hide" ); + tags.insert( "." ); + } + + TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); + return TestCase( _testCase, info ); + } + + void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ) + { + testCaseInfo.tags = tags; + testCaseInfo.lcaseTags.clear(); + + std::ostringstream oss; + for( std::set::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) { + oss << '[' << *it << ']'; + std::string lcaseTag = toLower( *it ); + testCaseInfo.properties = static_cast( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); + testCaseInfo.lcaseTags.insert( lcaseTag ); + } + testCaseInfo.tagsAsString = oss.str(); + } + + TestCaseInfo::TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::set const& _tags, + SourceLineInfo const& _lineInfo ) + : name( _name ), + className( _className ), + description( _description ), + lineInfo( _lineInfo ), + properties( None ) + { + setTags( *this, _tags ); + } + + TestCaseInfo::TestCaseInfo( TestCaseInfo const& other ) + : name( other.name ), + className( other.className ), + description( other.description ), + tags( other.tags ), + lcaseTags( other.lcaseTags ), + tagsAsString( other.tagsAsString ), + lineInfo( other.lineInfo ), + properties( other.properties ) + {} + + bool TestCaseInfo::isHidden() const { + return ( properties & IsHidden ) != 0; + } + bool TestCaseInfo::throws() const { + return ( properties & Throws ) != 0; + } + bool TestCaseInfo::okToFail() const { + return ( properties & (ShouldFail | MayFail ) ) != 0; + } + bool TestCaseInfo::expectedToFail() const { + return ( properties & (ShouldFail ) ) != 0; + } + + TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} + + TestCase::TestCase( TestCase const& other ) + : TestCaseInfo( other ), + test( other.test ) + {} + + TestCase TestCase::withName( std::string const& _newName ) const { + TestCase other( *this ); + other.name = _newName; + return other; + } + + void TestCase::swap( TestCase& other ) { + test.swap( other.test ); + name.swap( other.name ); + className.swap( other.className ); + description.swap( other.description ); + tags.swap( other.tags ); + lcaseTags.swap( other.lcaseTags ); + tagsAsString.swap( other.tagsAsString ); + std::swap( TestCaseInfo::properties, static_cast( other ).properties ); + std::swap( lineInfo, other.lineInfo ); + } + + void TestCase::invoke() const { + test->invoke(); + } + + bool TestCase::operator == ( TestCase const& other ) const { + return test.get() == other.test.get() && + name == other.name && + className == other.className; + } + + bool TestCase::operator < ( TestCase const& other ) const { + return name < other.name; + } + TestCase& TestCase::operator = ( TestCase const& other ) { + TestCase temp( other ); + swap( temp ); + return *this; + } + + TestCaseInfo const& TestCase::getTestCaseInfo() const + { + return *this; + } + +} // end namespace Catch + +// #included from: catch_version.hpp +#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED + +namespace Catch { + + Version::Version + ( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + std::string const& _branchName, + unsigned int _buildNumber ) + : majorVersion( _majorVersion ), + minorVersion( _minorVersion ), + patchNumber( _patchNumber ), + branchName( _branchName ), + buildNumber( _buildNumber ) + {} + + std::ostream& operator << ( std::ostream& os, Version const& version ) { + os << version.majorVersion << '.' + << version.minorVersion << '.' + << version.patchNumber; + + if( !version.branchName.empty() ) { + os << '-' << version.branchName + << '.' << version.buildNumber; + } + return os; + } + + Version libraryVersion( 1, 8, 1, "", 0 ); + +} + +// #included from: catch_message.hpp +#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED + +namespace Catch { + + MessageInfo::MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + type( _type ), + sequence( ++globalCount ) + {} + + // This may need protecting if threading support is added + unsigned int MessageInfo::globalCount = 0; + + //////////////////////////////////////////////////////////////////////////// + + ScopedMessage::ScopedMessage( MessageBuilder const& builder ) + : m_info( builder.m_info ) + { + m_info.message = builder.m_stream.str(); + getResultCapture().pushScopedMessage( m_info ); + } + ScopedMessage::ScopedMessage( ScopedMessage const& other ) + : m_info( other.m_info ) + {} + + ScopedMessage::~ScopedMessage() { + getResultCapture().popScopedMessage( m_info ); + } + +} // end namespace Catch + +// #included from: catch_legacy_reporter_adapter.hpp +#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED + +// #included from: catch_legacy_reporter_adapter.h +#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED + +namespace Catch +{ + // Deprecated + struct IReporter : IShared { + virtual ~IReporter(); + + virtual bool shouldRedirectStdout() const = 0; + + virtual void StartTesting() = 0; + virtual void EndTesting( Totals const& totals ) = 0; + virtual void StartGroup( std::string const& groupName ) = 0; + virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; + virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; + virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; + virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; + virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; + virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; + virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; + virtual void Aborted() = 0; + virtual void Result( AssertionResult const& result ) = 0; + }; + + class LegacyReporterAdapter : public SharedImpl + { + public: + LegacyReporterAdapter( Ptr const& legacyReporter ); + virtual ~LegacyReporterAdapter(); + + virtual ReporterPreferences getPreferences() const; + virtual void noMatchingTestCases( std::string const& ); + virtual void testRunStarting( TestRunInfo const& ); + virtual void testGroupStarting( GroupInfo const& groupInfo ); + virtual void testCaseStarting( TestCaseInfo const& testInfo ); + virtual void sectionStarting( SectionInfo const& sectionInfo ); + virtual void assertionStarting( AssertionInfo const& ); + virtual bool assertionEnded( AssertionStats const& assertionStats ); + virtual void sectionEnded( SectionStats const& sectionStats ); + virtual void testCaseEnded( TestCaseStats const& testCaseStats ); + virtual void testGroupEnded( TestGroupStats const& testGroupStats ); + virtual void testRunEnded( TestRunStats const& testRunStats ); + virtual void skipTest( TestCaseInfo const& ); + + private: + Ptr m_legacyReporter; + }; +} + +namespace Catch +{ + LegacyReporterAdapter::LegacyReporterAdapter( Ptr const& legacyReporter ) + : m_legacyReporter( legacyReporter ) + {} + LegacyReporterAdapter::~LegacyReporterAdapter() {} + + ReporterPreferences LegacyReporterAdapter::getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); + return prefs; + } + + void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} + void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { + m_legacyReporter->StartTesting(); + } + void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { + m_legacyReporter->StartGroup( groupInfo.name ); + } + void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { + m_legacyReporter->StartTestCase( testInfo ); + } + void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { + m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); + } + void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { + // Not on legacy interface + } + + bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { + if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { + for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); + it != itEnd; + ++it ) { + if( it->type == ResultWas::Info ) { + ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); + rb << it->message; + rb.setResultType( ResultWas::Info ); + AssertionResult result = rb.build(); + m_legacyReporter->Result( result ); + } + } + } + m_legacyReporter->Result( assertionStats.assertionResult ); + return true; + } + void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { + if( sectionStats.missingAssertions ) + m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); + m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); + } + void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { + m_legacyReporter->EndTestCase + ( testCaseStats.testInfo, + testCaseStats.totals, + testCaseStats.stdOut, + testCaseStats.stdErr ); + } + void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { + if( testGroupStats.aborting ) + m_legacyReporter->Aborted(); + m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); + } + void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { + m_legacyReporter->EndTesting( testRunStats.totals ); + } + void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { + } +} + +// #included from: catch_timer.hpp + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++11-long-long" +#endif + +#ifdef CATCH_PLATFORM_WINDOWS + +#else + +#include + +#endif + +namespace Catch { + + namespace { +#ifdef CATCH_PLATFORM_WINDOWS + uint64_t getCurrentTicks() { + static uint64_t hz=0, hzo=0; + if (!hz) { + QueryPerformanceFrequency( reinterpret_cast( &hz ) ); + QueryPerformanceCounter( reinterpret_cast( &hzo ) ); + } + uint64_t t; + QueryPerformanceCounter( reinterpret_cast( &t ) ); + return ((t-hzo)*1000000)/hz; + } +#else + uint64_t getCurrentTicks() { + timeval t; + gettimeofday(&t,CATCH_NULL); + return static_cast( t.tv_sec ) * 1000000ull + static_cast( t.tv_usec ); + } +#endif + } + + void Timer::start() { + m_ticks = getCurrentTicks(); + } + unsigned int Timer::getElapsedMicroseconds() const { + return static_cast(getCurrentTicks() - m_ticks); + } + unsigned int Timer::getElapsedMilliseconds() const { + return static_cast(getElapsedMicroseconds()/1000); + } + double Timer::getElapsedSeconds() const { + return getElapsedMicroseconds()/1000000.0; + } + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +// #included from: catch_common.hpp +#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED + +#include +#include + +namespace Catch { + + bool startsWith( std::string const& s, std::string const& prefix ) { + return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); + } + bool startsWith( std::string const& s, char prefix ) { + return !s.empty() && s[0] == prefix; + } + bool endsWith( std::string const& s, std::string const& suffix ) { + return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); + } + bool endsWith( std::string const& s, char suffix ) { + return !s.empty() && s[s.size()-1] == suffix; + } + bool contains( std::string const& s, std::string const& infix ) { + return s.find( infix ) != std::string::npos; + } + char toLowerCh(char c) { + return static_cast( std::tolower( c ) ); + } + void toLowerInPlace( std::string& s ) { + std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); + } + std::string toLower( std::string const& s ) { + std::string lc = s; + toLowerInPlace( lc ); + return lc; + } + std::string trim( std::string const& str ) { + static char const* whitespaceChars = "\n\r\t "; + std::string::size_type start = str.find_first_not_of( whitespaceChars ); + std::string::size_type end = str.find_last_not_of( whitespaceChars ); + + return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); + } + + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { + bool replaced = false; + std::size_t i = str.find( replaceThis ); + while( i != std::string::npos ) { + replaced = true; + str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); + if( i < str.size()-withThis.size() ) + i = str.find( replaceThis, i+withThis.size() ); + else + i = std::string::npos; + } + return replaced; + } + + pluralise::pluralise( std::size_t count, std::string const& label ) + : m_count( count ), + m_label( label ) + {} + + std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { + os << pluraliser.m_count << ' ' << pluraliser.m_label; + if( pluraliser.m_count != 1 ) + os << 's'; + return os; + } + + SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){} + SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) + : file( _file ), + line( _line ) + {} + bool SourceLineInfo::empty() const { + return file[0] == '\0'; + } + bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const { + return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); + } + bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const { + return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0)); + } + + void seedRng( IConfig const& config ) { + if( config.rngSeed() != 0 ) + std::srand( config.rngSeed() ); + } + unsigned int rngSeed() { + return getCurrentContext().getConfig()->rngSeed(); + } + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { +#ifndef __GNUG__ + os << info.file << '(' << info.line << ')'; +#else + os << info.file << ':' << info.line; +#endif + return os; + } + + void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { + std::ostringstream oss; + oss << locationInfo << ": Internal Catch error: '" << message << '\''; + if( alwaysTrue() ) + throw std::logic_error( oss.str() ); + } +} + +// #included from: catch_section.hpp +#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED + +namespace Catch { + + SectionInfo::SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description ) + : name( _name ), + description( _description ), + lineInfo( _lineInfo ) + {} + + Section::Section( SectionInfo const& info ) + : m_info( info ), + m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) + { + m_timer.start(); + } + + Section::~Section() { + if( m_sectionIncluded ) { + SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); + if( std::uncaught_exception() ) + getResultCapture().sectionEndedEarly( endInfo ); + else + getResultCapture().sectionEnded( endInfo ); + } + } + + // This indicates whether the section should be executed or not + Section::operator bool() const { + return m_sectionIncluded; + } + +} // end namespace Catch + +// #included from: catch_debugger.hpp +#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED + +#ifdef CATCH_PLATFORM_MAC + + #include + #include + #include + #include + #include + + namespace Catch{ + + // The following function is taken directly from the following technical note: + // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html + + // Returns true if the current process is being debugged (either + // running under the debugger or has a debugger attached post facto). + bool isDebuggerActive(){ + + int mib[4]; + struct kinfo_proc info; + size_t size; + + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) { + Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; + return false; + } + + // We're being debugged if the P_TRACED flag is set. + + return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); + } + } // namespace Catch + +#elif defined(CATCH_PLATFORM_LINUX) + #include + #include + + namespace Catch{ + // The standard POSIX way of detecting a debugger is to attempt to + // ptrace() the process, but this needs to be done from a child and not + // this process itself to still allow attaching to this process later + // if wanted, so is rather heavy. Under Linux we have the PID of the + // "debugger" (which doesn't need to be gdb, of course, it could also + // be strace, for example) in /proc/$PID/status, so just get it from + // there instead. + bool isDebuggerActive(){ + std::ifstream in("/proc/self/status"); + for( std::string line; std::getline(in, line); ) { + static const int PREFIX_LEN = 11; + if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { + // We're traced if the PID is not 0 and no other PID starts + // with 0 digit, so it's enough to check for just a single + // character. + return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; + } + } + + return false; + } + } // namespace Catch +#elif defined(_MSC_VER) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#else + namespace Catch { + inline bool isDebuggerActive() { return false; } + } +#endif // Platform + +#ifdef CATCH_PLATFORM_WINDOWS + + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + ::OutputDebugStringA( text.c_str() ); + } + } +#else + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + // !TBD: Need a version for Mac/ XCode and other IDEs + Catch::cout() << text; + } + } +#endif // Platform + +// #included from: catch_tostring.hpp +#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED + +namespace Catch { + +namespace Detail { + + const std::string unprintableString = "{?}"; + + namespace { + const int hexThreshold = 255; + + struct Endianness { + enum Arch { Big, Little }; + + static Arch which() { + union _{ + int asInt; + char asChar[sizeof (int)]; + } u; + + u.asInt = 1; + return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; + } + }; + } + + std::string rawMemoryToString( const void *object, std::size_t size ) + { + // Reverse order for little endian architectures + int i = 0, end = static_cast( size ), inc = 1; + if( Endianness::which() == Endianness::Little ) { + i = end-1; + end = inc = -1; + } + + unsigned char const *bytes = static_cast(object); + std::ostringstream os; + os << "0x" << std::setfill('0') << std::hex; + for( ; i != end; i += inc ) + os << std::setw(2) << static_cast(bytes[i]); + return os.str(); + } +} + +std::string toString( std::string const& value ) { + std::string s = value; + if( getCurrentContext().getConfig()->showInvisibles() ) { + for(size_t i = 0; i < s.size(); ++i ) { + std::string subs; + switch( s[i] ) { + case '\n': subs = "\\n"; break; + case '\t': subs = "\\t"; break; + default: break; + } + if( !subs.empty() ) { + s = s.substr( 0, i ) + subs + s.substr( i+1 ); + ++i; + } + } + } + return '"' + s + '"'; +} +std::string toString( std::wstring const& value ) { + + std::string s; + s.reserve( value.size() ); + for(size_t i = 0; i < value.size(); ++i ) + s += value[i] <= 0xff ? static_cast( value[i] ) : '?'; + return Catch::toString( s ); +} + +std::string toString( const char* const value ) { + return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" ); +} + +std::string toString( char* const value ) { + return Catch::toString( static_cast( value ) ); +} + +std::string toString( const wchar_t* const value ) +{ + return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" ); +} + +std::string toString( wchar_t* const value ) +{ + return Catch::toString( static_cast( value ) ); +} + +std::string toString( int value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} + +std::string toString( unsigned long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} + +std::string toString( unsigned int value ) { + return Catch::toString( static_cast( value ) ); +} + +template +std::string fpToString( T value, int precision ) { + std::ostringstream oss; + oss << std::setprecision( precision ) + << std::fixed + << value; + std::string d = oss.str(); + std::size_t i = d.find_last_not_of( '0' ); + if( i != std::string::npos && i != d.size()-1 ) { + if( d[i] == '.' ) + i++; + d = d.substr( 0, i+1 ); + } + return d; +} + +std::string toString( const double value ) { + return fpToString( value, 10 ); +} +std::string toString( const float value ) { + return fpToString( value, 5 ) + 'f'; +} + +std::string toString( bool value ) { + return value ? "true" : "false"; +} + +std::string toString( char value ) { + if ( value == '\r' ) + return "'\\r'"; + if ( value == '\f' ) + return "'\\f'"; + if ( value == '\n' ) + return "'\\n'"; + if ( value == '\t' ) + return "'\\t'"; + if ( '\0' <= value && value < ' ' ) + return toString( static_cast( value ) ); + char chstr[] = "' '"; + chstr[1] = value; + return chstr; +} + +std::string toString( signed char value ) { + return toString( static_cast( value ) ); +} + +std::string toString( unsigned char value ) { + return toString( static_cast( value ) ); +} + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG +std::string toString( long long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} +std::string toString( unsigned long long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} +#endif + +#ifdef CATCH_CONFIG_CPP11_NULLPTR +std::string toString( std::nullptr_t ) { + return "nullptr"; +} +#endif + +#ifdef __OBJC__ + std::string toString( NSString const * const& nsstring ) { + if( !nsstring ) + return "nil"; + return "@" + toString([nsstring UTF8String]); + } + std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) { + if( !nsstring ) + return "nil"; + return "@" + toString([nsstring UTF8String]); + } + std::string toString( NSObject* const& nsObject ) { + return toString( [nsObject description] ); + } +#endif + +} // end namespace Catch + +// #included from: catch_result_builder.hpp +#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED + +namespace Catch { + + std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) { + return secondArg.empty() || secondArg == "\"\"" + ? capturedExpression + : capturedExpression + ", " + secondArg; + } + ResultBuilder::ResultBuilder( char const* macroName, + SourceLineInfo const& lineInfo, + char const* capturedExpression, + ResultDisposition::Flags resultDisposition, + char const* secondArg ) + : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ), + m_shouldDebugBreak( false ), + m_shouldThrow( false ) + {} + + ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { + m_data.resultType = result; + return *this; + } + ResultBuilder& ResultBuilder::setResultType( bool result ) { + m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; + return *this; + } + + void ResultBuilder::endExpression( DecomposedExpression const& expr ) { + AssertionResult result = build( expr ); + handleResult( result ); + } + + void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { + m_assertionInfo.resultDisposition = resultDisposition; + m_stream.oss << Catch::translateActiveException(); + captureResult( ResultWas::ThrewException ); + } + + void ResultBuilder::captureResult( ResultWas::OfType resultType ) { + setResultType( resultType ); + captureExpression(); + } + + void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { + if( expectedMessage.empty() ) + captureExpectedException( Matchers::Impl::MatchAllOf() ); + else + captureExpectedException( Matchers::Equals( expectedMessage ) ); + } + + void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase const& matcher ) { + + assert( !isFalseTest( m_assertionInfo.resultDisposition ) ); + AssertionResultData data = m_data; + data.resultType = ResultWas::Ok; + data.reconstructedExpression = m_assertionInfo.capturedExpression; + + std::string actualMessage = Catch::translateActiveException(); + if( !matcher.match( actualMessage ) ) { + data.resultType = ResultWas::ExpressionFailed; + data.reconstructedExpression = actualMessage; + } + AssertionResult result( m_assertionInfo, data ); + handleResult( result ); + } + + void ResultBuilder::captureExpression() { + AssertionResult result = build(); + handleResult( result ); + } + + void ResultBuilder::handleResult( AssertionResult const& result ) + { + getResultCapture().assertionEnded( result ); + + if( !result.isOk() ) { + if( getCurrentContext().getConfig()->shouldDebugBreak() ) + m_shouldDebugBreak = true; + if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) + m_shouldThrow = true; + } + } + + void ResultBuilder::react() { +#if defined(CATCH_CONFIG_FAST_COMPILE) + if (m_shouldDebugBreak) { + /////////////////////////////////////////////////////////////////// + // To inspect the state during test, you need to go one level up the callstack + // To go back to the test and change execution, jump over the throw statement + /////////////////////////////////////////////////////////////////// + CATCH_BREAK_INTO_DEBUGGER(); + } +#endif + if( m_shouldThrow ) + throw Catch::TestFailureException(); + } + + bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } + bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } + + AssertionResult ResultBuilder::build() const + { + return build( *this ); + } + + // CAVEAT: The returned AssertionResult stores a pointer to the argument expr, + // a temporary DecomposedExpression, which in turn holds references to + // operands, possibly temporary as well. + // It should immediately be passed to handleResult; if the expression + // needs to be reported, its string expansion must be composed before + // the temporaries are destroyed. + AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const + { + assert( m_data.resultType != ResultWas::Unknown ); + AssertionResultData data = m_data; + + // Flip bool results if FalseTest flag is set + if( isFalseTest( m_assertionInfo.resultDisposition ) ) { + data.negate( expr.isBinaryExpression() ); + } + + data.message = m_stream.oss.str(); + data.decomposedExpression = &expr; // for lazy reconstruction + return AssertionResult( m_assertionInfo, data ); + } + + void ResultBuilder::reconstructExpression( std::string& dest ) const { + dest = m_assertionInfo.capturedExpression; + } + +} // end namespace Catch + +// #included from: catch_tag_alias_registry.hpp +#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED + +// #included from: catch_tag_alias_registry.h +#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED + +#include + +namespace Catch { + + class TagAliasRegistry : public ITagAliasRegistry { + public: + virtual ~TagAliasRegistry(); + virtual Option find( std::string const& alias ) const; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const; + void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + static TagAliasRegistry& get(); + + private: + std::map m_registry; + }; + +} // end namespace Catch + +namespace Catch { + + TagAliasRegistry::~TagAliasRegistry() {} + + Option TagAliasRegistry::find( std::string const& alias ) const { + std::map::const_iterator it = m_registry.find( alias ); + if( it != m_registry.end() ) + return it->second; + else + return Option(); + } + + std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { + std::string expandedTestSpec = unexpandedTestSpec; + for( std::map::const_iterator it = m_registry.begin(), itEnd = m_registry.end(); + it != itEnd; + ++it ) { + std::size_t pos = expandedTestSpec.find( it->first ); + if( pos != std::string::npos ) { + expandedTestSpec = expandedTestSpec.substr( 0, pos ) + + it->second.tag + + expandedTestSpec.substr( pos + it->first.size() ); + } + } + return expandedTestSpec; + } + + void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { + + if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) { + std::ostringstream oss; + oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo; + throw std::domain_error( oss.str().c_str() ); + } + if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { + std::ostringstream oss; + oss << "error: tag alias, \"" << alias << "\" already registered.\n" + << "\tFirst seen at " << find(alias)->lineInfo << '\n' + << "\tRedefined at " << lineInfo; + throw std::domain_error( oss.str().c_str() ); + } + } + + TagAliasRegistry& TagAliasRegistry::get() { + static TagAliasRegistry instance; + return instance; + + } + + ITagAliasRegistry::~ITagAliasRegistry() {} + ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); } + + RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { + try { + TagAliasRegistry::get().add( alias, tag, lineInfo ); + } + catch( std::exception& ex ) { + Colour colourGuard( Colour::Red ); + Catch::cerr() << ex.what() << std::endl; + exit(1); + } + } + +} // end namespace Catch + +// #included from: catch_matchers_string.hpp + +namespace Catch { +namespace Matchers { + + namespace StdString { + + CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_str( adjustString( str ) ) + {} + std::string CasedString::adjustString( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No + ? toLower( str ) + : str; + } + std::string CasedString::caseSensitivitySuffix() const { + return m_caseSensitivity == CaseSensitive::No + ? " (case insensitive)" + : std::string(); + } + + StringMatcherBase::StringMatcherBase( std::string operation, CasedString const& comparator ) + : m_comparator( comparator ), + m_operation( operation ) { + } + + std::string StringMatcherBase::describe() const { + std::string description; + description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + + m_comparator.caseSensitivitySuffix().size()); + description += m_operation; + description += ": \""; + description += m_comparator.m_str; + description += "\""; + description += m_comparator.caseSensitivitySuffix(); + return description; + } + + EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {} + + bool EqualsMatcher::match( std::string const& source ) const { + return m_comparator.adjustString( source ) == m_comparator.m_str; + } + + ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {} + + bool ContainsMatcher::match( std::string const& source ) const { + return contains( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {} + + bool StartsWithMatcher::match( std::string const& source ) const { + return startsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {} + + bool EndsWithMatcher::match( std::string const& source ) const { + return endsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + } // namespace StdString + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + +} // namespace Matchers +} // namespace Catch +// #included from: ../reporters/catch_reporter_multi.hpp +#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED + +namespace Catch { + +class MultipleReporters : public SharedImpl { + typedef std::vector > Reporters; + Reporters m_reporters; + +public: + void add( Ptr const& reporter ) { + m_reporters.push_back( reporter ); + } + +public: // IStreamingReporter + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporters[0]->getPreferences(); + } + + virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->noMatchingTestCases( spec ); + } + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testRunStarting( testRunInfo ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testGroupStarting( groupInfo ); + } + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testCaseStarting( testInfo ); + } + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->sectionStarting( sectionInfo ); + } + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->assertionStarting( assertionInfo ); + } + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + bool clearBuffer = false; + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + clearBuffer |= (*it)->assertionEnded( assertionStats ); + return clearBuffer; + } + + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->sectionEnded( sectionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testCaseEnded( testCaseStats ); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testGroupEnded( testGroupStats ); + } + + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testRunEnded( testRunStats ); + } + + virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->skipTest( testInfo ); + } + + virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE { + return this; + } + +}; + +Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ) { + Ptr resultingReporter; + + if( existingReporter ) { + MultipleReporters* multi = existingReporter->tryAsMulti(); + if( !multi ) { + multi = new MultipleReporters; + resultingReporter = Ptr( multi ); + if( existingReporter ) + multi->add( existingReporter ); + } + else + resultingReporter = existingReporter; + multi->add( additionalReporter ); + } + else + resultingReporter = additionalReporter; + + return resultingReporter; +} + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_xml.hpp +#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED + +// #included from: catch_reporter_bases.hpp +#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED + +#include +#include + +namespace Catch { + + struct StreamingReporterBase : SharedImpl { + + StreamingReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + } + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporterPrefs; + } + + virtual ~StreamingReporterBase() CATCH_OVERRIDE; + + virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {} + + virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE { + currentTestRunInfo = _testRunInfo; + } + virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE { + currentGroupInfo = _groupInfo; + } + + virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE { + currentTestCaseInfo = _testInfo; + } + virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { + m_sectionStack.push_back( _sectionInfo ); + } + + virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE { + m_sectionStack.pop_back(); + } + virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE { + currentTestCaseInfo.reset(); + } + virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE { + currentGroupInfo.reset(); + } + virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE { + currentTestCaseInfo.reset(); + currentGroupInfo.reset(); + currentTestRunInfo.reset(); + } + + virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE { + // Don't do anything with this by default. + // It can optionally be overridden in the derived class. + } + + Ptr m_config; + std::ostream& stream; + + LazyStat currentTestRunInfo; + LazyStat currentGroupInfo; + LazyStat currentTestCaseInfo; + + std::vector m_sectionStack; + ReporterPreferences m_reporterPrefs; + }; + + struct CumulativeReporterBase : SharedImpl { + template + struct Node : SharedImpl<> { + explicit Node( T const& _value ) : value( _value ) {} + virtual ~Node() {} + + typedef std::vector > ChildNodes; + T value; + ChildNodes children; + }; + struct SectionNode : SharedImpl<> { + explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {} + virtual ~SectionNode(); + + bool operator == ( SectionNode const& other ) const { + return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; + } + bool operator == ( Ptr const& other ) const { + return operator==( *other ); + } + + SectionStats stats; + typedef std::vector > ChildSections; + typedef std::vector Assertions; + ChildSections childSections; + Assertions assertions; + std::string stdOut; + std::string stdErr; + }; + + struct BySectionInfo { + BySectionInfo( SectionInfo const& other ) : m_other( other ) {} + BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} + bool operator() ( Ptr const& node ) const { + return node->stats.sectionInfo.lineInfo == m_other.lineInfo; + } + private: + void operator=( BySectionInfo const& ); + SectionInfo const& m_other; + }; + + typedef Node TestCaseNode; + typedef Node TestGroupNode; + typedef Node TestRunNode; + + CumulativeReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + } + ~CumulativeReporterBase(); + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporterPrefs; + } + + virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {} + virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {} + + virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {} + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); + Ptr node; + if( m_sectionStack.empty() ) { + if( !m_rootSection ) + m_rootSection = new SectionNode( incompleteStats ); + node = m_rootSection; + } + else { + SectionNode& parentNode = *m_sectionStack.back(); + SectionNode::ChildSections::const_iterator it = + std::find_if( parentNode.childSections.begin(), + parentNode.childSections.end(), + BySectionInfo( sectionInfo ) ); + if( it == parentNode.childSections.end() ) { + node = new SectionNode( incompleteStats ); + parentNode.childSections.push_back( node ); + } + else + node = *it; + } + m_sectionStack.push_back( node ); + m_deepestSection = node; + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + assert( !m_sectionStack.empty() ); + SectionNode& sectionNode = *m_sectionStack.back(); + sectionNode.assertions.push_back( assertionStats ); + // AssertionResult holds a pointer to a temporary DecomposedExpression, + // which getExpandedExpression() calls to build the expression string. + // Our section stack copy of the assertionResult will likely outlive the + // temporary, so it must be expanded or discarded now to avoid calling + // a destroyed object later. + prepareExpandedExpression( sectionNode.assertions.back().assertionResult ); + return true; + } + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + assert( !m_sectionStack.empty() ); + SectionNode& node = *m_sectionStack.back(); + node.stats = sectionStats; + m_sectionStack.pop_back(); + } + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + Ptr node = new TestCaseNode( testCaseStats ); + assert( m_sectionStack.size() == 0 ); + node->children.push_back( m_rootSection ); + m_testCases.push_back( node ); + m_rootSection.reset(); + + assert( m_deepestSection ); + m_deepestSection->stdOut = testCaseStats.stdOut; + m_deepestSection->stdErr = testCaseStats.stdErr; + } + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + Ptr node = new TestGroupNode( testGroupStats ); + node->children.swap( m_testCases ); + m_testGroups.push_back( node ); + } + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + Ptr node = new TestRunNode( testRunStats ); + node->children.swap( m_testGroups ); + m_testRuns.push_back( node ); + testRunEndedCumulative(); + } + virtual void testRunEndedCumulative() = 0; + + virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {} + + virtual void prepareExpandedExpression( AssertionResult& result ) const { + if( result.isOk() ) + result.discardDecomposedExpression(); + else + result.expandDecomposedExpression(); + } + + Ptr m_config; + std::ostream& stream; + std::vector m_assertions; + std::vector > > m_sections; + std::vector > m_testCases; + std::vector > m_testGroups; + + std::vector > m_testRuns; + + Ptr m_rootSection; + Ptr m_deepestSection; + std::vector > m_sectionStack; + ReporterPreferences m_reporterPrefs; + + }; + + template + char const* getLineOfChars() { + static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; + if( !*line ) { + std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); + line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; + } + return line; + } + + struct TestEventListenerBase : StreamingReporterBase { + TestEventListenerBase( ReporterConfig const& _config ) + : StreamingReporterBase( _config ) + {} + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} + virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE { + return false; + } + }; + +} // end namespace Catch + +// #included from: ../internal/catch_reporter_registrars.hpp +#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED + +namespace Catch { + + template + class LegacyReporterRegistrar { + + class ReporterFactory : public IReporterFactory { + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new LegacyReporterAdapter( new T( config ) ); + } + + virtual std::string getDescription() const { + return T::getDescription(); + } + }; + + public: + + LegacyReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); + } + }; + + template + class ReporterRegistrar { + + class ReporterFactory : public SharedImpl { + + // *** Please Note ***: + // - If you end up here looking at a compiler error because it's trying to register + // your custom reporter class be aware that the native reporter interface has changed + // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via + // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. + // However please consider updating to the new interface as the old one is now + // deprecated and will probably be removed quite soon! + // Please contact me via github if you have any questions at all about this. + // In fact, ideally, please contact me anyway to let me know you've hit this - as I have + // no idea who is actually using custom reporters at all (possibly no-one!). + // The new interface is designed to minimise exposure to interface changes in the future. + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new T( config ); + } + + virtual std::string getDescription() const { + return T::getDescription(); + } + }; + + public: + + ReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); + } + }; + + template + class ListenerRegistrar { + + class ListenerFactory : public SharedImpl { + + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new T( config ); + } + virtual std::string getDescription() const { + return std::string(); + } + }; + + public: + + ListenerRegistrar() { + getMutableRegistryHub().registerListener( new ListenerFactory() ); + } + }; +} + +#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ + namespace{ Catch::LegacyReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } + +#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ + namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } + +#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \ + namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } + +// #included from: ../internal/catch_xmlwriter.hpp +#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED + +#include +#include +#include +#include + +namespace Catch { + + class XmlEncode { + public: + enum ForWhat { ForTextNodes, ForAttributes }; + + XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ) + : m_str( str ), + m_forWhat( forWhat ) + {} + + void encodeTo( std::ostream& os ) const { + + // Apostrophe escaping not necessary if we always use " to write attributes + // (see: http://www.w3.org/TR/xml/#syntax) + + for( std::size_t i = 0; i < m_str.size(); ++ i ) { + char c = m_str[i]; + switch( c ) { + case '<': os << "<"; break; + case '&': os << "&"; break; + + case '>': + // See: http://www.w3.org/TR/xml/#syntax + if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' ) + os << ">"; + else + os << c; + break; + + case '\"': + if( m_forWhat == ForAttributes ) + os << """; + else + os << c; + break; + + default: + // Escape control chars - based on contribution by @espenalb in PR #465 and + // by @mrpi PR #588 + if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) { + // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) + << static_cast( c ); + } + else + os << c; + } + } + } + + friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { + xmlEncode.encodeTo( os ); + return os; + } + + private: + std::string m_str; + ForWhat m_forWhat; + }; + + class XmlWriter { + public: + + class ScopedElement { + public: + ScopedElement( XmlWriter* writer ) + : m_writer( writer ) + {} + + ScopedElement( ScopedElement const& other ) + : m_writer( other.m_writer ){ + other.m_writer = CATCH_NULL; + } + + ~ScopedElement() { + if( m_writer ) + m_writer->endElement(); + } + + ScopedElement& writeText( std::string const& text, bool indent = true ) { + m_writer->writeText( text, indent ); + return *this; + } + + template + ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { + m_writer->writeAttribute( name, attribute ); + return *this; + } + + private: + mutable XmlWriter* m_writer; + }; + + XmlWriter() + : m_tagIsOpen( false ), + m_needsNewline( false ), + m_os( Catch::cout() ) + { + writeDeclaration(); + } + + XmlWriter( std::ostream& os ) + : m_tagIsOpen( false ), + m_needsNewline( false ), + m_os( os ) + { + writeDeclaration(); + } + + ~XmlWriter() { + while( !m_tags.empty() ) + endElement(); + } + + XmlWriter& startElement( std::string const& name ) { + ensureTagClosed(); + newlineIfNecessary(); + m_os << m_indent << '<' << name; + m_tags.push_back( name ); + m_indent += " "; + m_tagIsOpen = true; + return *this; + } + + ScopedElement scopedElement( std::string const& name ) { + ScopedElement scoped( this ); + startElement( name ); + return scoped; + } + + XmlWriter& endElement() { + newlineIfNecessary(); + m_indent = m_indent.substr( 0, m_indent.size()-2 ); + if( m_tagIsOpen ) { + m_os << "/>"; + m_tagIsOpen = false; + } + else { + m_os << m_indent << ""; + } + m_os << std::endl; + m_tags.pop_back(); + return *this; + } + + XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) { + if( !name.empty() && !attribute.empty() ) + m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; + return *this; + } + + XmlWriter& writeAttribute( std::string const& name, bool attribute ) { + m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; + return *this; + } + + template + XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { + std::ostringstream oss; + oss << attribute; + return writeAttribute( name, oss.str() ); + } + + XmlWriter& writeText( std::string const& text, bool indent = true ) { + if( !text.empty() ){ + bool tagWasOpen = m_tagIsOpen; + ensureTagClosed(); + if( tagWasOpen && indent ) + m_os << m_indent; + m_os << XmlEncode( text ); + m_needsNewline = true; + } + return *this; + } + + XmlWriter& writeComment( std::string const& text ) { + ensureTagClosed(); + m_os << m_indent << ""; + m_needsNewline = true; + return *this; + } + + void writeStylesheetRef( std::string const& url ) { + m_os << "\n"; + } + + XmlWriter& writeBlankLine() { + ensureTagClosed(); + m_os << '\n'; + return *this; + } + + void ensureTagClosed() { + if( m_tagIsOpen ) { + m_os << ">" << std::endl; + m_tagIsOpen = false; + } + } + + private: + XmlWriter( XmlWriter const& ); + void operator=( XmlWriter const& ); + + void writeDeclaration() { + m_os << "\n"; + } + + void newlineIfNecessary() { + if( m_needsNewline ) { + m_os << std::endl; + m_needsNewline = false; + } + } + + bool m_tagIsOpen; + bool m_needsNewline; + std::vector m_tags; + std::string m_indent; + std::ostream& m_os; + }; + +} +// #included from: catch_reenable_warnings.h + +#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(pop) +# else +# pragma clang diagnostic pop +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic pop +#endif + + +namespace Catch { + class XmlReporter : public StreamingReporterBase { + public: + XmlReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_xml(_config.stream()), + m_sectionDepth( 0 ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + virtual ~XmlReporter() CATCH_OVERRIDE; + + static std::string getDescription() { + return "Reports test results as an XML document"; + } + + virtual std::string getStylesheetRef() const { + return std::string(); + } + + void writeSourceInfo( SourceLineInfo const& sourceInfo ) { + m_xml + .writeAttribute( "filename", sourceInfo.file ) + .writeAttribute( "line", sourceInfo.line ); + } + + public: // StreamingReporterBase + + virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE { + StreamingReporterBase::noMatchingTestCases( s ); + } + + virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testRunStarting( testInfo ); + std::string stylesheetRef = getStylesheetRef(); + if( !stylesheetRef.empty() ) + m_xml.writeStylesheetRef( stylesheetRef ); + m_xml.startElement( "Catch" ); + if( !m_config->name().empty() ) + m_xml.writeAttribute( "name", m_config->name() ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testGroupStarting( groupInfo ); + m_xml.startElement( "Group" ) + .writeAttribute( "name", groupInfo.name ); + } + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseStarting(testInfo); + m_xml.startElement( "TestCase" ) + .writeAttribute( "name", trim( testInfo.name ) ) + .writeAttribute( "description", testInfo.description ) + .writeAttribute( "tags", testInfo.tagsAsString ); + + writeSourceInfo( testInfo.lineInfo ); + + if ( m_config->showDurations() == ShowDurations::Always ) + m_testCaseTimer.start(); + m_xml.ensureTagClosed(); + } + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + StreamingReporterBase::sectionStarting( sectionInfo ); + if( m_sectionDepth++ > 0 ) { + m_xml.startElement( "Section" ) + .writeAttribute( "name", trim( sectionInfo.name ) ) + .writeAttribute( "description", sectionInfo.description ); + writeSourceInfo( sectionInfo.lineInfo ); + m_xml.ensureTagClosed(); + } + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + const AssertionResult& assertionResult = assertionStats.assertionResult; + + // Print any info messages in tags. + if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { + for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); + it != itEnd; + ++it ) { + if( it->type == ResultWas::Info ) { + m_xml.scopedElement( "Info" ) + .writeText( it->message ); + } else if ( it->type == ResultWas::Warning ) { + m_xml.scopedElement( "Warning" ) + .writeText( it->message ); + } + } + } + + // Drop out if result was successful but we're not printing them. + if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) ) + return true; + + // Print the expression if there is one. + if( assertionResult.hasExpression() ) { + m_xml.startElement( "Expression" ) + .writeAttribute( "success", assertionResult.succeeded() ) + .writeAttribute( "type", assertionResult.getTestMacroName() ); + + writeSourceInfo( assertionResult.getSourceInfo() ); + + m_xml.scopedElement( "Original" ) + .writeText( assertionResult.getExpression() ); + m_xml.scopedElement( "Expanded" ) + .writeText( assertionResult.getExpandedExpression() ); + } + + // And... Print a result applicable to each result type. + switch( assertionResult.getResultType() ) { + case ResultWas::ThrewException: + m_xml.startElement( "Exception" ); + writeSourceInfo( assertionResult.getSourceInfo() ); + m_xml.writeText( assertionResult.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::FatalErrorCondition: + m_xml.startElement( "FatalErrorCondition" ); + writeSourceInfo( assertionResult.getSourceInfo() ); + m_xml.writeText( assertionResult.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::Info: + m_xml.scopedElement( "Info" ) + .writeText( assertionResult.getMessage() ); + break; + case ResultWas::Warning: + // Warning will already have been written + break; + case ResultWas::ExplicitFailure: + m_xml.startElement( "Failure" ); + writeSourceInfo( assertionResult.getSourceInfo() ); + m_xml.writeText( assertionResult.getMessage() ); + m_xml.endElement(); + break; + default: + break; + } + + if( assertionResult.hasExpression() ) + m_xml.endElement(); + + return true; + } + + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + StreamingReporterBase::sectionEnded( sectionStats ); + if( --m_sectionDepth > 0 ) { + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); + e.writeAttribute( "successes", sectionStats.assertions.passed ); + e.writeAttribute( "failures", sectionStats.assertions.failed ); + e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); + + m_xml.endElement(); + } + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseEnded( testCaseStats ); + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); + e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); + + if( !testCaseStats.stdOut.empty() ) + m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false ); + if( !testCaseStats.stdErr.empty() ) + m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false ); + + m_xml.endElement(); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + StreamingReporterBase::testGroupEnded( testGroupStats ); + // TODO: Check testGroupStats.aborting and act accordingly. + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) + .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + StreamingReporterBase::testRunEnded( testRunStats ); + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testRunStats.totals.assertions.passed ) + .writeAttribute( "failures", testRunStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + private: + Timer m_testCaseTimer; + XmlWriter m_xml; + int m_sectionDepth; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter ) + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_junit.hpp +#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED + +#include + +namespace Catch { + + namespace { + std::string getCurrentTimestamp() { + // Beware, this is not reentrant because of backward compatibility issues + // Also, UTC only, again because of backward compatibility (%z is C++11) + time_t rawtime; + std::time(&rawtime); + const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z"); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &rawtime); +#else + std::tm* timeInfo; + timeInfo = std::gmtime(&rawtime); +#endif + + char timeStamp[timeStampSize]; + const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp); + } + + } + + class JunitReporter : public CumulativeReporterBase { + public: + JunitReporter( ReporterConfig const& _config ) + : CumulativeReporterBase( _config ), + xml( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + virtual ~JunitReporter() CATCH_OVERRIDE; + + static std::string getDescription() { + return "Reports test results in an XML format that looks like Ant's junitreport target"; + } + + virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {} + + virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE { + CumulativeReporterBase::testRunStarting( runInfo ); + xml.startElement( "testsuites" ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + suiteTimer.start(); + stdOutForSuite.str(""); + stdErrForSuite.str(""); + unexpectedExceptions = 0; + CumulativeReporterBase::testGroupStarting( groupInfo ); + } + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException ) + unexpectedExceptions++; + return CumulativeReporterBase::assertionEnded( assertionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + stdOutForSuite << testCaseStats.stdOut; + stdErrForSuite << testCaseStats.stdErr; + CumulativeReporterBase::testCaseEnded( testCaseStats ); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + double suiteTime = suiteTimer.getElapsedSeconds(); + CumulativeReporterBase::testGroupEnded( testGroupStats ); + writeGroup( *m_testGroups.back(), suiteTime ); + } + + virtual void testRunEndedCumulative() CATCH_OVERRIDE { + xml.endElement(); + } + + void writeGroup( TestGroupNode const& groupNode, double suiteTime ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); + TestGroupStats const& stats = groupNode.value; + xml.writeAttribute( "name", stats.groupInfo.name ); + xml.writeAttribute( "errors", unexpectedExceptions ); + xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); + xml.writeAttribute( "tests", stats.totals.assertions.total() ); + xml.writeAttribute( "hostname", "tbd" ); // !TBD + if( m_config->showDurations() == ShowDurations::Never ) + xml.writeAttribute( "time", "" ); + else + xml.writeAttribute( "time", suiteTime ); + xml.writeAttribute( "timestamp", getCurrentTimestamp() ); + + // Write test cases + for( TestGroupNode::ChildNodes::const_iterator + it = groupNode.children.begin(), itEnd = groupNode.children.end(); + it != itEnd; + ++it ) + writeTestCase( **it ); + + xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false ); + xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false ); + } + + void writeTestCase( TestCaseNode const& testCaseNode ) { + TestCaseStats const& stats = testCaseNode.value; + + // All test cases have exactly one section - which represents the + // test case itself. That section may have 0-n nested sections + assert( testCaseNode.children.size() == 1 ); + SectionNode const& rootSection = *testCaseNode.children.front(); + + std::string className = stats.testInfo.className; + + if( className.empty() ) { + if( rootSection.childSections.empty() ) + className = "global"; + } + writeSection( className, "", rootSection ); + } + + void writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode ) { + std::string name = trim( sectionNode.stats.sectionInfo.name ); + if( !rootName.empty() ) + name = rootName + '/' + name; + + if( !sectionNode.assertions.empty() || + !sectionNode.stdOut.empty() || + !sectionNode.stdErr.empty() ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); + if( className.empty() ) { + xml.writeAttribute( "classname", name ); + xml.writeAttribute( "name", "root" ); + } + else { + xml.writeAttribute( "classname", className ); + xml.writeAttribute( "name", name ); + } + xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) ); + + writeAssertions( sectionNode ); + + if( !sectionNode.stdOut.empty() ) + xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); + if( !sectionNode.stdErr.empty() ) + xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); + } + for( SectionNode::ChildSections::const_iterator + it = sectionNode.childSections.begin(), + itEnd = sectionNode.childSections.end(); + it != itEnd; + ++it ) + if( className.empty() ) + writeSection( name, "", **it ); + else + writeSection( className, name, **it ); + } + + void writeAssertions( SectionNode const& sectionNode ) { + for( SectionNode::Assertions::const_iterator + it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end(); + it != itEnd; + ++it ) + writeAssertion( *it ); + } + void writeAssertion( AssertionStats const& stats ) { + AssertionResult const& result = stats.assertionResult; + if( !result.isOk() ) { + std::string elementName; + switch( result.getResultType() ) { + case ResultWas::ThrewException: + case ResultWas::FatalErrorCondition: + elementName = "error"; + break; + case ResultWas::ExplicitFailure: + elementName = "failure"; + break; + case ResultWas::ExpressionFailed: + elementName = "failure"; + break; + case ResultWas::DidntThrowException: + elementName = "failure"; + break; + + // We should never see these here: + case ResultWas::Info: + case ResultWas::Warning: + case ResultWas::Ok: + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + elementName = "internalError"; + break; + } + + XmlWriter::ScopedElement e = xml.scopedElement( elementName ); + + xml.writeAttribute( "message", result.getExpandedExpression() ); + xml.writeAttribute( "type", result.getTestMacroName() ); + + std::ostringstream oss; + if( !result.getMessage().empty() ) + oss << result.getMessage() << '\n'; + for( std::vector::const_iterator + it = stats.infoMessages.begin(), + itEnd = stats.infoMessages.end(); + it != itEnd; + ++it ) + if( it->type == ResultWas::Info ) + oss << it->message << '\n'; + + oss << "at " << result.getSourceInfo(); + xml.writeText( oss.str(), false ); + } + } + + XmlWriter xml; + Timer suiteTimer; + std::ostringstream stdOutForSuite; + std::ostringstream stdErrForSuite; + unsigned int unexpectedExceptions; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter ) + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_console.hpp +#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED + +#include +#include + +namespace Catch { + + namespace { + // Because formatting using c++ streams is stateful, drop down to C is required + // Alternatively we could use stringstream, but its performance is... not good. + std::string getFormattedDuration( double duration ) { + // Max exponent + 1 is required to represent the whole part + // + 1 for decimal point + // + 3 for the 3 decimal places + // + 1 for null terminator + const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; + char buffer[maxDoubleSize]; +#ifdef _MSC_VER + sprintf_s(buffer, "%.3f", duration); +#else + sprintf(buffer, "%.3f", duration); +#endif + return std::string(buffer); + } + } + + struct ConsoleReporter : StreamingReporterBase { + ConsoleReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_headerPrinted( false ) + {} + + virtual ~ConsoleReporter() CATCH_OVERRIDE; + static std::string getDescription() { + return "Reports test results as plain lines of text"; + } + + virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { + stream << "No test cases matched '" << spec << '\'' << std::endl; + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { + } + + virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE { + AssertionResult const& result = _assertionStats.assertionResult; + + bool printInfoMessages = true; + + // Drop out if result was successful and we're not printing those + if( !m_config->includeSuccessfulResults() && result.isOk() ) { + if( result.getResultType() != ResultWas::Warning ) + return false; + printInfoMessages = false; + } + + lazyPrint(); + + AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); + printer.print(); + stream << std::endl; + return true; + } + + virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { + m_headerPrinted = false; + StreamingReporterBase::sectionStarting( _sectionInfo ); + } + virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE { + if( _sectionStats.missingAssertions ) { + lazyPrint(); + Colour colour( Colour::ResultError ); + if( m_sectionStack.size() > 1 ) + stream << "\nNo assertions in section"; + else + stream << "\nNo assertions in test case"; + stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; + } + if( m_config->showDurations() == ShowDurations::Always ) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + if( m_headerPrinted ) { + m_headerPrinted = false; + } + StreamingReporterBase::sectionEnded( _sectionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseEnded( _testCaseStats ); + m_headerPrinted = false; + } + virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE { + if( currentGroupInfo.used ) { + printSummaryDivider(); + stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; + printTotals( _testGroupStats.totals ); + stream << '\n' << std::endl; + } + StreamingReporterBase::testGroupEnded( _testGroupStats ); + } + virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE { + printTotalsDivider( _testRunStats.totals ); + printTotals( _testRunStats.totals ); + stream << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + private: + + class AssertionPrinter { + void operator= ( AssertionPrinter const& ); + public: + AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) + : stream( _stream ), + stats( _stats ), + result( _stats.assertionResult ), + colour( Colour::None ), + message( result.getMessage() ), + messages( _stats.infoMessages ), + printInfoMessages( _printInfoMessages ) + { + switch( result.getResultType() ) { + case ResultWas::Ok: + colour = Colour::Success; + passOrFail = "PASSED"; + //if( result.hasMessage() ) + if( _stats.infoMessages.size() == 1 ) + messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; + break; + case ResultWas::ExpressionFailed: + if( result.isOk() ) { + colour = Colour::Success; + passOrFail = "FAILED - but was ok"; + } + else { + colour = Colour::Error; + passOrFail = "FAILED"; + } + if( _stats.infoMessages.size() == 1 ) + messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; + break; + case ResultWas::ThrewException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to unexpected exception with message"; + break; + case ResultWas::FatalErrorCondition: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to a fatal error condition"; + break; + case ResultWas::DidntThrowException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "because no exception was thrown where one was expected"; + break; + case ResultWas::Info: + messageLabel = "info"; + break; + case ResultWas::Warning: + messageLabel = "warning"; + break; + case ResultWas::ExplicitFailure: + passOrFail = "FAILED"; + colour = Colour::Error; + if( _stats.infoMessages.size() == 1 ) + messageLabel = "explicitly with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "explicitly with messages"; + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + passOrFail = "** internal error **"; + colour = Colour::Error; + break; + } + } + + void print() const { + printSourceInfo(); + if( stats.totals.assertions.total() > 0 ) { + if( result.isOk() ) + stream << '\n'; + printResultType(); + printOriginalExpression(); + printReconstructedExpression(); + } + else { + stream << '\n'; + } + printMessage(); + } + + private: + void printResultType() const { + if( !passOrFail.empty() ) { + Colour colourGuard( colour ); + stream << passOrFail << ":\n"; + } + } + void printOriginalExpression() const { + if( result.hasExpression() ) { + Colour colourGuard( Colour::OriginalExpression ); + stream << " "; + stream << result.getExpressionInMacro(); + stream << '\n'; + } + } + void printReconstructedExpression() const { + if( result.hasExpandedExpression() ) { + stream << "with expansion:\n"; + Colour colourGuard( Colour::ReconstructedExpression ); + stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n'; + } + } + void printMessage() const { + if( !messageLabel.empty() ) + stream << messageLabel << ':' << '\n'; + for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); + it != itEnd; + ++it ) { + // If this assertion is a warning ignore any INFO messages + if( printInfoMessages || it->type != ResultWas::Info ) + stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n'; + } + } + void printSourceInfo() const { + Colour colourGuard( Colour::FileName ); + stream << result.getSourceInfo() << ": "; + } + + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + Colour::Code colour; + std::string passOrFail; + std::string messageLabel; + std::string message; + std::vector messages; + bool printInfoMessages; + }; + + void lazyPrint() { + + if( !currentTestRunInfo.used ) + lazyPrintRunInfo(); + if( !currentGroupInfo.used ) + lazyPrintGroupInfo(); + + if( !m_headerPrinted ) { + printTestCaseAndSectionHeader(); + m_headerPrinted = true; + } + } + void lazyPrintRunInfo() { + stream << '\n' << getLineOfChars<'~'>() << '\n'; + Colour colour( Colour::SecondaryText ); + stream << currentTestRunInfo->name + << " is a Catch v" << libraryVersion << " host application.\n" + << "Run with -? for options\n\n"; + + if( m_config->rngSeed() != 0 ) + stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; + + currentTestRunInfo.used = true; + } + void lazyPrintGroupInfo() { + if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) { + printClosedHeader( "Group: " + currentGroupInfo->name ); + currentGroupInfo.used = true; + } + } + void printTestCaseAndSectionHeader() { + assert( !m_sectionStack.empty() ); + printOpenHeader( currentTestCaseInfo->name ); + + if( m_sectionStack.size() > 1 ) { + Colour colourGuard( Colour::Headers ); + + std::vector::const_iterator + it = m_sectionStack.begin()+1, // Skip first section (test case) + itEnd = m_sectionStack.end(); + for( ; it != itEnd; ++it ) + printHeaderString( it->name, 2 ); + } + + SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; + + if( !lineInfo.empty() ){ + stream << getLineOfChars<'-'>() << '\n'; + Colour colourGuard( Colour::FileName ); + stream << lineInfo << '\n'; + } + stream << getLineOfChars<'.'>() << '\n' << std::endl; + } + + void printClosedHeader( std::string const& _name ) { + printOpenHeader( _name ); + stream << getLineOfChars<'.'>() << '\n'; + } + void printOpenHeader( std::string const& _name ) { + stream << getLineOfChars<'-'>() << '\n'; + { + Colour colourGuard( Colour::Headers ); + printHeaderString( _name ); + } + } + + // if string has a : in first line will set indent to follow it on + // subsequent lines + void printHeaderString( std::string const& _string, std::size_t indent = 0 ) { + std::size_t i = _string.find( ": " ); + if( i != std::string::npos ) + i+=2; + else + i = 0; + stream << Text( _string, TextAttributes() + .setIndent( indent+i) + .setInitialIndent( indent ) ) << '\n'; + } + + struct SummaryColumn { + + SummaryColumn( std::string const& _label, Colour::Code _colour ) + : label( _label ), + colour( _colour ) + {} + SummaryColumn addRow( std::size_t count ) { + std::ostringstream oss; + oss << count; + std::string row = oss.str(); + for( std::vector::iterator it = rows.begin(); it != rows.end(); ++it ) { + while( it->size() < row.size() ) + *it = ' ' + *it; + while( it->size() > row.size() ) + row = ' ' + row; + } + rows.push_back( row ); + return *this; + } + + std::string label; + Colour::Code colour; + std::vector rows; + + }; + + void printTotals( Totals const& totals ) { + if( totals.testCases.total() == 0 ) { + stream << Colour( Colour::Warning ) << "No tests ran\n"; + } + else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) { + stream << Colour( Colour::ResultSuccess ) << "All tests passed"; + stream << " (" + << pluralise( totals.assertions.passed, "assertion" ) << " in " + << pluralise( totals.testCases.passed, "test case" ) << ')' + << '\n'; + } + else { + + std::vector columns; + columns.push_back( SummaryColumn( "", Colour::None ) + .addRow( totals.testCases.total() ) + .addRow( totals.assertions.total() ) ); + columns.push_back( SummaryColumn( "passed", Colour::Success ) + .addRow( totals.testCases.passed ) + .addRow( totals.assertions.passed ) ); + columns.push_back( SummaryColumn( "failed", Colour::ResultError ) + .addRow( totals.testCases.failed ) + .addRow( totals.assertions.failed ) ); + columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure ) + .addRow( totals.testCases.failedButOk ) + .addRow( totals.assertions.failedButOk ) ); + + printSummaryRow( "test cases", columns, 0 ); + printSummaryRow( "assertions", columns, 1 ); + } + } + void printSummaryRow( std::string const& label, std::vector const& cols, std::size_t row ) { + for( std::vector::const_iterator it = cols.begin(); it != cols.end(); ++it ) { + std::string value = it->rows[row]; + if( it->label.empty() ) { + stream << label << ": "; + if( value != "0" ) + stream << value; + else + stream << Colour( Colour::Warning ) << "- none -"; + } + else if( value != "0" ) { + stream << Colour( Colour::LightGrey ) << " | "; + stream << Colour( it->colour ) + << value << ' ' << it->label; + } + } + stream << '\n'; + } + + static std::size_t makeRatio( std::size_t number, std::size_t total ) { + std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0; + return ( ratio == 0 && number > 0 ) ? 1 : ratio; + } + static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) { + if( i > j && i > k ) + return i; + else if( j > k ) + return j; + else + return k; + } + + void printTotalsDivider( Totals const& totals ) { + if( totals.testCases.total() > 0 ) { + std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() ); + std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() ); + std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() ); + while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 ) + findMax( failedRatio, failedButOkRatio, passedRatio )++; + while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 ) + findMax( failedRatio, failedButOkRatio, passedRatio )--; + + stream << Colour( Colour::Error ) << std::string( failedRatio, '=' ); + stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' ); + if( totals.testCases.allPassed() ) + stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' ); + else + stream << Colour( Colour::Success ) << std::string( passedRatio, '=' ); + } + else { + stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' ); + } + stream << '\n'; + } + void printSummaryDivider() { + stream << getLineOfChars<'-'>() << '\n'; + } + + private: + bool m_headerPrinted; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter ) + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_compact.hpp +#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED + +namespace Catch { + + struct CompactReporter : StreamingReporterBase { + + CompactReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ) + {} + + virtual ~CompactReporter(); + + static std::string getDescription() { + return "Reports test results on a single line, suitable for IDEs"; + } + + virtual ReporterPreferences getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = false; + return prefs; + } + + virtual void noMatchingTestCases( std::string const& spec ) { + stream << "No test cases matched '" << spec << '\'' << std::endl; + } + + virtual void assertionStarting( AssertionInfo const& ) { + } + + virtual bool assertionEnded( AssertionStats const& _assertionStats ) { + AssertionResult const& result = _assertionStats.assertionResult; + + bool printInfoMessages = true; + + // Drop out if result was successful and we're not printing those + if( !m_config->includeSuccessfulResults() && result.isOk() ) { + if( result.getResultType() != ResultWas::Warning ) + return false; + printInfoMessages = false; + } + + AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); + printer.print(); + + stream << std::endl; + return true; + } + + virtual void testRunEnded( TestRunStats const& _testRunStats ) { + printTotals( _testRunStats.totals ); + stream << '\n' << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + private: + class AssertionPrinter { + void operator= ( AssertionPrinter const& ); + public: + AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) + : stream( _stream ) + , stats( _stats ) + , result( _stats.assertionResult ) + , messages( _stats.infoMessages ) + , itMessage( _stats.infoMessages.begin() ) + , printInfoMessages( _printInfoMessages ) + {} + + void print() { + printSourceInfo(); + + itMessage = messages.begin(); + + switch( result.getResultType() ) { + case ResultWas::Ok: + printResultType( Colour::ResultSuccess, passedString() ); + printOriginalExpression(); + printReconstructedExpression(); + if ( ! result.hasExpression() ) + printRemainingMessages( Colour::None ); + else + printRemainingMessages(); + break; + case ResultWas::ExpressionFailed: + if( result.isOk() ) + printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) ); + else + printResultType( Colour::Error, failedString() ); + printOriginalExpression(); + printReconstructedExpression(); + printRemainingMessages(); + break; + case ResultWas::ThrewException: + printResultType( Colour::Error, failedString() ); + printIssue( "unexpected exception with message:" ); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::FatalErrorCondition: + printResultType( Colour::Error, failedString() ); + printIssue( "fatal error condition with message:" ); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::DidntThrowException: + printResultType( Colour::Error, failedString() ); + printIssue( "expected exception, got none" ); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::Info: + printResultType( Colour::None, "info" ); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::Warning: + printResultType( Colour::None, "warning" ); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::ExplicitFailure: + printResultType( Colour::Error, failedString() ); + printIssue( "explicitly" ); + printRemainingMessages( Colour::None ); + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + printResultType( Colour::Error, "** internal error **" ); + break; + } + } + + private: + // Colour::LightGrey + + static Colour::Code dimColour() { return Colour::FileName; } + +#ifdef CATCH_PLATFORM_MAC + static const char* failedString() { return "FAILED"; } + static const char* passedString() { return "PASSED"; } +#else + static const char* failedString() { return "failed"; } + static const char* passedString() { return "passed"; } +#endif + + void printSourceInfo() const { + Colour colourGuard( Colour::FileName ); + stream << result.getSourceInfo() << ':'; + } + + void printResultType( Colour::Code colour, std::string passOrFail ) const { + if( !passOrFail.empty() ) { + { + Colour colourGuard( colour ); + stream << ' ' << passOrFail; + } + stream << ':'; + } + } + + void printIssue( std::string issue ) const { + stream << ' ' << issue; + } + + void printExpressionWas() { + if( result.hasExpression() ) { + stream << ';'; + { + Colour colour( dimColour() ); + stream << " expression was:"; + } + printOriginalExpression(); + } + } + + void printOriginalExpression() const { + if( result.hasExpression() ) { + stream << ' ' << result.getExpression(); + } + } + + void printReconstructedExpression() const { + if( result.hasExpandedExpression() ) { + { + Colour colour( dimColour() ); + stream << " for: "; + } + stream << result.getExpandedExpression(); + } + } + + void printMessage() { + if ( itMessage != messages.end() ) { + stream << " '" << itMessage->message << '\''; + ++itMessage; + } + } + + void printRemainingMessages( Colour::Code colour = dimColour() ) { + if ( itMessage == messages.end() ) + return; + + // using messages.end() directly yields compilation error: + std::vector::const_iterator itEnd = messages.end(); + const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); + + { + Colour colourGuard( colour ); + stream << " with " << pluralise( N, "message" ) << ':'; + } + + for(; itMessage != itEnd; ) { + // If this assertion is a warning ignore any INFO messages + if( printInfoMessages || itMessage->type != ResultWas::Info ) { + stream << " '" << itMessage->message << '\''; + if ( ++itMessage != itEnd ) { + Colour colourGuard( dimColour() ); + stream << " and"; + } + } + } + } + + private: + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + std::vector messages; + std::vector::const_iterator itMessage; + bool printInfoMessages; + }; + + // Colour, message variants: + // - white: No tests ran. + // - red: Failed [both/all] N test cases, failed [both/all] M assertions. + // - white: Passed [both/all] N test cases (no assertions). + // - red: Failed N tests cases, failed M assertions. + // - green: Passed [both/all] N tests cases with M assertions. + + std::string bothOrAll( std::size_t count ) const { + return count == 1 ? std::string() : count == 2 ? "both " : "all " ; + } + + void printTotals( const Totals& totals ) const { + if( totals.testCases.total() == 0 ) { + stream << "No tests ran."; + } + else if( totals.testCases.failed == totals.testCases.total() ) { + Colour colour( Colour::ResultError ); + const std::string qualify_assertions_failed = + totals.assertions.failed == totals.assertions.total() ? + bothOrAll( totals.assertions.failed ) : std::string(); + stream << + "Failed " << bothOrAll( totals.testCases.failed ) + << pluralise( totals.testCases.failed, "test case" ) << ", " + "failed " << qualify_assertions_failed << + pluralise( totals.assertions.failed, "assertion" ) << '.'; + } + else if( totals.assertions.total() == 0 ) { + stream << + "Passed " << bothOrAll( totals.testCases.total() ) + << pluralise( totals.testCases.total(), "test case" ) + << " (no assertions)."; + } + else if( totals.assertions.failed ) { + Colour colour( Colour::ResultError ); + stream << + "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", " + "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.'; + } + else { + Colour colour( Colour::ResultSuccess ); + stream << + "Passed " << bothOrAll( totals.testCases.passed ) + << pluralise( totals.testCases.passed, "test case" ) << + " with " << pluralise( totals.assertions.passed, "assertion" ) << '.'; + } + } + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter ) + +} // end namespace Catch + +namespace Catch { + // These are all here to avoid warnings about not having any out of line + // virtual methods + NonCopyable::~NonCopyable() {} + IShared::~IShared() {} + IStream::~IStream() CATCH_NOEXCEPT {} + FileStream::~FileStream() CATCH_NOEXCEPT {} + CoutStream::~CoutStream() CATCH_NOEXCEPT {} + DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {} + StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} + IContext::~IContext() {} + IResultCapture::~IResultCapture() {} + ITestCase::~ITestCase() {} + ITestCaseRegistry::~ITestCaseRegistry() {} + IRegistryHub::~IRegistryHub() {} + IMutableRegistryHub::~IMutableRegistryHub() {} + IExceptionTranslator::~IExceptionTranslator() {} + IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} + IReporter::~IReporter() {} + IReporterFactory::~IReporterFactory() {} + IReporterRegistry::~IReporterRegistry() {} + IStreamingReporter::~IStreamingReporter() {} + AssertionStats::~AssertionStats() {} + SectionStats::~SectionStats() {} + TestCaseStats::~TestCaseStats() {} + TestGroupStats::~TestGroupStats() {} + TestRunStats::~TestRunStats() {} + CumulativeReporterBase::SectionNode::~SectionNode() {} + CumulativeReporterBase::~CumulativeReporterBase() {} + + StreamingReporterBase::~StreamingReporterBase() {} + ConsoleReporter::~ConsoleReporter() {} + CompactReporter::~CompactReporter() {} + IRunner::~IRunner() {} + IMutableContext::~IMutableContext() {} + IConfig::~IConfig() {} + XmlReporter::~XmlReporter() {} + JunitReporter::~JunitReporter() {} + TestRegistry::~TestRegistry() {} + FreeFunctionTestCase::~FreeFunctionTestCase() {} + IGeneratorInfo::~IGeneratorInfo() {} + IGeneratorsForTest::~IGeneratorsForTest() {} + WildcardPattern::~WildcardPattern() {} + TestSpec::Pattern::~Pattern() {} + TestSpec::NamePattern::~NamePattern() {} + TestSpec::TagPattern::~TagPattern() {} + TestSpec::ExcludedPattern::~ExcludedPattern() {} + + void Config::dummy() {} + + namespace TestCaseTracking { + ITracker::~ITracker() {} + TrackerBase::~TrackerBase() {} + SectionTracker::~SectionTracker() {} + IndexTracker::~IndexTracker() {} + } +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif + +#ifdef CATCH_CONFIG_MAIN +// #included from: internal/catch_default_main.hpp +#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED + +#ifndef __OBJC__ + +// Standard C/C++ main entry point +int main (int argc, char * argv[]) { + int result = Catch::Session().run( argc, argv ); + return ( result < 0xff ? result : 0xff ); +} + +#else // __OBJC__ + +// Objective-C entry point +int main (int argc, char * const argv[]) { +#if !CATCH_ARC_ENABLED + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +#endif + + Catch::registerTestMethods(); + int result = Catch::Session().run( argc, (char* const*)argv ); + +#if !CATCH_ARC_ENABLED + [pool drain]; +#endif + + return ( result < 0xff ? result : 0xff ); +} + +#endif // __OBJC__ + +#endif + +#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED +# undef CLARA_CONFIG_MAIN +#endif + +////// + +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" ) +#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" ) + +#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" ) +#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" ) +#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" ) +#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" ) + +#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" ) +#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" ) +#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" ) +#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" ) +#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" ) + +#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CATCH_CHECK_THROWS" ) +#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" ) +#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" ) +#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" ) + +#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) +#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) + +#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) +#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg ) +#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) +#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) +#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) + #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) + #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) + #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) + #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) + #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) + #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ ) +#else + #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) + #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) + #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) + #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description ) + #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) + #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg ) + #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg ) +#endif +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) + +#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) +#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) + +#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) + +// "BDD-style" convenience wrappers +#ifdef CATCH_CONFIG_VARIADIC_MACROS +#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#else +#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) +#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) +#endif +#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" ) +#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" ) +#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) +#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" ) +#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" ) +#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" ) + +#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" ) +#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" ) +#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" ) +#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" ) + +#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" ) +#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" ) +#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" ) +#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" ) +#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" ) + +#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" ) +#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" ) +#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" ) +#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" ) + +#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) +#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) + +#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) +#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg ) +#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) +#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) +#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) + #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) + #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) + #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) + #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) + #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ ) + #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ ) +#else + #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) + #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) + #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) + #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description ) + #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) + #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg ) + #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg ) +#endif +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) + +#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) +#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) + +#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) + +#endif + +#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) + +// "BDD-style" convenience wrappers +#ifdef CATCH_CONFIG_VARIADIC_MACROS +#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#else +#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) +#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) +#endif +#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" ) +#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" ) +#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" ) +#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" ) +#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" ) + +using Catch::Detail::Approx; + +#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED + diff --git a/libraries/Lora_Serialization/test/main.cpp b/libraries/Lora_Serialization/test/main.cpp new file mode 100644 index 0000000..74a17f8 --- /dev/null +++ b/libraries/Lora_Serialization/test/main.cpp @@ -0,0 +1,6 @@ +#include "main.h" + +#include "helpers.cpp" +#include "../src/LoraEncoder.cpp" +#include "../src/LoraMessage.cpp" +#include "test.cpp" diff --git a/libraries/Lora_Serialization/test/main.h b/libraries/Lora_Serialization/test/main.h new file mode 100644 index 0000000..46281f2 --- /dev/null +++ b/libraries/Lora_Serialization/test/main.h @@ -0,0 +1,6 @@ +#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file +#include "lib/Catch/single_include/catch.hpp" +#ifndef Arduino_h + #include + typedef uint8_t byte; +#endif diff --git a/libraries/Lora_Serialization/test/roundtrip/latLng.js b/libraries/Lora_Serialization/test/roundtrip/latLng.js new file mode 100644 index 0000000..aa3e1c4 --- /dev/null +++ b/libraries/Lora_Serialization/test/roundtrip/latLng.js @@ -0,0 +1,44 @@ +import test from 'ava'; +import { decoder, encoder } from '../../src'; + +test('with a positive latLng', t => { + const latLng = [90, 180]; + const buf = encoder.encode([latLng], [encoder.latLng]); + const back = decoder.decode(buf, [decoder.latLng])[0]; + t.deepEqual(back, latLng); + t.pass(); +}); + +test('with a negative latLng', t => { + const latLng = [-90, -180]; + const buf = encoder.encode([latLng], [encoder.latLng]); + const back = decoder.decode(buf, [decoder.latLng])[0]; + t.deepEqual(back, latLng); + t.pass(); +}); + +function fixTuple(tuple, precision) { + return tuple.map(t => +Number(t).toFixed(precision)); +} + +test('with a latitude range', t => { + for(var lat = -90; lat < 90; lat+=0.01) { + const latLng = [lat, 0]; + const buf = encoder.encode([latLng], [encoder.latLng]); + const back = decoder.decode(buf, [decoder.latLng])[0]; + t.deepEqual(fixTuple(back, 2), fixTuple(latLng, 2)); + } + + t.pass(); +}); + +test('with a longitude range', t => { + for(var long = -180; long < 180; long+=0.01) { + const latLng = [0, long]; + const buf = encoder.encode([latLng], [encoder.latLng]); + const back = decoder.decode(buf, [decoder.latLng])[0]; + t.deepEqual(fixTuple(back, 2), fixTuple(latLng, 2)); + } + + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/roundtrip/temperature.js b/libraries/Lora_Serialization/test/roundtrip/temperature.js new file mode 100644 index 0000000..df58244 --- /dev/null +++ b/libraries/Lora_Serialization/test/roundtrip/temperature.js @@ -0,0 +1,19 @@ +import test from 'ava'; +import { decoder, encoder } from '../../src'; + +test('with 0.01', t => { + const buf = encoder.encode([0.01], [encoder.temperature]); + const back = decoder.decode(buf, [decoder.temperature])[0]; + t.is(back, 0.01); + t.pass(); +}); + +test('with all temperatures', t => { + for (let temperature = -327.6; temperature < 327.6; temperature += 0.1) { + temperature = +temperature.toFixed(1); + const buf = encoder.encode([temperature], [encoder.temperature]); + const back = decoder.decode(buf, [decoder.temperature])[0]; + t.is(back.toFixed(1), temperature.toFixed(1)); + } + t.pass(); +}); diff --git a/libraries/Lora_Serialization/test/test.cpp b/libraries/Lora_Serialization/test/test.cpp new file mode 100644 index 0000000..7cb111b --- /dev/null +++ b/libraries/Lora_Serialization/test/test.cpp @@ -0,0 +1,196 @@ +TEST_CASE( "LoRa Serialization", "[LoRa]" ) { + + SECTION( "should transform a simple unixtime to a byte array" ) { + byte x[4]; + LoraEncoder encoder(x); + encoder.writeUnixtime(1); + byte expected[] = {1, 0, 0, 0}; + compare_array(expected, x, 0, sizeof(expected)); + } + + SECTION( "should transform a given unixtime to a byte array" ) { + uint32_t now = 1467632413; + byte x[4]; + LoraEncoder encoder(x); + byte expected[] = {0x1d, 0x4b, 0x7a, 0x57}; + + encoder.writeUnixtime(now); + compare_array(expected, x, 0, sizeof(expected)); + } + + SECTION( "latLngToBytes should transform a coordinate to a byte array" ) { + byte x[8]; + LoraEncoder encoder(x); + byte expected[] = {0x64, 0xa6, 0xfa, 0xfd, 0x6a, 0x24, 0x04, 0x09}; + + encoder.writeLatLng(-33.905052, 151.26641); + compare_array(expected, x, 0, sizeof(expected)); + } + + SECTION( "uint8ToBytes should transform an unsigned 8bit int to a byte array" ) { + byte x[1]; + LoraEncoder encoder(x); + byte expected[] = {0x0A}; + + encoder.writeUint8(10); + compare_array(expected, x, 0, sizeof(expected)); + } + + SECTION( "uint16ToBytes should transform an unsigned 16bit int to a byte array" ) { + byte x[2]; + LoraEncoder encoder(x); + byte expected[] = {0x9d, 0x5b}; + + encoder.writeUint16(23453); + compare_array(expected, x, 0, sizeof(expected)); + } + + SECTION( "tempToBytes should transform a temperature to a byte array" ) { + byte x[2]; + LoraEncoder encoder(x); + byte expected[] = {0x1f, 0x4c}; + + encoder.writeTemperature(80.12); + compare_array(expected, x, 0, sizeof(expected)); + } + + SECTION( "tempToBytes should transform a negative temperature to a byte array" ) { + byte x[2]; + LoraEncoder encoder(x); + byte expected[] = {0xcf, 0xc7}; + + encoder.writeTemperature(-123.45); + compare_array(expected, x, 0, sizeof(expected)); + } + + SECTION( "humidityToBytes should transform a humidity to a byte array" ) { + byte x[2]; + LoraEncoder encoder(x); + byte expected[] = {0x0f, 0x27}; + + encoder.writeHumidity(99.99); + compare_array(expected, x, 0, sizeof(expected)); + } + + SECTION( "write multiple fields to one byte array" ) { + byte x[19]; + LoraEncoder encoder(x); + byte expected[] = { + 0x1d, 0x4b, 0x7a, 0x57, // Unixtime + 0x64, 0xa6, 0xfa, 0xfd, 0x6a, 0x24, 0x04, 0x09, // coordinate + 0x0A, // Uint8 + 0x9d, 0x5b, // Uint16 + 0x1f, 0x4c, // temperature + 0x0f, 0x27 // humidity + }; + + encoder.writeUnixtime(1467632413); + encoder.writeLatLng(-33.905052, 151.26641); + encoder.writeUint8(10); + encoder.writeUint16(23453); + encoder.writeTemperature(80.12); + encoder.writeHumidity(99.99); + + compare_array(expected, x, 0, sizeof(expected)); + } +} + +TEST_CASE( "LoRa Message", "[LoRa]" ) { + SECTION( "should provide a convenient way to add unixtime" ) { + uint32_t now = 1467632413; + byte expected[] = {0x1d, 0x4b, 0x7a, 0x57}; + LoraMessage message; + + message.addUnixtime(now); + + REQUIRE(message.getLength() == sizeof(expected)); + compare_array(expected, message.getBytes(), 0, sizeof(expected)); + } + + SECTION( "should provide a convenient way to add latLng" ) { + byte expected[] = {0x64, 0xa6, 0xfa, 0xfd, 0x6a, 0x24, 0x04, 0x09}; + LoraMessage message; + + message.addLatLng(-33.905052, 151.26641); + + REQUIRE(message.getLength() == sizeof(expected)); + compare_array(expected, message.getBytes(), 0, sizeof(expected)); + } + + SECTION( "should provide a convenient way to add an unsigned 8bit int" ) { + byte expected[] = {0x0A}; + LoraMessage message; + + message.addUint8(10); + + REQUIRE(message.getLength() == sizeof(expected)); + compare_array(expected, message.getBytes(), 0, sizeof(expected)); + } + + SECTION( "should provide a convenient way to add an unsigned 16bit int" ) { + byte expected[] = {0x9d, 0x5b}; + LoraMessage message; + + message.addUint16(23453); + + REQUIRE(message.getLength() == sizeof(expected)); + compare_array(expected, message.getBytes(), 0, sizeof(expected)); + } + + SECTION( "should provide a convenient way to add a temperature" ) { + byte expected[] = {0x1f, 0x4c}; + LoraMessage message; + + message.addTemperature(80.12); + + REQUIRE(message.getLength() == sizeof(expected)); + compare_array(expected, message.getBytes(), 0, sizeof(expected)); + } + + SECTION( "should provide a convenient way to add a humidity" ) { + byte expected[] = {0x0f, 0x27}; + LoraMessage message; + + message.addHumidity(99.99); + + REQUIRE(message.getLength() == sizeof(expected)); + compare_array(expected, message.getBytes(), 0, sizeof(expected)); + } + + SECTION( "should provide a convenient way to add a bitmap" ) { + byte expected[] = {0x80}; + LoraMessage message; + + message.addBitmap(true, false, false, false, false, false, false, false); + + REQUIRE(message.getLength() == sizeof(expected)); + compare_array(expected, message.getBytes(), 0, sizeof(expected)); + } + + SECTION( "should allow chaining" ) { + byte expected[] = { + 0x1d, 0x4b, 0x7a, 0x57, // Unixtime + 0x64, 0xa6, 0xfa, 0xfd, 0x6a, 0x24, 0x04, 0x09, // coordinate + 0x0A, // Uint8 + 0x9d, 0x5b, // Uint16 + 0x1f, 0x4c, // temperature + 0x0f, 0x27, // humidity + 0x1e, 0x4b, 0x7a, 0x57, // Unixtime, + 0xfd // Bitmap + }; + LoraMessage message; + + message + .addUnixtime(1467632413) + .addLatLng(-33.905052, 151.26641) + .addUint8(10) + .addUint16(23453) + .addTemperature(80.12) + .addHumidity(99.99) + .addUnixtime(1467632414) + .addBitmap(true, true, true, true, true, true, false, true); + + REQUIRE(message.getLength() == sizeof(expected)); + compare_array(expected, message.getBytes(), 0, sizeof(expected)); + } +} diff --git a/libraries/Lora_Serialization/yarn.lock b/libraries/Lora_Serialization/yarn.lock new file mode 100644 index 0000000..262661f --- /dev/null +++ b/libraries/Lora_Serialization/yarn.lock @@ -0,0 +1,4269 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ava/babel-preset-stage-4@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.0.0.tgz#a613b5e152f529305422546b072d47facfb26291" + dependencies: + babel-plugin-check-es2015-constants "^6.8.0" + babel-plugin-syntax-trailing-function-commas "^6.20.0" + babel-plugin-transform-async-to-generator "^6.16.0" + babel-plugin-transform-es2015-destructuring "^6.19.0" + babel-plugin-transform-es2015-function-name "^6.9.0" + babel-plugin-transform-es2015-modules-commonjs "^6.18.0" + babel-plugin-transform-es2015-parameters "^6.21.0" + babel-plugin-transform-es2015-spread "^6.8.0" + babel-plugin-transform-es2015-sticky-regex "^6.8.0" + babel-plugin-transform-es2015-unicode-regex "^6.11.0" + babel-plugin-transform-exponentiation-operator "^6.8.0" + package-hash "^1.2.0" + +"@ava/babel-preset-transform-test-files@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-2.0.1.tgz#d75232cc6d71dc9c7eae4b76a9004fd81501d0c1" + dependencies: + babel-plugin-ava-throws-helper "^1.0.0" + babel-plugin-espower "^2.3.2" + package-hash "^1.2.0" + +"@ava/pretty-format@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@ava/pretty-format/-/pretty-format-1.1.0.tgz#d0a57d25eb9aeab9643bdd1a030642b91c123e28" + dependencies: + ansi-styles "^2.2.1" + esutils "^2.0.2" + +"@semantic-release/commit-analyzer@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-2.0.0.tgz#924d1e2c30167c6a472bed9f66ee8f8e077489b2" + dependencies: + conventional-changelog "0.0.17" + +"@semantic-release/condition-travis@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@semantic-release/condition-travis/-/condition-travis-5.0.2.tgz#f4bb777a6c6db5565d70754a9b629233bd4a6597" + dependencies: + "@semantic-release/error" "^1.0.0" + semver "^5.0.3" + travis-deploy-once "1.0.0-node-0.10-support" + +"@semantic-release/error@^1.0.0": + version "1.0.0" + resolved "http://registry.npmjs.org/@semantic-release/error/-/error-1.0.0.tgz#bb8f8eeedd5c7f8c46f96b37ef39e1b8c376c1cc" + +"@semantic-release/last-release-npm@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@semantic-release/last-release-npm/-/last-release-npm-1.2.1.tgz#ff748142ecf15354b833a86ba18205f7fce594ee" + dependencies: + "@semantic-release/error" "^1.0.0" + npm-registry-client "^7.0.1" + npmlog "^1.2.1" + +"@semantic-release/release-notes-generator@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-2.0.0.tgz#7c5da65689466d536a53fdfa9f4d62a3bd13c16e" + dependencies: + conventional-changelog "0.0.17" + github-url-from-git "^1.4.0" + +abbrev@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.4.tgz#17a8d6a7a6c4ef538b814ec9abac2779293bf30a" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +agent-base@2: + version "2.0.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.0.1.tgz#bd8f9e86a8eb221fffa07bd14befd55df142815e" + dependencies: + extend "~3.0.0" + semver "~5.0.1" + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.7.0: + version "4.11.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.3.tgz#ce30bdb90d1254f762c75af915fb3a63e7183d22" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-align@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-1.1.0.tgz#2f0c1658829739add5ebb15e6b0c6e3423f016ba" + dependencies: + string-width "^1.0.1" + +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + +ansi@^0.3.0, ansi@~0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" + +anymatch@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" + dependencies: + arrify "^1.0.0" + micromatch "^2.1.5" + +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + dependencies: + default-require-extensions "^1.0.0" + +aproba@^1.0.3: + version "1.1.1" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + +are-we-there-yet@~1.0.0: + version "1.0.6" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz#a2d28c93102aa6cc96245a26cb954de06ec53f0c" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.0 || ^1.1.13" + +are-we-there-yet@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.0 || ^1.1.13" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-exclude@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/arr-exclude/-/arr-exclude-1.0.0.tgz#dfc7c2e552a270723ccda04cf3128c8cbfe5c631" + +arr-flatten@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asap@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assertion-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async@^1.4.0, async@^1.4.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@^2.0.1: + version "2.1.5" + resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" + dependencies: + lodash "^4.14.0" + +async@~0.2.6: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +auto-bind@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-1.1.0.tgz#93b864dc7ee01a326281775d5c75ca0a751e5961" + +ava-init@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ava-init/-/ava-init-0.2.0.tgz#9304c8b4c357d66e3dfdae1fbff47b1199d5c55d" + dependencies: + arr-exclude "^1.0.0" + execa "^0.5.0" + has-yarn "^1.0.0" + read-pkg-up "^2.0.0" + write-pkg "^2.0.0" + +ava@^0.18.2: + version "0.18.2" + resolved "https://registry.yarnpkg.com/ava/-/ava-0.18.2.tgz#79253d1636077034a2780bb55b5c3e6c3d7f312f" + dependencies: + "@ava/babel-preset-stage-4" "^1.0.0" + "@ava/babel-preset-transform-test-files" "^2.0.0" + "@ava/pretty-format" "^1.1.0" + arr-flatten "^1.0.1" + array-union "^1.0.1" + array-uniq "^1.0.2" + arrify "^1.0.0" + auto-bind "^1.1.0" + ava-init "^0.2.0" + babel-code-frame "^6.16.0" + babel-core "^6.17.0" + bluebird "^3.0.0" + caching-transform "^1.0.0" + chalk "^1.0.0" + chokidar "^1.4.2" + clean-stack "^1.1.1" + clean-yaml-object "^0.1.0" + cli-cursor "^2.1.0" + cli-spinners "^1.0.0" + cli-truncate "^0.2.0" + co-with-promise "^4.6.0" + code-excerpt "^2.1.0" + common-path-prefix "^1.0.0" + convert-source-map "^1.2.0" + core-assert "^0.2.0" + currently-unhandled "^0.4.1" + debug "^2.2.0" + diff "^3.0.1" + dot-prop "^4.1.0" + empower-core "^0.6.1" + equal-length "^1.0.0" + figures "^2.0.0" + find-cache-dir "^0.1.1" + fn-name "^2.0.0" + get-port "^2.1.0" + globby "^6.0.0" + has-flag "^2.0.0" + ignore-by-default "^1.0.0" + indent-string "^3.0.0" + is-ci "^1.0.7" + is-generator-fn "^1.0.0" + is-obj "^1.0.0" + is-observable "^0.2.0" + is-promise "^2.1.0" + jest-snapshot "^18.1.0" + last-line-stream "^1.0.0" + lodash.debounce "^4.0.3" + lodash.difference "^4.3.0" + lodash.flatten "^4.2.0" + lodash.isequal "^4.5.0" + loud-rejection "^1.2.0" + matcher "^0.1.1" + max-timeout "^1.0.0" + md5-hex "^2.0.0" + meow "^3.7.0" + ms "^0.7.1" + multimatch "^2.1.0" + observable-to-promise "^0.4.0" + option-chain "^0.1.0" + package-hash "^1.2.0" + pkg-conf "^2.0.0" + plur "^2.0.0" + pretty-ms "^2.0.0" + require-precompiled "^0.1.0" + resolve-cwd "^1.0.0" + slash "^1.0.0" + source-map-support "^0.4.0" + stack-utils "^1.0.0" + strip-ansi "^3.0.1" + strip-bom-buf "^1.0.0" + time-require "^0.1.2" + unique-temp-dir "^1.0.0" + update-notifier "^1.0.0" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +babel-core@^6.17.0, babel-core@^6.23.0: + version "6.23.1" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.23.1.tgz#c143cb621bb2f621710c220c5d579d15b8a442df" + dependencies: + babel-code-frame "^6.22.0" + babel-generator "^6.23.0" + babel-helpers "^6.23.0" + babel-messages "^6.23.0" + babel-register "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-traverse "^6.23.1" + babel-types "^6.23.0" + babylon "^6.11.0" + convert-source-map "^1.1.0" + debug "^2.1.1" + json5 "^0.5.0" + lodash "^4.2.0" + minimatch "^3.0.2" + path-is-absolute "^1.0.0" + private "^0.1.6" + slash "^1.0.0" + source-map "^0.5.0" + +babel-generator@^6.1.0, babel-generator@^6.18.0, babel-generator@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.23.0.tgz#6b8edab956ef3116f79d8c84c5a3c05f32a74bc5" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.23.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.2.0" + source-map "^0.5.0" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.22.0.tgz#29df56be144d81bdeac08262bfa41d2c5e91cdcd" + dependencies: + babel-helper-explode-assignable-expression "^6.22.0" + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-helper-call-delegate@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.22.0.tgz#119921b56120f17e9dae3f74b4f5cc7bcc1b37ef" + dependencies: + babel-helper-hoist-variables "^6.22.0" + babel-runtime "^6.22.0" + babel-traverse "^6.22.0" + babel-types "^6.22.0" + +babel-helper-explode-assignable-expression@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.22.0.tgz#c97bf76eed3e0bae4048121f2b9dae1a4e7d0478" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.22.0" + babel-types "^6.22.0" + +babel-helper-function-name@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.23.0.tgz#25742d67175c8903dbe4b6cb9d9e1fcb8dcf23a6" + dependencies: + babel-helper-get-function-arity "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-traverse "^6.23.0" + babel-types "^6.23.0" + +babel-helper-get-function-arity@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.22.0.tgz#0beb464ad69dc7347410ac6ade9f03a50634f5ce" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-helper-hoist-variables@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.22.0.tgz#3eacbf731d80705845dd2e9718f600cfb9b4ba72" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-helper-regex@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.22.0.tgz#79f532be1647b1f0ee3474b5f5c3da58001d247d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.22.0" + lodash "^4.2.0" + +babel-helper-remap-async-to-generator@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.22.0.tgz#2186ae73278ed03b8b15ced089609da981053383" + dependencies: + babel-helper-function-name "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.22.0" + babel-traverse "^6.22.0" + babel-types "^6.22.0" + +babel-helpers@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.23.0.tgz#4f8f2e092d0b6a8808a4bde79c27f1e2ecf0d992" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.23.0" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-ava-throws-helper@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-ava-throws-helper/-/babel-plugin-ava-throws-helper-1.0.0.tgz#8fe6e79d2fd19838b5c3649f89cfb03fd563e241" + dependencies: + babel-template "^6.7.0" + babel-types "^6.7.2" + +babel-plugin-check-es2015-constants@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-espower@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/babel-plugin-espower/-/babel-plugin-espower-2.3.2.tgz#5516b8fcdb26c9f0e1d8160749f6e4c65e71271e" + dependencies: + babel-generator "^6.1.0" + babylon "^6.1.0" + call-matcher "^1.0.0" + core-js "^2.0.0" + espower-location-detector "^1.0.0" + espurify "^1.6.0" + estraverse "^4.1.1" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-trailing-function-commas@^6.20.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-to-generator@^6.16.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.22.0.tgz#194b6938ec195ad36efc4c33a971acf00d8cd35e" + dependencies: + babel-helper-remap-async-to-generator "^6.22.0" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-destructuring@^6.19.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.9.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.22.0.tgz#f5fcc8b09093f9a23c76ac3d9e392c3ec4b77104" + dependencies: + babel-helper-function-name "^6.22.0" + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-plugin-transform-es2015-modules-commonjs@^6.18.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.23.0.tgz#cba7aa6379fb7ec99250e6d46de2973aaffa7b92" + dependencies: + babel-plugin-transform-strict-mode "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-types "^6.23.0" + +babel-plugin-transform-es2015-parameters@^6.21.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.23.0.tgz#3a2aabb70c8af945d5ce386f1a4250625a83ae3b" + dependencies: + babel-helper-call-delegate "^6.22.0" + babel-helper-get-function-arity "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-traverse "^6.23.0" + babel-types "^6.23.0" + +babel-plugin-transform-es2015-spread@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.22.0.tgz#ab316829e866ee3f4b9eb96939757d19a5bc4593" + dependencies: + babel-helper-regex "^6.22.0" + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.11.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.22.0.tgz#8d9cc27e7ee1decfe65454fb986452a04a613d20" + dependencies: + babel-helper-regex "^6.22.0" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.22.0.tgz#d57c8335281918e54ef053118ce6eb108468084d" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.22.0" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-strict-mode@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.22.0.tgz#e008df01340fdc87e959da65991b7e05970c8c7c" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-polyfill@^6.16.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" + dependencies: + babel-runtime "^6.22.0" + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-register@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.23.0.tgz#c9aa3d4cca94b51da34826c4a0f9e08145d74ff3" + dependencies: + babel-core "^6.23.0" + babel-runtime "^6.22.0" + core-js "^2.4.0" + home-or-tmp "^2.0.0" + lodash "^4.2.0" + mkdirp "^0.5.1" + source-map-support "^0.4.2" + +babel-runtime@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0, babel-template@^6.7.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.23.0.tgz#04d4f270adbb3aa704a8143ae26faa529238e638" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.23.0" + babel-types "^6.23.0" + babylon "^6.11.0" + lodash "^4.2.0" + +babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1: + version "6.23.1" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.23.1.tgz#d3cb59010ecd06a97d81310065f966b699e14f48" + dependencies: + babel-code-frame "^6.22.0" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.23.0" + babylon "^6.15.0" + debug "^2.2.0" + globals "^9.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +babel-types@^6.18.0, babel-types@^6.22.0, babel-types@^6.23.0, babel-types@^6.7.2: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.23.0.tgz#bb17179d7538bad38cd0c9e115d340f77e7e9acf" + dependencies: + babel-runtime "^6.22.0" + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^1.0.1" + +babylon@^6.1.0, babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0: + version "6.16.1" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3" + +balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +binary-extensions@^1.0.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" + +bl@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" + dependencies: + readable-stream "~2.0.5" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^3.0.0, bluebird@^3.4.1, bluebird@^3.4.6: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +boxen@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-0.6.0.tgz#8364d4248ac34ff0ef1b2f2bf49a6c60ce0d81b6" + dependencies: + ansi-align "^1.1.0" + camelcase "^2.1.0" + chalk "^1.1.1" + cli-boxes "^1.0.0" + filled-array "^1.0.0" + object-assign "^4.0.1" + repeating "^2.0.0" + string-width "^1.0.1" + widest-line "^1.0.0" + +brace-expansion@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +buf-compare@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +caching-transform@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" + dependencies: + md5-hex "^1.2.0" + mkdirp "^0.5.1" + write-file-atomic "^1.1.4" + +call-matcher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.0.1.tgz#5134d077984f712a54dad3cbf62de28dce416ca8" + dependencies: + core-js "^2.0.0" + deep-equal "^1.0.0" + espurify "^1.6.0" + estraverse "^4.0.0" + +call-signature@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^2.0.0, camelcase@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + +capture-stack-trace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chai@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" + dependencies: + assertion-error "^1.0.1" + deep-eql "^0.1.3" + type-detect "^1.0.0" + +chalk@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + +chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chokidar@^1.4.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +ci-info@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534" + +circular-json@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" + +clean-stack@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.1.1.tgz#a1b3711122df162df7c7cb9b3c0470f28cb58adb" + +clean-yaml-object@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz#63fb110dc2ce1a84dc21f6d9334876d010ae8b68" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-spinners@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.0.0.tgz#ef987ed3d48391ac3dab9180b406a742180d6e6a" + +cli-truncate@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + +cli-width@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + +clone@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" + +co-with-promise@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co-with-promise/-/co-with-promise-4.6.0.tgz#413e7db6f5893a60b942cf492c4bec93db415ab7" + dependencies: + pinkie-promise "^1.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-excerpt@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/code-excerpt/-/code-excerpt-2.1.0.tgz#5dcc081e88f4a7e3b554e9e35d7ef232d47f8147" + dependencies: + convert-to-spaces "^1.0.1" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +common-path-prefix@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-1.0.0.tgz#cd52f6f0712e0baab97d6f9732874f22f47752c0" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.4.6, concat-stream@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +config-chain@~1.1.8: + version "1.1.11" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.11.tgz#aba09747dfbe4c3e70e766a6e41586e1859fc6f2" + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +configstore@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1" + dependencies: + dot-prop "^3.0.0" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + object-assign "^4.0.1" + os-tmpdir "^1.0.0" + osenv "^0.1.0" + uuid "^2.0.1" + write-file-atomic "^1.1.2" + xdg-basedir "^2.0.0" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +conventional-changelog@0.0.17: + version "0.0.17" + resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-0.0.17.tgz#5e0216600f4686190f0c82efbb0b3dd11b49ce34" + dependencies: + dateformat "^1.0.11" + event-stream "^3.3.0" + github-url-from-git "^1.4.0" + lodash "^3.6.0" + normalize-package-data "^1.0.3" + +conventional-commit-types@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/conventional-commit-types/-/conventional-commit-types-2.1.0.tgz#45d860386c9a2e6537ee91d8a1b61bd0411b3d04" + +convert-source-map@^1.1.0, convert-source-map@^1.1.1, convert-source-map@^1.2.0, convert-source-map@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.4.0.tgz#e3dad195bf61bfe13a7a3c73e9876ec14a0268f3" + +convert-to-spaces@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz#7e3e48bbe6d997b1417ddca2868204b4d3d85715" + +core-assert@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/core-assert/-/core-assert-0.2.1.tgz#f85e2cf9bfed28f773cc8b3fa5c5b69bdc02fe3f" + dependencies: + buf-compare "^1.0.0" + is-error "^2.2.0" + +core-js@^2.0.0, core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +core-util-is@^1.0.1, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +coveralls@^2.11.16: + version "2.11.16" + resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-2.11.16.tgz#da9061265142ddee954f68379122be97be8ab4b1" + dependencies: + js-yaml "3.6.1" + lcov-parse "0.0.10" + log-driver "1.2.5" + minimist "1.2.0" + request "2.79.0" + +create-error-class@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + +cross-spawn@^4, cross-spawn@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + +cz-conventional-changelog@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cz-conventional-changelog/-/cz-conventional-changelog-2.0.0.tgz#55a979afdfe95e7024879d2a0f5924630170b533" + dependencies: + conventional-commit-types "^2.0.0" + lodash.map "^4.5.1" + longest "^1.0.1" + pad-right "^0.2.2" + right-pad "^1.0.1" + word-wrap "^1.0.3" + +d@^0.1.1, d@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309" + dependencies: + es5-ext "~0.10.2" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +date-time@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/date-time/-/date-time-0.1.1.tgz#ed2f6d93d9790ce2fd66d5b5ff3edd5bbcbf3b07" + +dateformat@^1.0.11: + version "1.0.12" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + dependencies: + get-stdin "^4.0.1" + meow "^3.3.0" + +debug-log@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + +debug@2, debug@^2.1.1, debug@^2.2.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351" + dependencies: + ms "0.7.2" + +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-eql@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + dependencies: + type-detect "0.1.1" + +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + +deep-extend@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + dependencies: + strip-bom "^2.0.0" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +dezalgo@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" + dependencies: + asap "^2.0.0" + wrappy "1" + +diff@^3.0.0, diff@^3.0.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + +doctrine@^1.2.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + dependencies: + is-obj "^1.0.0" + +dot-prop@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.1.1.tgz#a8493f0b7b5eeec82525b5c7587fa7de7ca859c1" + dependencies: + is-obj "^1.0.0" + +duplexer2@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + dependencies: + readable-stream "^2.0.2" + +duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + +duplexify@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.0.tgz#1aa773002e1578457e9d9d4a50b0ccaaebcbd604" + dependencies: + end-of-stream "1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +empower-core@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.6.1.tgz#6c187f502fcef7554d57933396aac655483772b1" + dependencies: + call-signature "0.0.2" + core-js "^2.0.0" + +end-of-stream@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.0.0.tgz#d4596e702734a93e40e9af864319eabd99ff2f0e" + dependencies: + once "~1.3.0" + +equal-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +es5-ext@^0.10.7, es5-ext@^0.10.8, es5-ext@~0.10.11, es5-ext@~0.10.2, es5-ext@~0.10.7: + version "0.10.12" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047" + dependencies: + es6-iterator "2" + es6-symbol "~3.1" + +es6-iterator@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.0.tgz#bd968567d61635e33c0b80727613c9cb4b096bac" + dependencies: + d "^0.1.1" + es5-ext "^0.10.7" + es6-symbol "3" + +es6-map@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.4.tgz#a34b147be224773a4d7da8072794cefa3632b897" + dependencies: + d "~0.1.1" + es5-ext "~0.10.11" + es6-iterator "2" + es6-set "~0.1.3" + es6-symbol "~3.1.0" + event-emitter "~0.3.4" + +es6-set@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.4.tgz#9516b6761c2964b92ff479456233a247dc707ce8" + dependencies: + d "~0.1.1" + es5-ext "~0.10.11" + es6-iterator "2" + es6-symbol "3" + event-emitter "~0.3.4" + +es6-symbol@3, es6-symbol@~3.1, es6-symbol@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa" + dependencies: + d "~0.1.1" + es5-ext "~0.10.11" + +es6-weak-map@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.1.tgz#0d2bbd8827eb5fb4ba8f97fbfea50d43db21ea81" + dependencies: + d "^0.1.1" + es5-ext "^0.10.8" + es6-iterator "2" + es6-symbol "3" + +escape-string-regexp@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + +escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint@^3.0.1: + version "3.17.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.17.0.tgz#e2704b09c5bae9fb49ee8bafeea3832c7257d498" + dependencies: + babel-code-frame "^6.16.0" + chalk "^1.1.3" + concat-stream "^1.4.6" + debug "^2.1.1" + doctrine "^1.2.2" + escope "^3.6.0" + espree "^3.4.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + glob "^7.0.3" + globals "^9.14.0" + ignore "^3.2.0" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.7.5" + strip-bom "^3.0.0" + strip-json-comments "~2.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espower-location-detector@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/espower-location-detector/-/espower-location-detector-1.0.0.tgz#a17b7ecc59d30e179e2bef73fb4137704cb331b5" + dependencies: + is-url "^1.2.1" + path-is-absolute "^1.0.0" + source-map "^0.5.0" + xtend "^4.0.0" + +espree@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.0.tgz#41656fa5628e042878025ef467e78f125cb86e1d" + dependencies: + acorn "4.0.4" + acorn-jsx "^3.0.0" + +esprima@^2.6.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + +espurify@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.7.0.tgz#1c5cf6cbccc32e6f639380bd4f991fab9ba9d226" + dependencies: + core-js "^2.0.0" + +esrecurse@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" + dependencies: + estraverse "~4.1.0" + object-assign "^4.0.1" + +estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +estraverse@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +event-emitter@~0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.4.tgz#8d63ddfb4cfe1fae3b32ca265c4c720222080bb5" + dependencies: + d "~0.1.1" + es5-ext "~0.10.7" + +event-stream@^3.3.0: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + +execa@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.5.1.tgz#de3fb85cb8d6e91c85bcbceb164581785cb57b36" + dependencies: + cross-spawn "^4.0.0" + get-stream "^2.2.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + +extend@3, extend@^3.0.0, extend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +filename-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +filled-array@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filled-array/-/filled-array-1.1.0.tgz#c3c4f6c663b923459a9aa29912d2d031f1507f84" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-up@^1.0.0, find-up@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +first-chunk-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + +flat-cache@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +fn-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" + +follow-redirects@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-0.0.7.tgz#34b90bab2a911aa347571da90f22bd36ecd8a919" + dependencies: + debug "^2.2.0" + stream-consume "^0.1.0" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreachasync@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/foreachasync/-/foreachasync-3.0.0.tgz#5502987dc8714be3392097f32e0071c9dee07cf6" + +foreground-child@^1.3.3, foreground-child@^1.5.3: + version "1.5.6" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" + dependencies: + cross-spawn "^4" + signal-exit "^3.0.0" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~1.0.0-rc4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c" + dependencies: + async "^2.0.1" + combined-stream "^1.0.5" + mime-types "^2.1.11" + +form-data@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +from@~0: + version "0.1.3" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.3.tgz#ef63ac2062ac32acf7862e0d40b44b896f22f3bc" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.29" + +fstream-ignore@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +gauge@~1.2.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93" + dependencies: + ansi "^0.3.0" + has-unicode "^2.0.0" + lodash.pad "^4.1.0" + lodash.padend "^4.1.0" + lodash.padstart "^4.1.0" + +gauge@~2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.3.tgz#1c23855f962f17b3ad3d0dc7443f304542edfe09" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-port@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-2.1.0.tgz#8783f9dcebd1eea495a334e1a6a251e78887ab1a" + dependencies: + pinkie-promise "^2.0.0" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +getpass@^0.1.1: + version "0.1.6" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" + dependencies: + assert-plus "^1.0.0" + +git-head@^1.2.1: + version "1.19.0" + resolved "https://registry.yarnpkg.com/git-head/-/git-head-1.19.0.tgz#35cf05be4b6cc473ff1d716d954b2ea1b3b7cc57" + dependencies: + git-refs "^1.1.3" + +git-refs@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/git-refs/-/git-refs-1.1.3.tgz#83097cb3a92585c4a4926ec54e2182df9e20e89d" + dependencies: + path-object "^2.3.0" + slash "^1.0.0" + walk "^2.3.9" + +github-url-from-git@^1.3.0, github-url-from-git@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/github-url-from-git/-/github-url-from-git-1.5.0.tgz#f985fedcc0a9aa579dc88d7aff068d55cc6251a0" + +github-url-from-username-repo@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/github-url-from-username-repo/-/github-url-from-username-repo-1.0.2.tgz#7dd79330d2abe69c10c2cef79714c97215791dfa" + +github@^8.0.0: + version "8.2.1" + resolved "https://registry.yarnpkg.com/github/-/github-8.2.1.tgz#616b2211fbcd1cc8631669aed67653e62eb53816" + dependencies: + follow-redirects "0.0.7" + https-proxy-agent "^1.0.0" + mime "^1.2.11" + netrc "^0.1.4" + +github@~0.1.10: + version "0.1.16" + resolved "https://registry.yarnpkg.com/github/-/github-0.1.16.tgz#895d2a85b0feb7980d89ac0ce4f44dcaa03f17b5" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^5.3.2: + version "5.3.5" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22" + dependencies: + extend "^3.0.0" + glob "^5.0.3" + glob-parent "^3.0.0" + micromatch "^2.3.7" + ordered-read-streams "^0.3.0" + through2 "^0.6.0" + to-absolute-glob "^0.1.1" + unique-stream "^2.0.2" + +glob@^5.0.3: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.0.0, globals@^9.14.0: + version "9.16.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.16.0.tgz#63e903658171ec2d9f51b1d31de5e2b8dc01fb80" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +got@^5.0.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35" + dependencies: + create-error-class "^3.0.1" + duplexer2 "^0.1.4" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + node-status-codes "^1.0.0" + object-assign "^4.0.1" + parse-json "^2.1.0" + pinkie-promise "^2.0.0" + read-all-stream "^3.0.0" + readable-stream "^2.0.5" + timed-out "^3.0.0" + unzip-response "^1.0.2" + url-parse-lax "^1.0.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +gulp-sourcemaps@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c" + dependencies: + convert-source-map "^1.1.1" + graceful-fs "^4.1.2" + strip-bom "^2.0.0" + through2 "^2.0.0" + vinyl "^1.0.0" + +handlebars@^4.0.3: + version "4.0.6" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.6.tgz#2ce4484850537f9c97a8026d5399b935c4ed4ed7" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-yarn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-1.0.0.tgz#89e25db604b725c8f5976fff0addc921b828a5a7" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4, hosted-git-info@^2.1.5: + version "2.2.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.2.0.tgz#7a0d097863d886c0fabbdcd37bf1758d8becf8a5" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-proxy-agent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" + dependencies: + agent-base "2" + debug "2" + extend "3" + +ignore-by-default@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + +ignore@^3.2.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.4.tgz#4055e03596729a8fabe45a43c100ad5ed815c4e8" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.1.0.tgz#08ff4334603388399b329e6b9538dc7a3cf5de7d" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@^1.2.0, ini@^1.3.4, ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +interpret@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" + +invariant@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +irregular-plurals@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.0.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-ci@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" + dependencies: + ci-info "^1.0.0" + +is-dotfile@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-error@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-extglob@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-finite@^1.0.0, is-finite@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + +is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: + version "2.16.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + +is-number@^2.0.2, is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" + dependencies: + symbol-observable "^0.2.2" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + +is-resolvable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" + dependencies: + tryit "^1.0.1" + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-url@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.2.tgz#498905a593bf47cc2d9e7f738372bbf7696c7f26" + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-valid-glob@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istanbul-lib-coverage@^1.0.0, istanbul-lib-coverage@^1.0.0-alpha, istanbul-lib-coverage@^1.0.0-alpha.0, istanbul-lib-coverage@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.0.1.tgz#f263efb519c051c5f1f3343034fc40e7b43ff212" + +istanbul-lib-hook@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.0.tgz#fc5367ee27f59268e8f060b0c7aaf051d9c425c5" + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.4.2.tgz#0e2fdfac93c1dabf2e31578637dc78a19089f43e" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.13.0" + istanbul-lib-coverage "^1.0.0" + semver "^5.3.0" + +istanbul-lib-report@^1.0.0-alpha.3: + version "1.0.0-alpha.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.0.0-alpha.3.tgz#32d5f6ec7f33ca3a602209e278b2e6ff143498af" + dependencies: + async "^1.4.2" + istanbul-lib-coverage "^1.0.0-alpha" + mkdirp "^0.5.1" + path-parse "^1.0.5" + rimraf "^2.4.3" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.1.0.tgz#9d429218f35b823560ea300a96ff0c3bbdab785f" + dependencies: + istanbul-lib-coverage "^1.0.0-alpha.0" + mkdirp "^0.5.1" + rimraf "^2.4.4" + source-map "^0.5.3" + +istanbul-reports@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.0.1.tgz#9a17176bc4a6cbebdae52b2f15961d52fa623fbc" + dependencies: + handlebars "^4.0.3" + +jest-diff@^18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-18.1.0.tgz#4ff79e74dd988c139195b365dc65d87f606f4803" + dependencies: + chalk "^1.1.3" + diff "^3.0.0" + jest-matcher-utils "^18.1.0" + pretty-format "^18.1.0" + +jest-file-exists@^17.0.0: + version "17.0.0" + resolved "https://registry.yarnpkg.com/jest-file-exists/-/jest-file-exists-17.0.0.tgz#7f63eb73a1c43a13f461be261768b45af2cdd169" + +jest-matcher-utils@^18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-18.1.0.tgz#1ac4651955ee2a60cef1e7fcc98cdfd773c0f932" + dependencies: + chalk "^1.1.3" + pretty-format "^18.1.0" + +jest-mock@^18.0.0: + version "18.0.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-18.0.0.tgz#5c248846ea33fa558b526f5312ab4a6765e489b3" + +jest-snapshot@^18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-18.1.0.tgz#55b96d2ee639c9bce76f87f2a3fd40b71c7a5916" + dependencies: + jest-diff "^18.1.0" + jest-file-exists "^17.0.0" + jest-matcher-utils "^18.1.0" + jest-util "^18.1.0" + natural-compare "^1.4.0" + pretty-format "^18.1.0" + +jest-util@^18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-18.1.0.tgz#3a99c32114ab17f84be094382527006e6d4bfc6a" + dependencies: + chalk "^1.1.1" + diff "^3.0.0" + graceful-fs "^4.1.6" + jest-file-exists "^17.0.0" + jest-mock "^18.0.0" + mkdirp "^0.5.1" + +jodid25519@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" + dependencies: + jsbn "~0.1.0" + +js-tokens@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" + +js-yaml@3.6.1, js-yaml@^3.5.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" + dependencies: + argparse "^1.0.7" + esprima "^2.6.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + +jsprim@^1.2.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252" + dependencies: + extsprintf "1.0.2" + json-schema "0.2.3" + verror "1.3.6" + +kind-of@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" + dependencies: + is-buffer "^1.0.2" + +last-line-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/last-line-stream/-/last-line-stream-1.0.0.tgz#d1b64d69f86ff24af2d04883a2ceee14520a5600" + dependencies: + through2 "^2.0.0" + +latest-version@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b" + dependencies: + package-json "^2.0.0" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lazy-req@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/lazy-req/-/lazy-req-1.1.0.tgz#bdaebead30f8d824039ce0ce149d4daa07ba1fac" + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + dependencies: + readable-stream "^2.0.5" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +lcov-parse@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" + +lcov-result-merger@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/lcov-result-merger/-/lcov-result-merger-1.2.0.tgz#5de1e6426f885929b77357f014de5fee1dad0553" + dependencies: + through2 "^2.0.1" + vinyl "^1.1.1" + vinyl-fs "^2.4.3" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + +lodash._bindcallback@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" + +lodash._createassigner@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" + dependencies: + lodash._bindcallback "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash.restparam "^3.0.0" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + +lodash.assign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" + dependencies: + lodash._baseassign "^3.0.0" + lodash._createassigner "^3.0.0" + lodash.keys "^3.0.0" + +lodash.debounce@^4.0.3: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + +lodash.difference@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" + +lodash.flatten@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.isequal@^4.0.0, lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.map@^4.5.1: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" + +lodash.pad@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" + +lodash.padend@^4.1.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" + +lodash.padstart@^4.1.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + +lodash@^3.6.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + +lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.2.0, lodash@^4.3.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +lodash@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.3.1.tgz#a4663b53686b895ff074e2ba504dfb76a8e2b770" + +log-driver@1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +loud-rejection@^1.0.0, loud-rejection@^1.2.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + +lru-cache@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + +matcher@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-0.1.2.tgz#ef20cbde64c24c50cc61af5b83ee0b1b8ff00101" + dependencies: + escape-string-regexp "^1.0.4" + +max-timeout@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/max-timeout/-/max-timeout-1.0.0.tgz#b68f69a2f99e0b476fd4cb23e2059ca750715e1f" + +md5-hex@^1.2.0, md5-hex@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + dependencies: + md5-o-matic "^0.1.1" + +md5-hex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + +meow@^3.3.0, meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-source-map@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.3.tgz#da1415f2722a5119db07b14c4f973410863a2abf" + dependencies: + source-map "^0.5.3" + +merge-stream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + dependencies: + readable-stream "^2.0.1" + +micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.26.0: + version "1.26.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff" + +mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.7: + version "2.1.14" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee" + dependencies: + mime-db "~1.26.0" + +mime@^1.2.11: + version "1.3.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" + +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +minimist@0.0.8, minimist@~0.0.1: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@1.2.0, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@0.7.2, ms@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + +multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + +nan@^2.3.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.1.tgz#d5b01691253326a97a2bbee9e61c55d8d60351e2" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +nerf-dart@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/nerf-dart/-/nerf-dart-1.0.0.tgz#e6dab7febf5ad816ea81cf5c629c5a0ebde72c1a" + +netrc@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/netrc/-/netrc-0.1.4.tgz#6be94fcaca8d77ade0a9670dc460914c94472444" + +node-pre-gyp@^0.6.29: + version "0.6.33" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.33.tgz#640ac55198f6a925972e0c16c4ac26a034d5ecc9" + dependencies: + mkdirp "~0.5.1" + nopt "~3.0.6" + npmlog "^4.0.1" + rc "~1.1.6" + request "^2.79.0" + rimraf "~2.5.4" + semver "~5.3.0" + tar "~2.2.1" + tar-pack "~3.3.0" + +node-status-codes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" + +node-uuid@~1.4.7: + version "1.4.7" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.7.tgz#6da5a17668c4b3dd59623bda11cf7fa4c1f60a6f" + +nopt@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +nopt@~3.0.1, nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +normalize-package-data@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-1.0.3.tgz#8be955b8907af975f1a4584ea8bb9b41492312f5" + dependencies: + github-url-from-git "^1.3.0" + github-url-from-username-repo "^1.0.0" + semver "2 || 3 || 4" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, "normalize-package-data@~1.0.1 || ^2.0.0": + version "2.3.5" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.5.tgz#8d924f142960e1777e7ffe170543631cc7cb02df" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" + +"npm-package-arg@^3.0.0 || ^4.0.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-4.2.0.tgz#809bc61cabf54bd5ff94f6165c89ba8ee88c115c" + dependencies: + hosted-git-info "^2.1.5" + semver "^5.1.0" + +npm-registry-client@^7.0.1: + version "7.4.5" + resolved "https://registry.yarnpkg.com/npm-registry-client/-/npm-registry-client-7.4.5.tgz#1ef61851bb7231db53e397aaf76ddf1cb645c3df" + dependencies: + concat-stream "^1.5.2" + graceful-fs "^4.1.6" + normalize-package-data "~1.0.1 || ^2.0.0" + npm-package-arg "^3.0.0 || ^4.0.0" + once "^1.3.3" + request "^2.74.0" + retry "^0.10.0" + semver "2 >=2.2.1 || 3.x || 4 || 5" + slide "^1.1.3" + optionalDependencies: + npmlog "2 || ^3.1.0 || ^4.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npmconf@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/npmconf/-/npmconf-2.1.2.tgz#66606a4a736f1e77a059aa071a79c94ab781853a" + dependencies: + config-chain "~1.1.8" + inherits "~2.0.0" + ini "^1.2.0" + mkdirp "^0.5.0" + nopt "~3.0.1" + once "~1.3.0" + osenv "^0.1.0" + semver "2 || 3 || 4" + uid-number "0.0.5" + +"npmlog@2 || ^3.1.0 || ^4.0.0", npmlog@^4.0.0, npmlog@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.1" + set-blocking "~2.0.0" + +npmlog@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-1.2.1.tgz#28e7be619609b53f7ad1dd300a10d64d716268b6" + dependencies: + ansi "~0.3.0" + are-we-there-yet "~1.0.0" + gauge "~1.2.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +nyc@^10.1.2: + version "10.1.2" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-10.1.2.tgz#ea7acaa20a235210101604f4e7d56d28453b0274" + dependencies: + archy "^1.0.0" + arrify "^1.0.1" + caching-transform "^1.0.0" + convert-source-map "^1.3.0" + debug-log "^1.0.1" + default-require-extensions "^1.0.0" + find-cache-dir "^0.1.1" + find-up "^1.1.2" + foreground-child "^1.5.3" + glob "^7.0.6" + istanbul-lib-coverage "^1.0.1" + istanbul-lib-hook "^1.0.0" + istanbul-lib-instrument "^1.4.2" + istanbul-lib-report "^1.0.0-alpha.3" + istanbul-lib-source-maps "^1.1.0" + istanbul-reports "^1.0.0" + md5-hex "^1.2.0" + merge-source-map "^1.0.2" + micromatch "^2.3.11" + mkdirp "^0.5.0" + resolve-from "^2.0.0" + rimraf "^2.5.4" + signal-exit "^3.0.1" + spawn-wrap "1.2.4" + test-exclude "^3.3.0" + yargs "^6.6.0" + yargs-parser "^4.0.2" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +observable-to-promise@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/observable-to-promise/-/observable-to-promise-0.4.0.tgz#28afe71645308f2d41d71f47ad3fece1a377e52b" + dependencies: + is-observable "^0.2.0" + symbol-observable "^0.2.2" + +once@^1.3.0, once@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +once@~1.3.0, once@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +onetime@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.0.tgz#52aa8110e52fc5126ffc667bd8ec21c2ed209ce6" + dependencies: + mimic-fn "^1.0.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +option-chain@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/option-chain/-/option-chain-0.1.1.tgz#e9b811e006f1c0f54802f28295bfc8970f8dcfbd" + dependencies: + object-assign "^4.0.1" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +ordered-read-streams@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b" + dependencies: + is-stream "^1.0.1" + readable-stream "^2.0.1" + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.0, osenv@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +package-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-1.2.0.tgz#003e56cd57b736a6ed6114cc2b81542672770e44" + dependencies: + md5-hex "^1.3.0" + +package-json@^2.0.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-2.4.0.tgz#0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb" + dependencies: + got "^5.0.0" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pad-right@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/pad-right/-/pad-right-0.2.2.tgz#6fbc924045d244f2a2a244503060d3bfc6009774" + dependencies: + repeat-string "^1.5.2" + +parse-github-repo-url@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.0.tgz#286c53e2c9962e0641649ee3ac9508fca4dd959c" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.1.0, parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-ms@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-0.1.2.tgz#dd3fa25ed6c2efc7bdde12ad9b46c163aa29224e" + +parse-ms@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-object@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/path-object/-/path-object-2.3.0.tgz#03e46653e5c375c60af1cabdd94bc6448a5d9110" + dependencies: + core-util-is "^1.0.1" + lodash.assign "^3.0.0" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + dependencies: + through "~2.3" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-1.0.0.tgz#d1da67f5482563bb7cf57f286ae2822ecfbf3670" + dependencies: + pinkie "^1.0.0" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-conf@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.0.0.tgz#071c87650403bccfb9c627f58751bfe47c067279" + dependencies: + find-up "^2.0.0" + load-json-file "^2.0.0" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + +plur@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/plur/-/plur-1.0.0.tgz#db85c6814f5e5e5a3b49efc28d604fec62975156" + +plur@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" + dependencies: + irregular-plurals "^1.0.0" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +pretty-format@^18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-18.1.0.tgz#fb65a86f7a7f9194963eee91865c1bcf1039e284" + dependencies: + ansi-styles "^2.2.1" + +pretty-ms@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-0.2.2.tgz#da879a682ff33a37011046f13d627f67c73b84f6" + dependencies: + parse-ms "^0.1.0" + +pretty-ms@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-2.1.0.tgz#4257c256df3fb0b451d6affaab021884126981dc" + dependencies: + is-finite "^1.0.1" + parse-ms "^1.0.0" + plur "^1.0.0" + +private@^0.1.6: + version "0.1.7" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + +pseudomap@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +qs@~6.2.0: + version "6.2.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.2.tgz#d506a5ad5b2cae1fd35c4f54ec182e267e3ef586" + +qs@~6.3.0: + version "6.3.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.1.tgz#918c0b3bcd36679772baf135b1acb4c1651ed79d" + +randomatic@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + dependencies: + is-number "^2.0.2" + kind-of "^3.0.2" + +rc@^1.0.1, rc@^1.1.6, rc@~1.1.6: + version "1.1.7" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.7.tgz#c5ea564bb07aff9fd3a5b32e906c1d3a65940fea" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-all-stream@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" + dependencies: + pinkie-promise "^2.0.0" + readable-stream "^2.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.3.tgz#9cf49463985df016c8ae8813097a9293a9b33729" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +regenerate@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" + +regenerator-runtime@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e" + +regex-cache@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" + dependencies: + is-equal-shallow "^0.1.3" + is-primitive "^2.0.0" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +registry-auth-token@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.1.0.tgz#997c08256e0c7999837b90e944db39d8a790276b" + dependencies: + rc "^1.1.6" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + dependencies: + rc "^1.0.1" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + dependencies: + lodash "^4.13.1" + +request-promise@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.1.1.tgz#26021e4f6f56fd4c309f6bf1ebd8c97a95ac1fb5" + dependencies: + bluebird "^3.4.1" + request-promise-core "1.1.1" + stealthy-require "^1.0.0" + +request@2.79.0, request@^2.74.0, request@^2.78.0, request@^2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + +request@~2.74.0: + version "2.74.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.74.0.tgz#7693ca768bbb0ea5c8ce08c084a45efa05b892ab" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + bl "~1.1.2" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~1.0.0-rc4" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + node-uuid "~1.4.7" + oauth-sign "~0.8.1" + qs "~6.2.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +require-precompiled@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" + +require-relative@^0.8.7: + version "0.8.7" + resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de" + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-1.0.0.tgz#4eaeea41ed040d1702457df64a42b2b07d246f9f" + dependencies: + resolve-from "^2.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve-from@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + +resolve@^1.1.6: + version "1.3.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" + dependencies: + path-parse "^1.0.5" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +retry@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +right-pad@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/right-pad/-/right-pad-1.0.1.tgz#8ca08c2cbb5b55e74dafa96bf7fd1a27d568c8d0" + +rimraf@2, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@^2.5.4: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" + dependencies: + glob "^7.0.5" + +rimraf@~2.5.1, rimraf@~2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + dependencies: + glob "^7.0.5" + +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + dependencies: + once "^1.3.0" + +run-auto@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/run-auto/-/run-auto-2.0.0.tgz#5f4353f58adbd6b74926489b4f259e1dad6a78d6" + dependencies: + dezalgo "^1.0.1" + +run-series@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/run-series/-/run-series-1.1.4.tgz#89a73ddc5e75c9ef8ab6320c0a1600d6a41179b9" + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + +semantic-release@^6.3.2: + version "6.3.6" + resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-6.3.6.tgz#629d0aec90b38a2957a57a4a9ee1214af51928c7" + dependencies: + "@semantic-release/commit-analyzer" "^2.0.0" + "@semantic-release/condition-travis" "^5.0.2" + "@semantic-release/error" "^1.0.0" + "@semantic-release/last-release-npm" "^1.2.1" + "@semantic-release/release-notes-generator" "^2.0.0" + git-head "^1.2.1" + github "^8.0.0" + lodash "^4.0.0" + nerf-dart "^1.0.0" + nopt "^4.0.0" + normalize-package-data "^2.3.4" + npmconf "^2.1.2" + npmlog "^4.0.0" + parse-github-repo-url "^1.3.0" + require-relative "^0.8.7" + run-auto "^2.0.0" + run-series "^1.1.3" + semver "^5.2.0" + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" + +"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.2.0, semver@^5.3.0, semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +"semver@2 || 3 || 4": + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + +semver@~5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +shelljs@^0.7.5: + version "0.7.6" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +signal-exit@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-2.1.2.tgz#375879b1f92ebc3b334480d038dc546a6d558564" + +signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +slide@^1.1.3, slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sort-keys@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + dependencies: + is-plain-obj "^1.0.0" + +source-map-support@^0.4.0, source-map-support@^0.4.2: + version "0.4.11" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.11.tgz#647f939978b38535909530885303daf23279f322" + dependencies: + source-map "^0.5.3" + +source-map@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.3, source-map@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +spawn-wrap@1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.2.4.tgz#920eb211a769c093eebfbd5b0e7a5d2e68ab2e40" + dependencies: + foreground-child "^1.3.3" + mkdirp "^0.5.0" + os-homedir "^1.0.1" + rimraf "^2.3.3" + signal-exit "^2.0.0" + which "^1.2.4" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + dependencies: + through "2" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.11.0.tgz#2d8d5ebb4a6fab28ffba37fa62a90f4a3ea59d77" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jodid25519 "^1.0.0" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stack-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.0.tgz#2392cd8ddbd222492ed6c047960f7414b46c0f83" + +stealthy-require@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.0.0.tgz#1a8ed8fc19a8b56268f76f5a1a3e3832b0c26200" + +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + dependencies: + duplexer "~0.1.1" + +stream-consume@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^3.0.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + +strip-bom-buf@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz#1cb45aaf57530f4caf86c7f75179d2c9a51dd572" + dependencies: + is-utf8 "^0.2.1" + +strip-bom-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" + dependencies: + first-chunk-stream "^1.0.0" + strip-bom "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +symbol-observable@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" + +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +tar-pack@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.3.0.tgz#30931816418f55afc4d21775afdd6720cee45dae" + dependencies: + debug "~2.2.0" + fstream "~1.0.10" + fstream-ignore "~1.0.5" + once "~1.3.3" + readable-stream "~2.1.4" + rimraf "~2.5.1" + tar "~2.2.1" + uid-number "~0.0.6" + +tar@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +test-exclude@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-3.3.0.tgz#7a17ca1239988c98367b0621456dbb7d4bc38977" + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +text-table@^0.2.0, text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +through2-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^0.6.0: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.1, through2@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through@2, through@^2.3.6, through@~2.3, through@~2.3.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +time-require@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/time-require/-/time-require-0.1.2.tgz#f9e12cb370fc2605e11404582ba54ef5ca2b2d98" + dependencies: + chalk "^0.4.0" + date-time "^0.1.1" + pretty-ms "^0.2.1" + text-table "^0.2.0" + +timed-out@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217" + +to-absolute-glob@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" + dependencies: + extend-shallow "^2.0.1" + +to-fast-properties@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +travis-ci@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/travis-ci/-/travis-ci-2.1.1.tgz#98696265af827ae3576f31aa06d876e74b4b082e" + dependencies: + github "~0.1.10" + lodash "~1.3.1" + request "~2.74.0" + underscore.string "~2.2.0rc" + +travis-deploy-once@1.0.0-node-0.10-support: + version "1.0.0-node-0.10-support" + resolved "https://registry.yarnpkg.com/travis-deploy-once/-/travis-deploy-once-1.0.0-node-0.10-support.tgz#98ecce7d95b2f4ba5dcdeeebf54b9df87713d5e6" + dependencies: + babel-polyfill "^6.16.0" + bluebird "^3.4.6" + request "^2.78.0" + request-promise "^4.1.1" + travis-ci "^2.1.1" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +tryit@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +type-detect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + +type-detect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +uglify-js@^2.6: + version "2.8.5" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.5.tgz#ae9f5b143f4183d99a1dabb350e243fdc06641ed" + dependencies: + async "~0.2.6" + source-map "~0.5.1" + uglify-to-browserify "~1.0.0" + yargs "~3.10.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +uid-number@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.5.tgz#5a3db23ef5dbd55b81fce0ec9a2ac6fccdebb81e" + +uid-number@~0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +uid2@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + +underscore.string@~2.2.0rc: + version "2.2.1" + resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.2.1.tgz#d7c0fa2af5d5a1a67f4253daee98132e733f0f19" + +unique-stream@^2.0.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" + dependencies: + json-stable-stringify "^1.0.0" + through2-filter "^2.0.0" + +unique-temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz#6dce95b2681ca003eebfb304a415f9cbabcc5385" + dependencies: + mkdirp "^0.5.1" + os-tmpdir "^1.0.1" + uid2 "0.0.3" + +unzip-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" + +update-notifier@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-1.0.3.tgz#8f92c515482bd6831b7c93013e70f87552c7cf5a" + dependencies: + boxen "^0.6.0" + chalk "^1.0.0" + configstore "^2.0.0" + is-npm "^1.0.0" + latest-version "^2.0.0" + lazy-req "^1.1.0" + semver-diff "^2.0.0" + xdg-basedir "^2.0.0" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + dependencies: + os-homedir "^1.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +uuid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + +uuid@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +vali-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +verror@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" + dependencies: + extsprintf "1.0.2" + +vinyl-fs@^2.4.3: + version "2.4.4" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239" + dependencies: + duplexify "^3.2.0" + glob-stream "^5.3.2" + graceful-fs "^4.0.0" + gulp-sourcemaps "1.6.0" + is-valid-glob "^0.3.0" + lazystream "^1.0.0" + lodash.isequal "^4.0.0" + merge-stream "^1.0.0" + mkdirp "^0.5.0" + object-assign "^4.0.0" + readable-stream "^2.0.4" + strip-bom "^2.0.0" + strip-bom-stream "^1.0.0" + through2 "^2.0.0" + through2-filter "^2.0.0" + vali-date "^1.0.0" + vinyl "^1.0.0" + +vinyl@^1.0.0, vinyl@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +walk@^2.3.9: + version "2.3.9" + resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.9.tgz#31b4db6678f2ae01c39ea9fb8725a9031e558a7b" + dependencies: + foreachasync "^3.0.0" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + +which@^1.2.4, which@^1.2.9: + version "1.2.12" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192" + dependencies: + isexe "^1.1.1" + +wide-align@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" + dependencies: + string-width "^1.0.1" + +widest-line@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" + dependencies: + string-width "^1.0.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +word-wrap@^1.0.3: + version "1.2.1" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.1.tgz#248f459b465d179a17bc407c854d3151d07e45d8" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^1.1.2, write-file-atomic@^1.1.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.1.tgz#7d45ba32316328dd1ec7d90f60ebc0d845bb759a" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.0.0.tgz#0eaec981fcf9288dbc2806cbd26e06ab9bdca4ed" + dependencies: + graceful-fs "^4.1.2" + mkdirp "^0.5.1" + pify "^2.0.0" + sort-keys "^1.1.1" + write-file-atomic "^1.1.2" + +write-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-2.0.0.tgz#93b922ee9a429f9bd74cdc69e549733c9e468156" + dependencies: + write-json-file "^2.0.0" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +xdg-basedir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" + dependencies: + os-homedir "^1.0.0" + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.0.0.tgz#306c543835f09ee1a4cb23b7bce9ab341c91cdd4" + +yargs-parser@^4.0.2, yargs-parser@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + dependencies: + camelcase "^3.0.0" + +yargs@^6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^4.2.0" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" diff --git a/libraries/SDS011-select-serial/Readme.md b/libraries/SDS011-select-serial/Readme.md new file mode 100644 index 0000000..ead3f03 --- /dev/null +++ b/libraries/SDS011-select-serial/Readme.md @@ -0,0 +1,26 @@ +# SDS011 library selectable serialport + +Arduino library for dust Sensor SDS011 (Nova Fitness Co.,Ltd) which allows to choose the serial port used to communicate with the sensor. +Based on the work of [ricky-z](https://github.com/ricki-z/SDS011) + +## Usage + +* Define SDS object: +``` +SDS011(Stream& serial); +``` +i.e. SDS011 mySDS(Serial1); + +* Start serial communication: +``` +Serial1.begin(9600); +``` + +* Read values: +``` +int read(float *p25, float *p10); +``` +i.e. error = mySDS(pm25,pm10); + +Reads the PM2.5 and PM10 values, return code is 0, if new values were read, and 1 if there were no new values. + diff --git a/libraries/SDS011-select-serial/SDS011-select-serial.cpp b/libraries/SDS011-select-serial/SDS011-select-serial.cpp new file mode 100644 index 0000000..e448aef --- /dev/null +++ b/libraries/SDS011-select-serial/SDS011-select-serial.cpp @@ -0,0 +1,97 @@ +// SDS011 dust sensor PM2.5 and PM10 +// --------------------- +// +// By R. Zschiegner (rz@madavi.de) +// April 2016 +// +// Documentation: +// - The iNovaFitness SDS011 datasheet +// + +#include "SDS011-select-serial.h" + +static const byte SLEEPCMD[19] = { + 0xAA, // head + 0xB4, // command id + 0x06, // data byte 1 + 0x01, // data byte 2 (set mode) + 0x00, // data byte 3 (sleep) + 0x00, // data byte 4 + 0x00, // data byte 5 + 0x00, // data byte 6 + 0x00, // data byte 7 + 0x00, // data byte 8 + 0x00, // data byte 9 + 0x00, // data byte 10 + 0x00, // data byte 11 + 0x00, // data byte 12 + 0x00, // data byte 13 + 0xFF, // data byte 14 (device id byte 1) + 0xFF, // data byte 15 (device id byte 2) + 0x05, // checksum + 0xAB // tail +}; + +SDS011::SDS011(Stream& serial): +sds_data(serial) {} + +// -------------------------------------------------------- +// SDS011:read +// -------------------------------------------------------- +int SDS011::read(float *p25, float *p10) { + byte buffer; + int value; + int len = 0; + int pm10_serial = 0; + int pm25_serial = 0; + int checksum_is; + int checksum_ok = 0; + int error = 1; + while ((sds_data.available() > 0) && (sds_data.available() >= (10-len))) { + buffer = sds_data.read(); + value = int(buffer); + switch (len) { + case (0): if (value != 170) { len = -1; }; break; + case (1): if (value != 192) { len = -1; }; break; + case (2): pm25_serial = value; checksum_is = value; break; + case (3): pm25_serial += (value << 8); checksum_is += value; break; + case (4): pm10_serial = value; checksum_is += value; break; + case (5): pm10_serial += (value << 8); checksum_is += value; break; + case (6): checksum_is += value; break; + case (7): checksum_is += value; break; + case (8): if (value == (checksum_is % 256)) { checksum_ok = 1; } else { len = -1; }; break; + case (9): if (value != 171) { len = -1; }; break; + } + len++; + if (len == 10 && checksum_ok == 1) { + *p10 = (float)pm10_serial/10.0; + *p25 = (float)pm25_serial/10.0; + len = 0; checksum_ok = 0; pm10_serial = 0.0; pm25_serial = 0.0; checksum_is = 0; + error = 0; + } + yield(); + } + return error; +} + +// -------------------------------------------------------- +// SDS011:sleep +// -------------------------------------------------------- +void SDS011::sleep() { + for (uint8_t i = 0; i < 19; i++) { + sds_data.write(SLEEPCMD[i]); + } + sds_data.flush(); + while (sds_data.available() > 0) { + sds_data.read(); + } +} + +// -------------------------------------------------------- +// SDS011:wakeup +// -------------------------------------------------------- +void SDS011::wakeup() { + sds_data.write(0x01); + sds_data.flush(); +} + diff --git a/libraries/SDS011-select-serial/SDS011-select-serial.h b/libraries/SDS011-select-serial/SDS011-select-serial.h new file mode 100644 index 0000000..be481d1 --- /dev/null +++ b/libraries/SDS011-select-serial/SDS011-select-serial.h @@ -0,0 +1,25 @@ +// SDS011 dust sensor PM2.5 and PM10 +// --------------------------------- +// +// By R. Zschiegner (rz@madavi.de) +// April 2016 +// +// Documentation: +// - The iNovaFitness SDS011 datasheet +// + +#if ARDUINO >= 100 + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +class SDS011 { + public: + SDS011(Stream& serial); + int read(float *p25, float *p10); + void sleep(); + void wakeup(); + private: + Stream& sds_data; +}; diff --git a/libraries/SDS011-select-serial/examples/SDS011-ArduinoMega_HW_Serial/SDS011-ArduinoMega_HW_Serial.ino b/libraries/SDS011-select-serial/examples/SDS011-ArduinoMega_HW_Serial/SDS011-ArduinoMega_HW_Serial.ino new file mode 100644 index 0000000..4c7fc13 --- /dev/null +++ b/libraries/SDS011-select-serial/examples/SDS011-ArduinoMega_HW_Serial/SDS011-ArduinoMega_HW_Serial.ino @@ -0,0 +1,27 @@ +// SDS011 dust sensor example +// for use with additional Serial ports +// like Arduino Mega +// ----------------------------- + +#include + +float p10,p25; +int error; + +SDS011 my_sds(Serial1); + +void setup() { + // initialize normal Serial port + Serial.begin(9600); + // initalize SDS Serial Port + Serial1.begin(9600); +} + +void loop() { + error = my_sds.read(&p25,&p10); + if (! error) { + Serial.println("P2.5: "+String(p25)); + Serial.println("P10: "+String(p10)); + } + delay(100); +} diff --git a/libraries/SDS011-select-serial/examples/SDS011-SoftSerial/SDS011-SoftSerial.ino b/libraries/SDS011-select-serial/examples/SDS011-SoftSerial/SDS011-SoftSerial.ino new file mode 100644 index 0000000..e7cd3a4 --- /dev/null +++ b/libraries/SDS011-select-serial/examples/SDS011-SoftSerial/SDS011-SoftSerial.ino @@ -0,0 +1,28 @@ +// SDS011 dust sensor example +// for use with SoftSerial +// ----------------------------- + +#include +#include + +float p10,p25; +int error; + +SoftwareSerial mySerial(10, 11); // RX, TX +SDS011 my_sds(mySerial); + +void setup() { + // initialize normal Serial port + Serial.begin(9600); + // initalize SDS Serial Port + mySerial.begin(9600); +} + +void loop() { + error = my_sds.read(&p25,&p10); + if (! error) { + Serial.println("P2.5: "+String(p25)); + Serial.println("P10: "+String(p10)); + } + delay(100); +} diff --git a/libraries/SDS011-select-serial/library.properties b/libraries/SDS011-select-serial/library.properties new file mode 100644 index 0000000..b7dc881 --- /dev/null +++ b/libraries/SDS011-select-serial/library.properties @@ -0,0 +1,9 @@ +name=SDS011 selectable serial sensor Library +version=0.0.6 +author=R. Zschiegner, G. Pape +maintainer=R.Zschiegner , G.Pape +sentence=Nova Fitness SDS011 dust sensor library +paragraph=Nova Fitness SDS011 dust sensor library +category=Sensors +url=https://github.com/sensebox/SDS011-select-serial +architectures=esp8266,avr diff --git a/libraries/SdFat/README.md b/libraries/SdFat/README.md new file mode 100644 index 0000000..0c6a98e --- /dev/null +++ b/libraries/SdFat/README.md @@ -0,0 +1,58 @@ +The Arduino SdFat library provides read/write access to FAT16/FAT32 +file systems on SD/SDHC flash cards. + +SdFat requires Arduino 1.6x or greater. + +Key changes: + +The SPI divisor has been replaced by SPISettings in the begin() call. + +``` +bool begin(uint8_t csPin = SS, SPISettings spiSettings = SPI_FULL_SPEED); +``` + +Several macros have been defined for backward compatibility. + +``` +#define SD_SCK_MHZ(maxMhz) SPISettings(1000000UL*maxMhz, MSBFIRST, SPI_MODE0) +// SPI divisor constants +/** Set SCK to max possible rate. */ +#define SPI_FULL_SPEED SD_SCK_MHZ(50) +/** Set SCK rate to F_CPU/3 for Due */ +#define SPI_DIV3_SPEED SD_SCK_HZ(F_CPU/3) +/** Set SCK rate to F_CPU/4. */ +#define SPI_HALF_SPEED SD_SCK_HZ(F_CPU/4) +// ... +``` + +There are two new classes, SdFatEX and SdFatSoftSpiEX. + +Teensy 3.5/3.6 SDIO support has been added. Try the TeensySdioDemo example. +Many other example will work with Teensy SDIO if you use the SdFatSdio classes +and call begin with no parameters. + +``` + SdFatSdio sd; + + .... + + if (!sd.begin()) { + // Handle failure. + } + +``` +Please read changes.txt and the html documentation in the extras folder for more information. + +Please report problems as issues. + +A number of configuration options can be set by editing SdFatConfig.h +define macros. See the html documentation for details + +Please read the html documentation for this library. Start with +html/index.html and read the Main Page. Next go to the Classes tab and +read the documentation for the classes SdFat, SdFatEX, SdBaseFile, +SdFile, File, StdioStream, ifstream, ofstream, and others. + +Please continue by reading the html documentation. + +Updated 26 Apr 2017 diff --git a/libraries/SdFat/examples/#attic/AnalogLogger/AnalogLogger.ino b/libraries/SdFat/examples/#attic/AnalogLogger/AnalogLogger.ino new file mode 100644 index 0000000..e846d53 --- /dev/null +++ b/libraries/SdFat/examples/#attic/AnalogLogger/AnalogLogger.ino @@ -0,0 +1,196 @@ +// A simple data logger for the Arduino analog pins with optional DS1307 +// uses RTClib from https://github.com/adafruit/RTClib +#include +#include "SdFat.h" +#include "FreeStack.h" + +#define SD_CHIP_SELECT SS // SD chip select pin +#define USE_DS1307 0 // set nonzero to use DS1307 RTC +#define LOG_INTERVAL 1000 // mills between entries +#define SENSOR_COUNT 3 // number of analog pins to log +#define ECHO_TO_SERIAL 1 // echo data to serial port if nonzero +#define WAIT_TO_START 1 // Wait for serial input in setup() +#define ADC_DELAY 10 // ADC delay for high impedence sensors + +// file system object +SdFat sd; + +// text file for logging +ofstream logfile; + +// Serial print stream +ArduinoOutStream cout(Serial); + +// buffer to format data - makes it eaiser to echo to Serial +char buf[80]; +//------------------------------------------------------------------------------ +#if SENSOR_COUNT > 6 +#error SENSOR_COUNT too large +#endif // SENSOR_COUNT +//------------------------------------------------------------------------------ +// store error strings in flash to save RAM +#define error(s) sd.errorHalt(F(s)) +//------------------------------------------------------------------------------ +#if USE_DS1307 +// use RTClib from Adafruit +// https://github.com/adafruit/RTClib + +// The Arduino IDE has a bug that causes Wire and RTClib to be loaded even +// if USE_DS1307 is false. + +#error remove this line and uncomment the next two lines. +//#include +//#include +RTC_DS1307 RTC; // define the Real Time Clock object +//------------------------------------------------------------------------------ +// call back for file timestamps +void dateTime(uint16_t* date, uint16_t* time) { + DateTime now = RTC.now(); + + // return date using FAT_DATE macro to format fields + *date = FAT_DATE(now.year(), now.month(), now.day()); + + // return time using FAT_TIME macro to format fields + *time = FAT_TIME(now.hour(), now.minute(), now.second()); +} +//------------------------------------------------------------------------------ +// format date/time +ostream& operator << (ostream& os, DateTime& dt) { + os << dt.year() << '/' << int(dt.month()) << '/' << int(dt.day()) << ','; + os << int(dt.hour()) << ':' << setfill('0') << setw(2) << int(dt.minute()); + os << ':' << setw(2) << int(dt.second()) << setfill(' '); + return os; +} +#endif // USE_DS1307 +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial. + while (!Serial) { + SysCall::yield(); + } + // F() stores strings in flash to save RAM + cout << endl << F("FreeStack: ") << FreeStack() << endl; + +#if WAIT_TO_START + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + // Discard input. + do { + delay(10); + } while(Serial.available() && Serial.read() >= 0); +#endif // WAIT_TO_START + +#if USE_DS1307 + // connect to RTC + Wire.begin(); + if (!RTC.begin()) { + error("RTC failed"); + } + + // set date time callback function + SdFile::dateTimeCallback(dateTime); + DateTime now = RTC.now(); + cout << now << endl; +#endif // USE_DS1307 + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(SD_CHIP_SELECT, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // create a new file in root, the current working directory + char name[] = "logger00.csv"; + + for (uint8_t i = 0; i < 100; i++) { + name[6] = i/10 + '0'; + name[7] = i%10 + '0'; + if (sd.exists(name)) { + continue; + } + logfile.open(name); + break; + } + if (!logfile.is_open()) { + error("file.open"); + } + + cout << F("Logging to: ") << name << endl; + cout << F("Type any character to stop\n\n"); + + // format header in buffer + obufstream bout(buf, sizeof(buf)); + + bout << F("millis"); + +#if USE_DS1307 + bout << F(",date,time"); +#endif // USE_DS1307 + + for (uint8_t i = 0; i < SENSOR_COUNT; i++) { + bout << F(",sens") << int(i); + } + logfile << buf << endl; + +#if ECHO_TO_SERIAL + cout << buf << endl; +#endif // ECHO_TO_SERIAL +} +//------------------------------------------------------------------------------ +void loop() { + uint32_t m; + + // wait for time to be a multiple of interval + do { + m = millis(); + } while (m % LOG_INTERVAL); + + // use buffer stream to format line + obufstream bout(buf, sizeof(buf)); + + // start with time in millis + bout << m; + +#if USE_DS1307 + DateTime now = RTC.now(); + bout << ',' << now; +#endif // USE_DS1307 + + // read analog pins and format data + for (uint8_t ia = 0; ia < SENSOR_COUNT; ia++) { +#if ADC_DELAY + analogRead(ia); + delay(ADC_DELAY); +#endif // ADC_DELAY + bout << ',' << analogRead(ia); + } + bout << endl; + + // log data and flush to SD + logfile << buf << flush; + + // check for error + if (!logfile) { + error("write data failed"); + } + +#if ECHO_TO_SERIAL + cout << buf; +#endif // ECHO_TO_SERIAL + + // don't log two points in the same millis + if (m == millis()) { + delay(1); + } + + if (!Serial.available()) { + return; + } + logfile.close(); + cout << F("Done!"); + SysCall::halt(); +} \ No newline at end of file diff --git a/libraries/SdFat/examples/#attic/BaseExtCaseTest/BaseExtCaseTest.ino b/libraries/SdFat/examples/#attic/BaseExtCaseTest/BaseExtCaseTest.ino new file mode 100644 index 0000000..0212d3b --- /dev/null +++ b/libraries/SdFat/examples/#attic/BaseExtCaseTest/BaseExtCaseTest.ino @@ -0,0 +1,46 @@ +/* + * Program to test Short File Name character case flags. + */ +#include +#include "SdFat.h" + +const uint8_t chipSelect = SS; + +SdFat sd; + +SdFile file; +const char* name[] = { + "low.low", "low.Mix", "low.UP", + "Mix.low", "Mix.Mix", "Mix.UP", + "UP.low", "UP.Mix", "UP.UP" +}; +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + Serial.println("type any character to start"); + while (!Serial.available()) { + SysCall::yield(); + } + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + Serial.println("begin failed"); + return; + } + for (uint8_t i = 0; i < 9; i++) { + sd.remove(name[i]); + if (!file.open(name[i], O_RDWR | O_CREAT | O_EXCL)) { + sd.errorHalt(name[i]); + } + file.println(name[i]); + + file.close(); + } + sd.ls(LS_DATE|LS_SIZE); + Serial.println("Done"); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/examples/#attic/HelloWorld/HelloWorld.ino b/libraries/SdFat/examples/#attic/HelloWorld/HelloWorld.ino new file mode 100644 index 0000000..f0dc22b --- /dev/null +++ b/libraries/SdFat/examples/#attic/HelloWorld/HelloWorld.ino @@ -0,0 +1,19 @@ +#include +#include "SdFat.h" + +// create a serial output stream +ArduinoOutStream cout(Serial); + +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + delay(2000); + + cout << "Hello, World!\n"; +} + +void loop() {} diff --git a/libraries/SdFat/examples/#attic/MiniSerial/MiniSerial.ino b/libraries/SdFat/examples/#attic/MiniSerial/MiniSerial.ino new file mode 100644 index 0000000..46931ab --- /dev/null +++ b/libraries/SdFat/examples/#attic/MiniSerial/MiniSerial.ino @@ -0,0 +1,29 @@ +// This example illustrates use of SdFat's +// minimal unbuffered AVR Serial support. +// +// This is useful for debug and saves RAM +// Will not work on Due, Leonardo, or Teensy + +#include +#include "SdFat.h" +#include "FreeStack.h" +#ifdef UDR0 // Must be AVR with serial port zero. +#include "MinimumSerial.h" + +MinimumSerial MiniSerial; + +void setup() { + MiniSerial.begin(9600); + MiniSerial.println(FreeStack()); +} +void loop() { + int c; + MiniSerial.println(F("Type any Character")); + while ((c = MiniSerial.read()) < 0) {} + MiniSerial.print(F("Read: ")); + MiniSerial.println((char)c); + while (MiniSerial.read() >= 0) {} +} +#else // UDR0 +#error no AVR serial port 0 +#endif // UDR0 \ No newline at end of file diff --git a/libraries/SdFat/examples/#attic/PrintBenchmarkSD/PrintBenchmarkSD.ino b/libraries/SdFat/examples/#attic/PrintBenchmarkSD/PrintBenchmarkSD.ino new file mode 100644 index 0000000..f727d2d --- /dev/null +++ b/libraries/SdFat/examples/#attic/PrintBenchmarkSD/PrintBenchmarkSD.ino @@ -0,0 +1,125 @@ +/* + * This program is a simple Print benchmark. + */ +#include +#include + +// SD chip select pin +const uint8_t chipSelect = SS; + +// number of lines to print +const uint16_t N_PRINT = 20000; + + +// test file +File file; + +//------------------------------------------------------------------------------ +void error(const char* s) { + Serial.println(s); + while (1) { + yield(); + } +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + yield(); + } +} +//------------------------------------------------------------------------------ +void loop() { + uint32_t maxLatency; + uint32_t minLatency; + uint32_t totalLatency; + + // Read any existing Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + + // F() stores strings in flash to save RAM + Serial.println(F("Type any character to start")); + while (!Serial.available()) { + yield(); + } + + // initialize the SD card + if (!SD.begin(chipSelect)) { + error("begin"); + } + + Serial.println(F("Starting print test. Please wait.\n")); + + // do write test + for (int test = 0; test < 2; test++) { + file = SD.open("bench.txt", FILE_WRITE); + + if (!file) { + error("open failed"); + } + switch(test) { + case 0: + Serial.println(F("Test of println(uint16_t)")); + break; + + case 1: + Serial.println(F("Test of println(double)")); + break; + } + maxLatency = 0; + minLatency = 999999; + totalLatency = 0; + uint32_t t = millis(); + for (uint16_t i = 0; i < N_PRINT; i++) { + uint32_t m = micros(); + + switch(test) { + case 0: + file.println(i); + break; + + case 1: + file.println((double)0.01*i); + break; + } + + if (file.getWriteError()) { + error("write failed"); + } + m = micros() - m; + if (maxLatency < m) { + maxLatency = m; + } + if (minLatency > m) { + minLatency = m; + } + totalLatency += m; + } + file.flush(); + t = millis() - t; + double s = file.size(); + Serial.print(F("Time ")); + Serial.print(0.001*t); + Serial.println(F(" sec")); + Serial.print(F("File size ")); + Serial.print(0.001*s); + Serial.print(F(" KB\n")); + Serial.print(F("Write ")); + Serial.print(s/t); + Serial.print(F(" KB/sec\n")); + Serial.print(F("Maximum latency: ")); + Serial.print(maxLatency); + Serial.print(F(" usec, Minimum Latency: ")); + Serial.print(minLatency); + Serial.print(F(" usec, Avg Latency: ")); + Serial.print(totalLatency/N_PRINT); + Serial.println(F(" usec\n")); + SD.remove("bench.txt"); + } + file.close(); + Serial.println(F("Done!\n")); +} \ No newline at end of file diff --git a/libraries/SdFat/examples/#attic/SD_Size/SD_Size.ino b/libraries/SdFat/examples/#attic/SD_Size/SD_Size.ino new file mode 100644 index 0000000..b021d27 --- /dev/null +++ b/libraries/SdFat/examples/#attic/SD_Size/SD_Size.ino @@ -0,0 +1,30 @@ +/* + * Program to compare size of Arduino SD library with SdFat. + * See SdFatSize.ino for SdFat program. + */ +#include +#include + +File file; +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + yield(); + } + + if (!SD.begin()) { + Serial.println("begin failed"); + return; + } + file = SD.open("TEST_SD.TXT", FILE_WRITE); + + file.println("Hello"); + + file.close(); + Serial.println("Done"); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/examples/#attic/SdFatSize/SdFatSize.ino b/libraries/SdFat/examples/#attic/SdFatSize/SdFatSize.ino new file mode 100644 index 0000000..3c37d30 --- /dev/null +++ b/libraries/SdFat/examples/#attic/SdFatSize/SdFatSize.ino @@ -0,0 +1,33 @@ +/* + * Program to compare size of SdFat with Arduino SD library. + * See SD_Size.ino for Arduino SD program. + * + */ +#include +#include "SdFat.h" + +SdFat sd; + +SdFile file; +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + + if (!sd.begin()) { + Serial.println("begin failed"); + return; + } + file.open("SizeTest.txt", O_RDWR | O_CREAT | O_AT_END); + + file.println("Hello"); + + file.close(); + Serial.println("Done"); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/examples/#attic/StreamParseInt/StreamParseInt.ino b/libraries/SdFat/examples/#attic/StreamParseInt/StreamParseInt.ino new file mode 100644 index 0000000..2da1f7c --- /dev/null +++ b/libraries/SdFat/examples/#attic/StreamParseInt/StreamParseInt.ino @@ -0,0 +1,44 @@ +// Simple demo of the Stream parsInt() member function. +#include +// The next two lines replace #include . +#include "SdFat.h" +SdFat SD; + +// SD card chip select pin - Modify the value of csPin for your SD module. +const uint8_t csPin = SS; + +File file; +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + // Wait for USB Serial. + while(!Serial) { + SysCall::yield(); + } + Serial.println(F("Type any character to start")); + while (!Serial.available()) { + SysCall::yield(); + } + // Initialize the SD. + if (!SD.begin(csPin)) { + Serial.println(F("begin error")); + return; + } + // Create and open the file. Use flag to truncate an existing file. + file = SD.open("stream.txt", O_RDWR|O_CREAT|O_TRUNC); + if (!file) { + Serial.println(F("open error")); + return; + } + // Write a test number to the file. + file.println("12345"); + + // Rewind the file and read the number with parseInt(). + file.seek(0); + int i = file.parseInt(); + Serial.print(F("parseInt: ")); + Serial.println(i); + file.close(); +} + +void loop() {} \ No newline at end of file diff --git a/libraries/SdFat/examples/#attic/append/append.ino b/libraries/SdFat/examples/#attic/append/append.ino new file mode 100644 index 0000000..6ced4df --- /dev/null +++ b/libraries/SdFat/examples/#attic/append/append.ino @@ -0,0 +1,76 @@ +/* + * Append Example + * + * This program shows how to use open for append. + * The program will append 100 line each time it opens the file. + * The program will open and close the file 100 times. + */ +#include +#include "SdFat.h" + +// SD chip select pin +const uint8_t chipSelect = SS; + +// file system object +SdFat sd; + +// create Serial stream +ArduinoOutStream cout(Serial); + +// store error strings in flash to save RAM +#define error(s) sd.errorHalt(F(s)) +//------------------------------------------------------------------------------ +void setup() { + // filename for this example + char name[] = "append.txt"; + + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + // F() stores strings in flash to save RAM + cout << endl << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + cout << F("Appending to: ") << name; + + for (uint8_t i = 0; i < 100; i++) { + // open stream for append + ofstream sdout(name, ios::out | ios::app); + if (!sdout) { + error("open failed"); + } + + // append 100 lines to the file + for (uint8_t j = 0; j < 100; j++) { + // use int() so byte will print as decimal number + sdout << "line " << int(j) << " of pass " << int(i); + sdout << " millis = " << millis() << endl; + } + // close the stream + sdout.close(); + + if (!sdout) { + error("append data failed"); + } + + // output progress indicator + if (i % 25 == 0) { + cout << endl; + } + cout << '.'; + } + cout << endl << "Done" << endl; +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/examples/#attic/average/average.ino b/libraries/SdFat/examples/#attic/average/average.ino new file mode 100644 index 0000000..01be276 --- /dev/null +++ b/libraries/SdFat/examples/#attic/average/average.ino @@ -0,0 +1,81 @@ +/* + * Calculate the sum and average of a list of floating point numbers + */ +#include +#include "SdFat.h" + +// SD chip select pin +const uint8_t chipSelect = SS; + +// object for the SD file system +SdFat sd; + +// define a serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void writeTestFile() { + // open the output file + ofstream sdout("AvgTest.txt"); + + // write a series of float numbers + for (int16_t i = -1001; i < 2000; i += 13) { + sdout << 0.1 * i << endl; + } + if (!sdout) { + sd.errorHalt("sdout failed"); + } + + sdout.close(); +} +//------------------------------------------------------------------------------ +void calcAverage() { + uint16_t n = 0; // count of input numbers + double num; // current input number + double sum = 0; // sum of input numbers + + // open the input file + ifstream sdin("AvgTest.txt"); + + // check for an open failure + if (!sdin) { + sd.errorHalt("sdin failed"); + } + + // read and sum the numbers + while (sdin >> num) { + n++; + sum += num; + } + + // print the results + cout << "sum of " << n << " numbers = " << sum << endl; + cout << "average = " << sum/n << endl; +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + // F() stores strings in flash to save RAM + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // write the test file + writeTestFile(); + + // read the test file and calculate the average + calcAverage(); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/examples/#attic/benchSD/benchSD.ino b/libraries/SdFat/examples/#attic/benchSD/benchSD.ino new file mode 100644 index 0000000..5adfd57 --- /dev/null +++ b/libraries/SdFat/examples/#attic/benchSD/benchSD.ino @@ -0,0 +1,149 @@ +/* + * This program is a simple binary write/read benchmark + * for the standard Arduino SD.h library. + */ +#include +#include + +// SD chip select pin +const uint8_t chipSelect = SS; + +#define FILE_SIZE_MB 5 +#define FILE_SIZE (1000000UL*FILE_SIZE_MB) +#define BUF_SIZE 100 + +uint8_t buf[BUF_SIZE]; + +// test file +File file; + +//------------------------------------------------------------------------------ +void error(const char* s) { + Serial.println(s); + while (1) { + yield(); + } +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + yield(); + } +} +//------------------------------------------------------------------------------ +void loop() { + uint32_t maxLatency; + uint32_t minLatency; + uint32_t totalLatency; + + // Discard any input. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + + // F() stores strings in flash to save RAM + Serial.println(F("Type any character to start")); + + while (!Serial.available()) { + yield(); + } + if (!SD.begin(chipSelect)) { + error("begin"); + } + + // open or create file - truncate existing file. + file = SD.open("Bench.dat", O_RDWR | O_TRUNC | O_CREAT); + if (!file) { + error("open failed"); + } + + // fill buf with known data + for (uint16_t i = 0; i < (BUF_SIZE-2); i++) { + buf[i] = 'A' + (i % 26); + } + buf[BUF_SIZE-2] = '\r'; + buf[BUF_SIZE-1] = '\n'; + + Serial.print(F("File size ")); + Serial.print(FILE_SIZE_MB); + Serial.println(F("MB")); + Serial.print(F("Buffer size ")); + Serial.print(BUF_SIZE); + Serial.println(F(" bytes")); + Serial.println(F("Starting write test. Please wait up to a minute")); + + // do write test + uint32_t n = FILE_SIZE/sizeof(buf); + maxLatency = 0; + minLatency = 999999; + totalLatency = 0; + uint32_t t = millis(); + for (uint32_t i = 0; i < n; i++) { + uint32_t m = micros(); + if (file.write(buf, sizeof(buf)) != sizeof(buf)) { + error("write failed"); + } + m = micros() - m; + if (maxLatency < m) { + maxLatency = m; + } + if (minLatency > m) { + minLatency = m; + } + totalLatency += m; + } + file.flush(); + t = millis() - t; + double s = file.size(); + Serial.print(F("Write ")); + Serial.print(s/t); + Serial.print(F(" KB/sec\n")); + Serial.print(F("Maximum latency: ")); + Serial.print(maxLatency); + Serial.print(F(" usec, Minimum Latency: ")); + Serial.print(minLatency); + Serial.print(F(" usec, Avg Latency: ")); + Serial.print(totalLatency/n); + Serial.print(F(" usec\n\n")); + Serial.println(F("Starting read test. Please wait up to a minute")); + // do read test + file.seek(0); + maxLatency = 0; + minLatency = 99999; + totalLatency = 0; + t = millis(); + for (uint32_t i = 0; i < n; i++) { + buf[BUF_SIZE-1] = 0; + uint32_t m = micros(); + if (file.read(buf, sizeof(buf)) != sizeof(buf)) { + error("read failed"); + } + m = micros() - m; + if (maxLatency < m) { + maxLatency = m; + } + if (minLatency > m) { + minLatency = m; + } + totalLatency += m; + if (buf[BUF_SIZE-1] != '\n') { + error("data check"); + } + } + t = millis() - t; + Serial.print(F("Read ")); + Serial.print(s/t); + Serial.print(F(" KB/sec\n")); + Serial.print(F("Maximum latency: ")); + Serial.print(maxLatency); + Serial.print(F(" usec, Minimum Latency: ")); + Serial.print(minLatency); + Serial.print(F(" usec, Avg Latency: ")); + Serial.print(totalLatency/n); + Serial.print(F(" usec\n\n")); + Serial.print(F("Done\n\n")); + file.close(); +} \ No newline at end of file diff --git a/libraries/SdFat/examples/#attic/bufstream/bufstream.ino b/libraries/SdFat/examples/#attic/bufstream/bufstream.ino new file mode 100644 index 0000000..11dc518 --- /dev/null +++ b/libraries/SdFat/examples/#attic/bufstream/bufstream.ino @@ -0,0 +1,38 @@ +/* + * Use of ibufsteam to parse a line and obufstream to format a line + */ +#include +#include "SdFat.h" + +// create a serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void setup() { + char buf[20]; // buffer for formatted line + int i, j, k; // values from parsed line + + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + delay(2000); + + // initialize input string + ibufstream bin("123 456 789"); + + // parse the string "123 456 789" + bin >> i >> j >> k; + + // initialize output buffer + obufstream bout(buf, sizeof(buf)); + + // format the output string + bout << k << ',' << j << ',' << i << endl; + + // write the string to serial + cout << buf; +} + +void loop() {} diff --git a/libraries/SdFat/examples/#attic/cin_cout/cin_cout.ino b/libraries/SdFat/examples/#attic/cin_cout/cin_cout.ino new file mode 100644 index 0000000..2cf6678 --- /dev/null +++ b/libraries/SdFat/examples/#attic/cin_cout/cin_cout.ino @@ -0,0 +1,38 @@ +/* + * Demo of ArduinoInStream and ArduinoOutStream + */ +#include +#include "SdFat.h" + +// create serial output stream +ArduinoOutStream cout(Serial); + +// input line buffer +char cinBuf[40]; + +// create serial input stream +ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } +} +//------------------------------------------------------------------------------ +void loop() { + int32_t n = 0; + + cout << "\nenter an integer\n"; + + cin.readline(); + + if (cin >> n) { + cout << "The number is: " << n; + } else { + // will fail if no digits or not in range [-2147483648, 2147483647] + cout << "Invalid input: " << cinBuf; + } + cout << endl; +} diff --git a/libraries/SdFat/examples/#attic/eventlog/eventlog.ino b/libraries/SdFat/examples/#attic/eventlog/eventlog.ino new file mode 100644 index 0000000..43d701c --- /dev/null +++ b/libraries/SdFat/examples/#attic/eventlog/eventlog.ino @@ -0,0 +1,62 @@ +/* + * Append a line to a file - demo of pathnames and streams + */ +#include +#include "SdFat.h" + +// SD chip select pin +const uint8_t chipSelect = SS; + +// file system object +SdFat sd; + +// define a serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +/* + * Append a line to logfile.txt + */ +void logEvent(const char *msg) { + // create dir if needed + sd.mkdir("logs/2014/Jan"); + + // create or open a file for append + ofstream sdlog("logs/2014/Jan/logfile.txt", ios::out | ios::app); + + // append a line to the file + sdlog << msg << endl; + + // check for errors + if (!sdlog) { + sd.errorHalt("append failed"); + } + + sdlog.close(); +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + // F() stores strings in flash to save RAM + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + delay(400); // catch Due reset problem + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // append a line to the logfile + logEvent("Another line for the logfile"); + + cout << F("Done - check /logs/2014/Jan/logfile.txt on the SD") << endl; +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/examples/#attic/fgetsRewrite/fgetsRewrite.ino b/libraries/SdFat/examples/#attic/fgetsRewrite/fgetsRewrite.ino new file mode 100644 index 0000000..622d1e5 --- /dev/null +++ b/libraries/SdFat/examples/#attic/fgetsRewrite/fgetsRewrite.ino @@ -0,0 +1,110 @@ +// Demo of rewriting a line read by fgets +#include +#include "SdFat.h" + +// SD card chip select pin +const uint8_t chipSelect = SS; + +// file system +SdFat sd; + +// print stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// store error strings in flash memory +#define error(s) sd.errorHalt(F(s)) +//------------------------------------------------------------------------------ +void demoFgets() { + char line[25]; + int c; + uint32_t pos; + + // open test file + SdFile rdfile("fgets.txt", O_RDWR); + + // check for open error + if (!rdfile.isOpen()) { + error("demoFgets"); + } + + // list file + cout << F("-----Before Rewrite\r\n"); + while ((c = rdfile.read()) >= 0) { + Serial.write(c); + } + + rdfile.rewind(); + // read lines from the file to get position + while (1) { + pos = rdfile.curPosition(); + if (rdfile.fgets(line, sizeof(line)) < 0) { + error("Line not found"); + } + // find line that contains "Line C" + if (strstr(line, "Line C")) { + break; + } + } + + // rewrite line with 'C' + if (!rdfile.seekSet(pos)) { + error("seekSet"); + } + rdfile.println("Line R"); + rdfile.rewind(); + + // list file + cout << F("\r\n-----After Rewrite\r\n"); + while ((c = rdfile.read()) >= 0) { + Serial.write(c); + } + + // close so rewrite is not lost + rdfile.close(); +} +//------------------------------------------------------------------------------ +void makeTestFile() { + // create or open test file + SdFile wrfile("fgets.txt", O_WRITE | O_CREAT | O_TRUNC); + + // check for open error + if (!wrfile.isOpen()) { + error("MakeTestFile"); + } + + // write test file + wrfile.print(F( + "Line A\r\n" + "Line B\r\n" + "Line C\r\n" + "Line D\r\n" + "Line E\r\n" + )); + wrfile.close(); +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + makeTestFile(); + + demoFgets(); + + cout << F("\nDone\n"); +} +void loop() {} diff --git a/libraries/SdFat/examples/#attic/readlog/readlog.ino b/libraries/SdFat/examples/#attic/readlog/readlog.ino new file mode 100644 index 0000000..31e9d06 --- /dev/null +++ b/libraries/SdFat/examples/#attic/readlog/readlog.ino @@ -0,0 +1,50 @@ +/* + * Read the logfile created by the eventlog.ino example. + * Demo of pathnames and working directories + */ +#include +#include "SdFat.h" + +// SD chip select pin +const uint8_t chipSelect = SS; + +// file system object +SdFat sd; + +// define a serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void setup() { + int c; + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // set current working directory + if (!sd.chdir("logs/2014/Jan/")) { + sd.errorHalt("chdir failed. Did you run eventlog.ino?"); + } + // open file in current working directory + ifstream file("logfile.txt"); + + if (!file.is_open()) { + sd.errorHalt("open failed"); + } + + // copy the file to Serial + while ((c = file.get()) >= 0) { + cout << (char)c; + } + + cout << "Done" << endl; +} +//------------------------------------------------------------------------------ +void loop() {} \ No newline at end of file diff --git a/libraries/SdFat/examples/#attic/readme.txt b/libraries/SdFat/examples/#attic/readme.txt new file mode 100644 index 0000000..fe0742e --- /dev/null +++ b/libraries/SdFat/examples/#attic/readme.txt @@ -0,0 +1,34 @@ +Old and debug examples. + +AnalogLogger - A simple data logger for one or more analog pins. + +append - This sketch creates a large file by successive + open/write/close operations. + +average - A demonstration of parsing floating point numbers. + +BaseExtCaseTest - Long file name test. + +benchSD - A read/write benchmark for the standard Arduino SD.h library. + +bufstream - ibufsteam to parse a line and obufstream to format a line. + +cin_cout - Demo of ArduinoInStream and ArduinoOutStream. + +eventlog - Append a line to a file - demo of pathnames and streams. + +fgetsRewrite - Demo of rewriting a line read by fgets. + +HelloWorld - Create a serial output stream. + +MiniSerial - SdFat minimal serial support for debug. + +PrintBenchmarkSD - Bench mark SD.h print. + +readlog - Read file. Demo of pathnames and current working directory. + +SD_Size - Determine flash used by SD.h example. + +SdFatSize - Determine flash used by SdFat. + +StreamParseInt - Simple demo of the Stream parsInt() member function. diff --git a/libraries/SdFat/examples/AnalogBinLogger/AnalogBinLogger.h b/libraries/SdFat/examples/AnalogBinLogger/AnalogBinLogger.h new file mode 100644 index 0000000..35a34e5 --- /dev/null +++ b/libraries/SdFat/examples/AnalogBinLogger/AnalogBinLogger.h @@ -0,0 +1,39 @@ +#ifndef AnalogBinLogger_h +#define AnalogBinLogger_h +//------------------------------------------------------------------------------ +// First block of file. +struct metadata_t { + unsigned long adcFrequency; // ADC clock frequency + unsigned long cpuFrequency; // CPU clock frequency + unsigned long sampleInterval; // Sample interval in CPU cycles. + unsigned long recordEightBits; // Size of ADC values, nonzero for 8-bits. + unsigned long pinCount; // Number of analog pins in a sample. + unsigned long pinNumber[123]; // List of pin numbers in a sample. +}; +//------------------------------------------------------------------------------ +// Data block for 8-bit ADC mode. +const size_t DATA_DIM8 = 508; +struct block8_t { + unsigned short count; // count of data values + unsigned short overrun; // count of overruns since last block + unsigned char data[DATA_DIM8]; +}; +//------------------------------------------------------------------------------ +// Data block for 10-bit ADC mode. +const size_t DATA_DIM16 = 254; +struct block16_t { + unsigned short count; // count of data values + unsigned short overrun; // count of overruns since last block + unsigned short data[DATA_DIM16]; +}; +//------------------------------------------------------------------------------ +// Data block for PC use +struct adcdata_t { + unsigned short count; // count of data values + unsigned short overrun; // count of overruns since last block + union { + unsigned char u8[DATA_DIM8]; + unsigned short u16[DATA_DIM16]; + } data; +}; +#endif // AnalogBinLogger_h \ No newline at end of file diff --git a/libraries/SdFat/examples/AnalogBinLogger/AnalogBinLogger.ino b/libraries/SdFat/examples/AnalogBinLogger/AnalogBinLogger.ino new file mode 100644 index 0000000..48c1a61 --- /dev/null +++ b/libraries/SdFat/examples/AnalogBinLogger/AnalogBinLogger.ino @@ -0,0 +1,826 @@ +/** + * This program logs data from the Arduino ADC to a binary file. + * + * Samples are logged at regular intervals. Each Sample consists of the ADC + * values for the analog pins defined in the PIN_LIST array. The pins numbers + * may be in any order. + * + * Edit the configuration constants below to set the sample pins, sample rate, + * and other configuration values. + * + * If your SD card has a long write latency, it may be necessary to use + * slower sample rates. Using a Mega Arduino helps overcome latency + * problems since 13 512 byte buffers will be used. + * + * Each 512 byte data block in the file has a four byte header followed by up + * to 508 bytes of data. (508 values in 8-bit mode or 254 values in 10-bit mode) + * Each block contains an integral number of samples with unused space at the + * end of the block. + * + * Data is written to the file using a SD multiple block write command. + */ +#ifdef __AVR__ +#include +#include "SdFat.h" +#include "FreeStack.h" +#include "AnalogBinLogger.h" +//------------------------------------------------------------------------------ +// Analog pin number list for a sample. Pins may be in any order and pin +// numbers may be repeated. +const uint8_t PIN_LIST[] = {0, 1, 2, 3, 4}; +//------------------------------------------------------------------------------ +// Sample rate in samples per second. +const float SAMPLE_RATE = 5000; // Must be 0.25 or greater. + +// The interval between samples in seconds, SAMPLE_INTERVAL, may be set to a +// constant instead of being calculated from SAMPLE_RATE. SAMPLE_RATE is not +// used in the code below. For example, setting SAMPLE_INTERVAL = 2.0e-4 +// will result in a 200 microsecond sample interval. +const float SAMPLE_INTERVAL = 1.0/SAMPLE_RATE; + +// Setting ROUND_SAMPLE_INTERVAL non-zero will cause the sample interval to +// be rounded to a a multiple of the ADC clock period and will reduce sample +// time jitter. +#define ROUND_SAMPLE_INTERVAL 1 +//------------------------------------------------------------------------------ +// ADC clock rate. +// The ADC clock rate is normally calculated from the pin count and sample +// interval. The calculation attempts to use the lowest possible ADC clock +// rate. +// +// You can select an ADC clock rate by defining the symbol ADC_PRESCALER to +// one of these values. You must choose an appropriate ADC clock rate for +// your sample interval. +// #define ADC_PRESCALER 7 // F_CPU/128 125 kHz on an Uno +// #define ADC_PRESCALER 6 // F_CPU/64 250 kHz on an Uno +// #define ADC_PRESCALER 5 // F_CPU/32 500 kHz on an Uno +// #define ADC_PRESCALER 4 // F_CPU/16 1000 kHz on an Uno +// #define ADC_PRESCALER 3 // F_CPU/8 2000 kHz on an Uno (8-bit mode only) +//------------------------------------------------------------------------------ +// Reference voltage. See the processor data-sheet for reference details. +// uint8_t const ADC_REF = 0; // External Reference AREF pin. +uint8_t const ADC_REF = (1 << REFS0); // Vcc Reference. +// uint8_t const ADC_REF = (1 << REFS1); // Internal 1.1 (only 644 1284P Mega) +// uint8_t const ADC_REF = (1 << REFS1) | (1 << REFS0); // Internal 1.1 or 2.56 +//------------------------------------------------------------------------------ +// File definitions. +// +// Maximum file size in blocks. +// The program creates a contiguous file with FILE_BLOCK_COUNT 512 byte blocks. +// This file is flash erased using special SD commands. The file will be +// truncated if logging is stopped early. +const uint32_t FILE_BLOCK_COUNT = 256000; + +// log file base name. Must be six characters or less. +#define FILE_BASE_NAME "analog" + +// Set RECORD_EIGHT_BITS non-zero to record only the high 8-bits of the ADC. +#define RECORD_EIGHT_BITS 0 +//------------------------------------------------------------------------------ +// Pin definitions. +// +// Digital pin to indicate an error, set to -1 if not used. +// The led blinks for fatal errors. The led goes on solid for SD write +// overrun errors and logging continues. +const int8_t ERROR_LED_PIN = 3; + +// SD chip select pin. +const uint8_t SD_CS_PIN = SS; +//------------------------------------------------------------------------------ +// Buffer definitions. +// +// The logger will use SdFat's buffer plus BUFFER_BLOCK_COUNT additional +// buffers. QUEUE_DIM must be a power of two larger than +//(BUFFER_BLOCK_COUNT + 1). +// +#if RAMEND < 0X8FF +#error Too little SRAM +// +#elif RAMEND < 0X10FF +// Use total of two 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 1; +// Dimension for queues of 512 byte SD blocks. +const uint8_t QUEUE_DIM = 4; // Must be a power of two! +// +#elif RAMEND < 0X20FF +// Use total of five 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 4; +// Dimension for queues of 512 byte SD blocks. +const uint8_t QUEUE_DIM = 8; // Must be a power of two! +// +#elif RAMEND < 0X40FF +// Use total of 13 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 12; +// Dimension for queues of 512 byte SD blocks. +const uint8_t QUEUE_DIM = 16; // Must be a power of two! +// +#else // RAMEND +// Use total of 29 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 28; +// Dimension for queues of 512 byte SD blocks. +const uint8_t QUEUE_DIM = 32; // Must be a power of two! +#endif // RAMEND +//============================================================================== +// End of configuration constants. +//============================================================================== +// Temporary log file. Will be deleted if a reset or power failure occurs. +#define TMP_FILE_NAME "tmp_log.bin" + +// Size of file base name. Must not be larger than six. +const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1; + +// Number of analog pins to log. +const uint8_t PIN_COUNT = sizeof(PIN_LIST)/sizeof(PIN_LIST[0]); + +// Minimum ADC clock cycles per sample interval +const uint16_t MIN_ADC_CYCLES = 15; + +// Extra cpu cycles to setup ADC with more than one pin per sample. +const uint16_t ISR_SETUP_ADC = PIN_COUNT > 1 ? 100 : 0; + +// Maximum cycles for timer0 system interrupt, millis, micros. +const uint16_t ISR_TIMER0 = 160; +//============================================================================== +SdFat sd; + +SdBaseFile binFile; + +char binName[13] = FILE_BASE_NAME "00.bin"; + +#if RECORD_EIGHT_BITS +const size_t SAMPLES_PER_BLOCK = DATA_DIM8/PIN_COUNT; +typedef block8_t block_t; +#else // RECORD_EIGHT_BITS +const size_t SAMPLES_PER_BLOCK = DATA_DIM16/PIN_COUNT; +typedef block16_t block_t; +#endif // RECORD_EIGHT_BITS + +block_t* emptyQueue[QUEUE_DIM]; +uint8_t emptyHead; +uint8_t emptyTail; + +block_t* fullQueue[QUEUE_DIM]; +volatile uint8_t fullHead; // volatile insures non-interrupt code sees changes. +uint8_t fullTail; + +// queueNext assumes QUEUE_DIM is a power of two +inline uint8_t queueNext(uint8_t ht) { + return (ht + 1) & (QUEUE_DIM -1); +} +//============================================================================== +// Interrupt Service Routines + +// Pointer to current buffer. +block_t* isrBuf; + +// Need new buffer if true. +bool isrBufNeeded = true; + +// overrun count +uint16_t isrOver = 0; + +// ADC configuration for each pin. +uint8_t adcmux[PIN_COUNT]; +uint8_t adcsra[PIN_COUNT]; +uint8_t adcsrb[PIN_COUNT]; +uint8_t adcindex = 1; + +// Insure no timer events are missed. +volatile bool timerError = false; +volatile bool timerFlag = false; +//------------------------------------------------------------------------------ +// ADC done interrupt. +ISR(ADC_vect) { + // Read ADC data. +#if RECORD_EIGHT_BITS + uint8_t d = ADCH; +#else // RECORD_EIGHT_BITS + // This will access ADCL first. + uint16_t d = ADC; +#endif // RECORD_EIGHT_BITS + + if (isrBufNeeded && emptyHead == emptyTail) { + // no buffers - count overrun + if (isrOver < 0XFFFF) { + isrOver++; + } + + // Avoid missed timer error. + timerFlag = false; + return; + } + // Start ADC + if (PIN_COUNT > 1) { + ADMUX = adcmux[adcindex]; + ADCSRB = adcsrb[adcindex]; + ADCSRA = adcsra[adcindex]; + if (adcindex == 0) { + timerFlag = false; + } + adcindex = adcindex < (PIN_COUNT - 1) ? adcindex + 1 : 0; + } else { + timerFlag = false; + } + // Check for buffer needed. + if (isrBufNeeded) { + // Remove buffer from empty queue. + isrBuf = emptyQueue[emptyTail]; + emptyTail = queueNext(emptyTail); + isrBuf->count = 0; + isrBuf->overrun = isrOver; + isrBufNeeded = false; + } + // Store ADC data. + isrBuf->data[isrBuf->count++] = d; + + // Check for buffer full. + if (isrBuf->count >= PIN_COUNT*SAMPLES_PER_BLOCK) { + // Put buffer isrIn full queue. + uint8_t tmp = fullHead; // Avoid extra fetch of volatile fullHead. + fullQueue[tmp] = (block_t*)isrBuf; + fullHead = queueNext(tmp); + + // Set buffer needed and clear overruns. + isrBufNeeded = true; + isrOver = 0; + } +} +//------------------------------------------------------------------------------ +// timer1 interrupt to clear OCF1B +ISR(TIMER1_COMPB_vect) { + // Make sure ADC ISR responded to timer event. + if (timerFlag) { + timerError = true; + } + timerFlag = true; +} +//============================================================================== +// Error messages stored in flash. +#define error(msg) {sd.errorPrint(F(msg));fatalBlink();} +//------------------------------------------------------------------------------ +// +void fatalBlink() { + while (true) { + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, HIGH); + delay(200); + digitalWrite(ERROR_LED_PIN, LOW); + delay(200); + } + } +} +//============================================================================== +#if ADPS0 != 0 || ADPS1 != 1 || ADPS2 != 2 +#error unexpected ADC prescaler bits +#endif +//------------------------------------------------------------------------------ +// initialize ADC and timer1 +void adcInit(metadata_t* meta) { + uint8_t adps; // prescaler bits for ADCSRA + uint32_t ticks = F_CPU*SAMPLE_INTERVAL + 0.5; // Sample interval cpu cycles. + + if (ADC_REF & ~((1 << REFS0) | (1 << REFS1))) { + error("Invalid ADC reference"); + } +#ifdef ADC_PRESCALER + if (ADC_PRESCALER > 7 || ADC_PRESCALER < 2) { + error("Invalid ADC prescaler"); + } + adps = ADC_PRESCALER; +#else // ADC_PRESCALER + // Allow extra cpu cycles to change ADC settings if more than one pin. + int32_t adcCycles = (ticks - ISR_TIMER0)/PIN_COUNT - ISR_SETUP_ADC; + + for (adps = 7; adps > 0; adps--) { + if (adcCycles >= (MIN_ADC_CYCLES << adps)) { + break; + } + } +#endif // ADC_PRESCALER + meta->adcFrequency = F_CPU >> adps; + if (meta->adcFrequency > (RECORD_EIGHT_BITS ? 2000000 : 1000000)) { + error("Sample Rate Too High"); + } +#if ROUND_SAMPLE_INTERVAL + // Round so interval is multiple of ADC clock. + ticks += 1 << (adps - 1); + ticks >>= adps; + ticks <<= adps; +#endif // ROUND_SAMPLE_INTERVAL + + if (PIN_COUNT > sizeof(meta->pinNumber)/sizeof(meta->pinNumber[0])) { + error("Too many pins"); + } + meta->pinCount = PIN_COUNT; + meta->recordEightBits = RECORD_EIGHT_BITS; + + for (int i = 0; i < PIN_COUNT; i++) { + uint8_t pin = PIN_LIST[i]; + if (pin >= NUM_ANALOG_INPUTS) { + error("Invalid Analog pin number"); + } + meta->pinNumber[i] = pin; + + // Set ADC reference and low three bits of analog pin number. + adcmux[i] = (pin & 7) | ADC_REF; + if (RECORD_EIGHT_BITS) { + adcmux[i] |= 1 << ADLAR; + } + + // If this is the first pin, trigger on timer/counter 1 compare match B. + adcsrb[i] = i == 0 ? (1 << ADTS2) | (1 << ADTS0) : 0; +#ifdef MUX5 + if (pin > 7) { + adcsrb[i] |= (1 << MUX5); + } +#endif // MUX5 + adcsra[i] = (1 << ADEN) | (1 << ADIE) | adps; + adcsra[i] |= i == 0 ? 1 << ADATE : 1 << ADSC; + } + + // Setup timer1 + TCCR1A = 0; + uint8_t tshift; + if (ticks < 0X10000) { + // no prescale, CTC mode + TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10); + tshift = 0; + } else if (ticks < 0X10000*8) { + // prescale 8, CTC mode + TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); + tshift = 3; + } else if (ticks < 0X10000*64) { + // prescale 64, CTC mode + TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11) | (1 << CS10); + tshift = 6; + } else if (ticks < 0X10000*256) { + // prescale 256, CTC mode + TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12); + tshift = 8; + } else if (ticks < 0X10000*1024) { + // prescale 1024, CTC mode + TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12) | (1 << CS10); + tshift = 10; + } else { + error("Sample Rate Too Slow"); + } + // divide by prescaler + ticks >>= tshift; + // set TOP for timer reset + ICR1 = ticks - 1; + // compare for ADC start + OCR1B = 0; + + // multiply by prescaler + ticks <<= tshift; + + // Sample interval in CPU clock ticks. + meta->sampleInterval = ticks; + meta->cpuFrequency = F_CPU; + float sampleRate = (float)meta->cpuFrequency/meta->sampleInterval; + Serial.print(F("Sample pins:")); + for (uint8_t i = 0; i < meta->pinCount; i++) { + Serial.print(' '); + Serial.print(meta->pinNumber[i], DEC); + } + Serial.println(); + Serial.print(F("ADC bits: ")); + Serial.println(meta->recordEightBits ? 8 : 10); + Serial.print(F("ADC clock kHz: ")); + Serial.println(meta->adcFrequency/1000); + Serial.print(F("Sample Rate: ")); + Serial.println(sampleRate); + Serial.print(F("Sample interval usec: ")); + Serial.println(1000000.0/sampleRate, 4); +} +//------------------------------------------------------------------------------ +// enable ADC and timer1 interrupts +void adcStart() { + // initialize ISR + isrBufNeeded = true; + isrOver = 0; + adcindex = 1; + + // Clear any pending interrupt. + ADCSRA |= 1 << ADIF; + + // Setup for first pin. + ADMUX = adcmux[0]; + ADCSRB = adcsrb[0]; + ADCSRA = adcsra[0]; + + // Enable timer1 interrupts. + timerError = false; + timerFlag = false; + TCNT1 = 0; + TIFR1 = 1 << OCF1B; + TIMSK1 = 1 << OCIE1B; +} +//------------------------------------------------------------------------------ +void adcStop() { + TIMSK1 = 0; + ADCSRA = 0; +} +//------------------------------------------------------------------------------ +// Convert binary file to csv file. +void binaryToCsv() { + uint8_t lastPct = 0; + block_t buf; + metadata_t* pm; + uint32_t t0 = millis(); + char csvName[13]; + StdioStream csvStream; + + if (!binFile.isOpen()) { + Serial.println(F("No current binary file")); + return; + } + binFile.rewind(); + if (!binFile.read(&buf , 512) == 512) { + error("Read metadata failed"); + } + // Create a new csv file. + strcpy(csvName, binName); + strcpy(&csvName[BASE_NAME_SIZE + 3], "csv"); + + if (!csvStream.fopen(csvName, "w")) { + error("open csvStream failed"); + } + Serial.println(); + Serial.print(F("Writing: ")); + Serial.print(csvName); + Serial.println(F(" - type any character to stop")); + pm = (metadata_t*)&buf; + csvStream.print(F("Interval,")); + float intervalMicros = 1.0e6*pm->sampleInterval/(float)pm->cpuFrequency; + csvStream.print(intervalMicros, 4); + csvStream.println(F(",usec")); + for (uint8_t i = 0; i < pm->pinCount; i++) { + if (i) { + csvStream.putc(','); + } + csvStream.print(F("pin")); + csvStream.print(pm->pinNumber[i]); + } + csvStream.println(); + uint32_t tPct = millis(); + while (!Serial.available() && binFile.read(&buf, 512) == 512) { + if (buf.count == 0) { + break; + } + if (buf.overrun) { + csvStream.print(F("OVERRUN,")); + csvStream.println(buf.overrun); + } + for (uint16_t j = 0; j < buf.count; j += PIN_COUNT) { + for (uint16_t i = 0; i < PIN_COUNT; i++) { + if (i) { + csvStream.putc(','); + } + csvStream.print(buf.data[i + j]); + } + csvStream.println(); + } + if ((millis() - tPct) > 1000) { + uint8_t pct = binFile.curPosition()/(binFile.fileSize()/100); + if (pct != lastPct) { + tPct = millis(); + lastPct = pct; + Serial.print(pct, DEC); + Serial.println('%'); + } + } + if (Serial.available()) { + break; + } + } + csvStream.fclose(); + Serial.print(F("Done: ")); + Serial.print(0.001*(millis() - t0)); + Serial.println(F(" Seconds")); +} +//------------------------------------------------------------------------------ +// read data file and check for overruns +void checkOverrun() { + bool headerPrinted = false; + block_t buf; + uint32_t bgnBlock, endBlock; + uint32_t bn = 0; + + if (!binFile.isOpen()) { + Serial.println(F("No current binary file")); + return; + } + if (!binFile.contiguousRange(&bgnBlock, &endBlock)) { + error("contiguousRange failed"); + } + binFile.rewind(); + Serial.println(); + Serial.println(F("Checking overrun errors - type any character to stop")); + if (!binFile.read(&buf , 512) == 512) { + error("Read metadata failed"); + } + bn++; + while (binFile.read(&buf, 512) == 512) { + if (buf.count == 0) { + break; + } + if (buf.overrun) { + if (!headerPrinted) { + Serial.println(); + Serial.println(F("Overruns:")); + Serial.println(F("fileBlockNumber,sdBlockNumber,overrunCount")); + headerPrinted = true; + } + Serial.print(bn); + Serial.print(','); + Serial.print(bgnBlock + bn); + Serial.print(','); + Serial.println(buf.overrun); + } + bn++; + } + if (!headerPrinted) { + Serial.println(F("No errors found")); + } else { + Serial.println(F("Done")); + } +} +//------------------------------------------------------------------------------ +// dump data file to Serial +void dumpData() { + block_t buf; + if (!binFile.isOpen()) { + Serial.println(F("No current binary file")); + return; + } + binFile.rewind(); + if (binFile.read(&buf , 512) != 512) { + error("Read metadata failed"); + } + Serial.println(); + Serial.println(F("Type any character to stop")); + delay(1000); + while (!Serial.available() && binFile.read(&buf , 512) == 512) { + if (buf.count == 0) { + break; + } + if (buf.overrun) { + Serial.print(F("OVERRUN,")); + Serial.println(buf.overrun); + } + for (uint16_t i = 0; i < buf.count; i++) { + Serial.print(buf.data[i], DEC); + if ((i+1)%PIN_COUNT) { + Serial.print(','); + } else { + Serial.println(); + } + } + } + Serial.println(F("Done")); +} +//------------------------------------------------------------------------------ +// log data +// max number of blocks to erase per erase call +uint32_t const ERASE_SIZE = 262144L; +void logData() { + uint32_t bgnBlock, endBlock; + + // Allocate extra buffer space. + block_t block[BUFFER_BLOCK_COUNT]; + + Serial.println(); + + // Initialize ADC and timer1. + adcInit((metadata_t*) &block[0]); + + // Find unused file name. + if (BASE_NAME_SIZE > 6) { + error("FILE_BASE_NAME too long"); + } + while (sd.exists(binName)) { + if (binName[BASE_NAME_SIZE + 1] != '9') { + binName[BASE_NAME_SIZE + 1]++; + } else { + binName[BASE_NAME_SIZE + 1] = '0'; + if (binName[BASE_NAME_SIZE] == '9') { + error("Can't create file name"); + } + binName[BASE_NAME_SIZE]++; + } + } + // Delete old tmp file. + if (sd.exists(TMP_FILE_NAME)) { + Serial.println(F("Deleting tmp file")); + if (!sd.remove(TMP_FILE_NAME)) { + error("Can't remove tmp file"); + } + } + // Create new file. + Serial.println(F("Creating new file")); + binFile.close(); + if (!binFile.createContiguous(TMP_FILE_NAME, 512 * FILE_BLOCK_COUNT)) { + error("createContiguous failed"); + } + // Get the address of the file on the SD. + if (!binFile.contiguousRange(&bgnBlock, &endBlock)) { + error("contiguousRange failed"); + } + // Use SdFat's internal buffer. + uint8_t* cache = (uint8_t*)sd.vol()->cacheClear(); + if (cache == 0) { + error("cacheClear failed"); + } + + // Flash erase all data in the file. + Serial.println(F("Erasing all data")); + uint32_t bgnErase = bgnBlock; + uint32_t endErase; + while (bgnErase < endBlock) { + endErase = bgnErase + ERASE_SIZE; + if (endErase > endBlock) { + endErase = endBlock; + } + if (!sd.card()->erase(bgnErase, endErase)) { + error("erase failed"); + } + bgnErase = endErase + 1; + } + // Start a multiple block write. + if (!sd.card()->writeStart(bgnBlock, FILE_BLOCK_COUNT)) { + error("writeBegin failed"); + } + // Write metadata. + if (!sd.card()->writeData((uint8_t*)&block[0])) { + error("Write metadata failed"); + } + // Initialize queues. + emptyHead = emptyTail = 0; + fullHead = fullTail = 0; + + // Use SdFat buffer for one block. + emptyQueue[emptyHead] = (block_t*)cache; + emptyHead = queueNext(emptyHead); + + // Put rest of buffers in the empty queue. + for (uint8_t i = 0; i < BUFFER_BLOCK_COUNT; i++) { + emptyQueue[emptyHead] = &block[i]; + emptyHead = queueNext(emptyHead); + } + // Give SD time to prepare for big write. + delay(1000); + Serial.println(F("Logging - type any character to stop")); + // Wait for Serial Idle. + Serial.flush(); + delay(10); + uint32_t bn = 1; + uint32_t t0 = millis(); + uint32_t t1 = t0; + uint32_t overruns = 0; + uint32_t count = 0; + uint32_t maxLatency = 0; + + // Start logging interrupts. + adcStart(); + while (1) { + if (fullHead != fullTail) { + // Get address of block to write. + block_t* pBlock = fullQueue[fullTail]; + + // Write block to SD. + uint32_t usec = micros(); + if (!sd.card()->writeData((uint8_t*)pBlock)) { + error("write data failed"); + } + usec = micros() - usec; + t1 = millis(); + if (usec > maxLatency) { + maxLatency = usec; + } + count += pBlock->count; + + // Add overruns and possibly light LED. + if (pBlock->overrun) { + overruns += pBlock->overrun; + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, HIGH); + } + } + // Move block to empty queue. + emptyQueue[emptyHead] = pBlock; + emptyHead = queueNext(emptyHead); + fullTail = queueNext(fullTail); + bn++; + if (bn == FILE_BLOCK_COUNT) { + // File full so stop ISR calls. + adcStop(); + break; + } + } + if (timerError) { + error("Missed timer event - rate too high"); + } + if (Serial.available()) { + // Stop ISR calls. + adcStop(); + if (isrBuf != 0 && isrBuf->count >= PIN_COUNT) { + // Truncate to last complete sample. + isrBuf->count = PIN_COUNT*(isrBuf->count/PIN_COUNT); + // Put buffer in full queue. + fullQueue[fullHead] = isrBuf; + fullHead = queueNext(fullHead); + isrBuf = 0; + } + if (fullHead == fullTail) { + break; + } + } + } + if (!sd.card()->writeStop()) { + error("writeStop failed"); + } + // Truncate file if recording stopped early. + if (bn != FILE_BLOCK_COUNT) { + Serial.println(F("Truncating file")); + if (!binFile.truncate(512L * bn)) { + error("Can't truncate file"); + } + } + if (!binFile.rename(sd.vwd(), binName)) { + error("Can't rename file"); + } + Serial.print(F("File renamed: ")); + Serial.println(binName); + Serial.print(F("Max block write usec: ")); + Serial.println(maxLatency); + Serial.print(F("Record time sec: ")); + Serial.println(0.001*(t1 - t0), 3); + Serial.print(F("Sample count: ")); + Serial.println(count/PIN_COUNT); + Serial.print(F("Samples/sec: ")); + Serial.println((1000.0/PIN_COUNT)*count/(t1-t0)); + Serial.print(F("Overruns: ")); + Serial.println(overruns); + Serial.println(F("Done")); +} +//------------------------------------------------------------------------------ +void setup(void) { + if (ERROR_LED_PIN >= 0) { + pinMode(ERROR_LED_PIN, OUTPUT); + } + Serial.begin(9600); + + // Read the first sample pin to init the ADC. + analogRead(PIN_LIST[0]); + + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(SD_CS_PIN, SD_SCK_MHZ(50))) { + sd.initErrorPrint(); + fatalBlink(); + } +} +//------------------------------------------------------------------------------ +void loop(void) { + // Read any Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + Serial.println(); + Serial.println(F("type:")); + Serial.println(F("c - convert file to csv")); + Serial.println(F("d - dump data to Serial")); + Serial.println(F("e - overrun error details")); + Serial.println(F("r - record ADC data")); + + while(!Serial.available()) { + SysCall::yield(); + } + char c = tolower(Serial.read()); + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, LOW); + } + // Read any Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + + if (c == 'c') { + binaryToCsv(); + } else if (c == 'd') { + dumpData(); + } else if (c == 'e') { + checkOverrun(); + } else if (c == 'r') { + logData(); + } else { + Serial.println(F("Invalid entry")); + } +} +#else // __AVR__ +#error This program is only for AVR. +#endif // __AVR__ \ No newline at end of file diff --git a/libraries/SdFat/examples/DirectoryFunctions/DirectoryFunctions.ino b/libraries/SdFat/examples/DirectoryFunctions/DirectoryFunctions.ino new file mode 100644 index 0000000..13ffc7e --- /dev/null +++ b/libraries/SdFat/examples/DirectoryFunctions/DirectoryFunctions.ino @@ -0,0 +1,124 @@ +/* + * Example use of chdir(), ls(), mkdir(), and rmdir(). + */ +#include +#include "SdFat.h" + +// SD card chip select pin. +const uint8_t chipSelect = SS; +//------------------------------------------------------------------------------ + +// File system object. +SdFat sd; + +// Use for file creation in folders. +SdFile file; + +// Create a Serial output stream. +ArduinoOutStream cout(Serial); + +// Buffer for Serial input. +char cinBuf[40]; + +// Create a serial input stream. +ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); +//============================================================================== +// Error messages stored in flash. +#define error(msg) sd.errorHalt(F(msg)) +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + delay(1000); + + cout << F("Type any character to start\n"); + // Wait for input line and discard. + cin.readline(); + cout << endl; + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + if (sd.exists("Folder1") + || sd.exists("Folder1/file1.txt") + || sd.exists("Folder1/File2.txt")) { + error("Please remove existing Folder1, file1.txt, and File2.txt"); + } + + int rootFileCount = 0; + sd.vwd()->rewind(); + while (file.openNext(sd.vwd(), O_READ)) { + if (!file.isHidden()) { + rootFileCount++; + } + file.close(); + if (rootFileCount > 10) { + error("Too many files in root. Please use an empty SD."); + } + } + if (rootFileCount) { + cout << F("\nPlease use an empty SD for best results.\n\n"); + delay(1000); + } + // Create a new folder. + if (!sd.mkdir("Folder1")) { + error("Create Folder1 failed"); + } + cout << F("Created Folder1\n"); + + // Create a file in Folder1 using a path. + if (!file.open("Folder1/file1.txt", O_CREAT | O_WRITE)) { + error("create Folder1/file1.txt failed"); + } + file.close(); + cout << F("Created Folder1/file1.txt\n"); + + // Change volume working directory to Folder1. + if (!sd.chdir("Folder1")) { + error("chdir failed for Folder1.\n"); + } + cout << F("chdir to Folder1\n"); + + // Create File2.txt in current directory. + if (!file.open("File2.txt", O_CREAT | O_WRITE)) { + error("create File2.txt failed"); + } + file.close(); + cout << F("Created File2.txt in current directory\n"); + + cout << F("\nList of files on the SD.\n"); + sd.ls("/", LS_R); + + // Remove files from current directory. + if (!sd.remove("file1.txt") || !sd.remove("File2.txt")) { + error("remove failed"); + } + cout << F("\nfile1.txt and File2.txt removed.\n"); + + // Change current directory to root. + if (!sd.chdir()) { + error("chdir to root failed.\n"); + } + + cout << F("\nList of files on the SD.\n"); + sd.ls(LS_R); + + // Remove Folder1. + if (!sd.rmdir("Folder1")) { + error("rmdir for Folder1 failed\n"); + } + + cout << F("\nFolder1 removed.\n"); + cout << F("\nList of files on the SD.\n"); + sd.ls(LS_R); + cout << F("Done!\n"); +} +//------------------------------------------------------------------------------ +// Nothing happens in loop. +void loop() {} \ No newline at end of file diff --git a/libraries/SdFat/examples/LongFileName/LongFileName.ino b/libraries/SdFat/examples/LongFileName/LongFileName.ino new file mode 100644 index 0000000..a3fb27a --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/LongFileName.ino @@ -0,0 +1,102 @@ +// Example use of lfnOpenNext and open by index. +// You can use test files located in +// SdFat/examples/LongFileName/testFiles. +#include +#include "SdFat.h" +#include "FreeStack.h" + +// SD card chip select pin. +const uint8_t SD_CS_PIN = SS; + +SdFat sd; +SdFile file; +SdFile dirFile; + +// Number of files found. +uint16_t n = 0; + +// Max of ten files since files are selected with a single digit. +const uint16_t nMax = 10; + +// Position of file's directory entry. +uint16_t dirIndex[nMax]; +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + while (!Serial) {} + delay(1000); + + // Print the location of some test files. + Serial.println(F("\r\n" + "You can use test files located in\r\n" + "SdFat/examples/LongFileName/testFiles")); + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(SD_CS_PIN, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + Serial.println(); + + // List files in root directory. + if (!dirFile.open("/", O_READ)) { + sd.errorHalt("open root failed"); + } + while (n < nMax && file.openNext(&dirFile, O_READ)) { + + // Skip directories and hidden files. + if (!file.isSubDir() && !file.isHidden()) { + + // Save dirIndex of file in directory. + dirIndex[n] = file.dirIndex(); + + // Print the file number and name. + Serial.print(n++); + Serial.write(' '); + file.printName(&Serial); + Serial.println(); + } + file.close(); + } +} +//------------------------------------------------------------------------------ +void loop() { + int c; + + // Read any existing Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + Serial.print(F("\r\nEnter File Number: ")); + + while (!Serial.available()) { + SysCall::yield(); + } + c = Serial.read(); + uint8_t i = c - '0'; + if (!isdigit(c) || i >= n) { + Serial.println(F("Invald number")); + return; + } + Serial.println(i); + if (!file.open(&dirFile, dirIndex[i], O_READ)) { + sd.errorHalt(F("open")); + } + Serial.println(); + + char last = 0; + + // Copy up to 500 characters to Serial. + for (int k = 0; k < 500 && (c = file.read()) > 0; k++) { + Serial.write(last = (char)c); + } + // Add new line if missing from last line. + if (last != '\n') { + Serial.println(); + } + file.close(); + Serial.flush(); + delay(100); +} \ No newline at end of file diff --git a/libraries/SdFat/examples/LongFileName/testFiles/A long name can be 255 characters.txt b/libraries/SdFat/examples/LongFileName/testFiles/A long name can be 255 characters.txt new file mode 100644 index 0000000..62c7a7b --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/testFiles/A long name can be 255 characters.txt @@ -0,0 +1,4 @@ +This is "A long name can be 255 characters.txt" +This file has a typical Long File Name. + +The maximum length of a Long File Name is 255 characters. diff --git a/libraries/SdFat/examples/LongFileName/testFiles/LFN,NAME.TXT b/libraries/SdFat/examples/LongFileName/testFiles/LFN,NAME.TXT new file mode 100644 index 0000000..3fc38d6 --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/testFiles/LFN,NAME.TXT @@ -0,0 +1 @@ +LFN,NAME.TXT is not 8.3 since it has a comma. \ No newline at end of file diff --git a/libraries/SdFat/examples/LongFileName/testFiles/MIXCASE.txt b/libraries/SdFat/examples/LongFileName/testFiles/MIXCASE.txt new file mode 100644 index 0000000..ce66142 --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/testFiles/MIXCASE.txt @@ -0,0 +1,5 @@ +MIXCASE.txt does not have a Long File Name. + +Starting with NT, file names of this form, +have the basename and extension character case +encoded in two bits of the 8.3 directory entry. diff --git a/libraries/SdFat/examples/LongFileName/testFiles/Not_8_3.txt b/libraries/SdFat/examples/LongFileName/testFiles/Not_8_3.txt new file mode 100644 index 0000000..701a34f --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/testFiles/Not_8_3.txt @@ -0,0 +1,2 @@ +Not_8_3.txt has a Long File Name +since the basename is mixed case. \ No newline at end of file diff --git a/libraries/SdFat/examples/LongFileName/testFiles/OK%83.TXT b/libraries/SdFat/examples/LongFileName/testFiles/OK%83.TXT new file mode 100644 index 0000000..6935e78 --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/testFiles/OK%83.TXT @@ -0,0 +1 @@ +OK%83.TXT is a valid 8.3 name. \ No newline at end of file diff --git a/libraries/SdFat/examples/LongFileName/testFiles/STD_8_3.TXT b/libraries/SdFat/examples/LongFileName/testFiles/STD_8_3.TXT new file mode 100644 index 0000000..e0d2234 --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/testFiles/STD_8_3.TXT @@ -0,0 +1 @@ +STD_8_3.TXT - a vanilla 8.3 name. \ No newline at end of file diff --git a/libraries/SdFat/examples/LongFileName/testFiles/With Blank.txt b/libraries/SdFat/examples/LongFileName/testFiles/With Blank.txt new file mode 100644 index 0000000..ef37e07 --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/testFiles/With Blank.txt @@ -0,0 +1,2 @@ +With Blank.txt +Just another example of a Long File Name. diff --git a/libraries/SdFat/examples/LongFileName/testFiles/With.Two dots.txt b/libraries/SdFat/examples/LongFileName/testFiles/With.Two dots.txt new file mode 100644 index 0000000..1739391 --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/testFiles/With.Two dots.txt @@ -0,0 +1,2 @@ +"With Two.dots.txt" +Lots of reasons this is a Long File Name. diff --git a/libraries/SdFat/examples/LongFileName/testFiles/lower.txt b/libraries/SdFat/examples/LongFileName/testFiles/lower.txt new file mode 100644 index 0000000..43a6bd0 --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/testFiles/lower.txt @@ -0,0 +1,5 @@ +lower.txt does not have a Long File Name. + +Starting with NT, file names of this form, +have the basename and extension character case +encoded in two bits of the 8.3 directory entry. diff --git a/libraries/SdFat/examples/LongFileName/testFiles/mixed.TXT b/libraries/SdFat/examples/LongFileName/testFiles/mixed.TXT new file mode 100644 index 0000000..03d9bd0 --- /dev/null +++ b/libraries/SdFat/examples/LongFileName/testFiles/mixed.TXT @@ -0,0 +1,5 @@ +mixed.TXT does not have a Long File Name. + +Starting with NT, file names of this form, +have the basename and extension character case +encoded in two bits of the 8.3 directory entry. \ No newline at end of file diff --git a/libraries/SdFat/examples/LowLatencyLogger/LowLatencyLogger.ino b/libraries/SdFat/examples/LowLatencyLogger/LowLatencyLogger.ino new file mode 100644 index 0000000..35cd382 --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLogger/LowLatencyLogger.ino @@ -0,0 +1,655 @@ +/** + * This program logs data to a binary file. Functions are included + * to convert the binary file to a csv text file. + * + * Samples are logged at regular intervals. The maximum logging rate + * depends on the quality of your SD card and the time required to + * read sensor data. This example has been tested at 500 Hz with + * good SD card on an Uno. 4000 HZ is possible on a Due. + * + * If your SD card has a long write latency, it may be necessary to use + * slower sample rates. Using a Mega Arduino helps overcome latency + * problems since 12 512 byte buffers will be used. + * + * Data is written to the file using a SD multiple block write command. + */ +#include +#include "SdFat.h" +#include "FreeStack.h" +#include "UserTypes.h" + +#ifdef __AVR_ATmega328P__ +#include "MinimumSerial.h" +MinimumSerial MinSerial; +#define Serial MinSerial +#endif // __AVR_ATmega328P__ +//============================================================================== +// Start of configuration constants. +//============================================================================== +// Abort run on an overrun. Data before the overrun will be saved. +#define ABORT_ON_OVERRUN 1 +//------------------------------------------------------------------------------ +//Interval between data records in microseconds. +const uint32_t LOG_INTERVAL_USEC = 2000; +//------------------------------------------------------------------------------ +// Set USE_SHARED_SPI non-zero for use of an SPI sensor. +// May not work for some cards. +#ifndef USE_SHARED_SPI +#define USE_SHARED_SPI 0 +#endif // USE_SHARED_SPI +//------------------------------------------------------------------------------ +// Pin definitions. +// +// SD chip select pin. +const uint8_t SD_CS_PIN = SS; +// +// Digital pin to indicate an error, set to -1 if not used. +// The led blinks for fatal errors. The led goes on solid for +// overrun errors and logging continues unless ABORT_ON_OVERRUN +// is non-zero. +#ifdef ERROR_LED_PIN +#undef ERROR_LED_PIN +#endif // ERROR_LED_PIN +const int8_t ERROR_LED_PIN = -1; +//------------------------------------------------------------------------------ +// File definitions. +// +// Maximum file size in blocks. +// The program creates a contiguous file with FILE_BLOCK_COUNT 512 byte blocks. +// This file is flash erased using special SD commands. The file will be +// truncated if logging is stopped early. +const uint32_t FILE_BLOCK_COUNT = 256000; +// +// log file base name if not defined in UserTypes.h +#ifndef FILE_BASE_NAME +#define FILE_BASE_NAME "data" +#endif // FILE_BASE_NAME +//------------------------------------------------------------------------------ +// Buffer definitions. +// +// The logger will use SdFat's buffer plus BUFFER_BLOCK_COUNT-1 additional +// buffers. +// +#ifndef RAMEND +// Assume ARM. Use total of ten 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 10; +// +#elif RAMEND < 0X8FF +#error Too little SRAM +// +#elif RAMEND < 0X10FF +// Use total of two 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 2; +// +#elif RAMEND < 0X20FF +// Use total of four 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 4; +// +#else // RAMEND +// Use total of 12 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 12; +#endif // RAMEND +//============================================================================== +// End of configuration constants. +//============================================================================== +// Temporary log file. Will be deleted if a reset or power failure occurs. +#define TMP_FILE_NAME FILE_BASE_NAME "##.bin" + +// Size of file base name. +const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1; +const uint8_t FILE_NAME_DIM = BASE_NAME_SIZE + 7; +char binName[FILE_NAME_DIM] = FILE_BASE_NAME "00.bin"; + +SdFat sd; + +SdBaseFile binFile; + +// Number of data records in a block. +const uint16_t DATA_DIM = (512 - 4)/sizeof(data_t); + +//Compute fill so block size is 512 bytes. FILL_DIM may be zero. +const uint16_t FILL_DIM = 512 - 4 - DATA_DIM*sizeof(data_t); + +struct block_t { + uint16_t count; + uint16_t overrun; + data_t data[DATA_DIM]; + uint8_t fill[FILL_DIM]; +}; +//============================================================================== +// Error messages stored in flash. +#define error(msg) {sd.errorPrint(&Serial, F(msg));fatalBlink();} +//------------------------------------------------------------------------------ +// +void fatalBlink() { + while (true) { + SysCall::yield(); + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, HIGH); + delay(200); + digitalWrite(ERROR_LED_PIN, LOW); + delay(200); + } + } +} +//------------------------------------------------------------------------------ +// read data file and check for overruns +void checkOverrun() { + bool headerPrinted = false; + block_t block; + uint32_t bn = 0; + + if (!binFile.isOpen()) { + Serial.println(); + Serial.println(F("No current binary file")); + return; + } + binFile.rewind(); + Serial.println(); + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + Serial.println(F("Checking overrun errors - type any character to stop")); + while (binFile.read(&block, 512) == 512) { + if (block.count == 0) { + break; + } + if (block.overrun) { + if (!headerPrinted) { + Serial.println(); + Serial.println(F("Overruns:")); + Serial.println(F("fileBlockNumber,sdBlockNumber,overrunCount")); + headerPrinted = true; + } + Serial.print(bn); + Serial.print(','); + Serial.print(binFile.firstBlock() + bn); + Serial.print(','); + Serial.println(block.overrun); + } + bn++; + } + if (!headerPrinted) { + Serial.println(F("No errors found")); + } else { + Serial.println(F("Done")); + } +} +//----------------------------------------------------------------------------- +// Convert binary file to csv file. +void binaryToCsv() { + uint8_t lastPct = 0; + block_t block; + uint32_t t0 = millis(); + uint32_t syncCluster = 0; + SdFile csvFile; + char csvName[FILE_NAME_DIM]; + + if (!binFile.isOpen()) { + Serial.println(); + Serial.println(F("No current binary file")); + return; + } + Serial.println(); + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + + // Create a new csvFile. + strcpy(csvName, binName); + strcpy(&csvName[BASE_NAME_SIZE + 3], "csv"); + + if (!csvFile.open(csvName, O_WRITE | O_CREAT | O_TRUNC)) { + error("open csvFile failed"); + } + binFile.rewind(); + Serial.print(F("Writing: ")); + Serial.print(csvName); + Serial.println(F(" - type any character to stop")); + printHeader(&csvFile); + uint32_t tPct = millis(); + while (!Serial.available() && binFile.read(&block, 512) == 512) { + uint16_t i; + if (block.count == 0 || block.count > DATA_DIM) { + break; + } + if (block.overrun) { + csvFile.print(F("OVERRUN,")); + csvFile.println(block.overrun); + } + for (i = 0; i < block.count; i++) { + printData(&csvFile, &block.data[i]); + } + if (csvFile.curCluster() != syncCluster) { + csvFile.sync(); + syncCluster = csvFile.curCluster(); + } + if ((millis() - tPct) > 1000) { + uint8_t pct = binFile.curPosition()/(binFile.fileSize()/100); + if (pct != lastPct) { + tPct = millis(); + lastPct = pct; + Serial.print(pct, DEC); + Serial.println('%'); + } + } + if (Serial.available()) { + break; + } + } + csvFile.close(); + Serial.print(F("Done: ")); + Serial.print(0.001*(millis() - t0)); + Serial.println(F(" Seconds")); +} +//----------------------------------------------------------------------------- +void createBinFile() { + // max number of blocks to erase per erase call + const uint32_t ERASE_SIZE = 262144L; + uint32_t bgnBlock, endBlock; + + // Delete old tmp file. + if (sd.exists(TMP_FILE_NAME)) { + Serial.println(F("Deleting tmp file " TMP_FILE_NAME)); + if (!sd.remove(TMP_FILE_NAME)) { + error("Can't remove tmp file"); + } + } + // Create new file. + Serial.println(F("\nCreating new file")); + binFile.close(); + if (!binFile.createContiguous(TMP_FILE_NAME, 512 * FILE_BLOCK_COUNT)) { + error("createContiguous failed"); + } + // Get the address of the file on the SD. + if (!binFile.contiguousRange(&bgnBlock, &endBlock)) { + error("contiguousRange failed"); + } + // Flash erase all data in the file. + Serial.println(F("Erasing all data")); + uint32_t bgnErase = bgnBlock; + uint32_t endErase; + while (bgnErase < endBlock) { + endErase = bgnErase + ERASE_SIZE; + if (endErase > endBlock) { + endErase = endBlock; + } + if (!sd.card()->erase(bgnErase, endErase)) { + error("erase failed"); + } + bgnErase = endErase + 1; + } +} +//------------------------------------------------------------------------------ +// dump data file to Serial +void dumpData() { + block_t block; + if (!binFile.isOpen()) { + Serial.println(); + Serial.println(F("No current binary file")); + return; + } + binFile.rewind(); + Serial.println(); + Serial.println(F("Type any character to stop")); + delay(1000); + printHeader(&Serial); + while (!Serial.available() && binFile.read(&block , 512) == 512) { + if (block.count == 0) { + break; + } + if (block.overrun) { + Serial.print(F("OVERRUN,")); + Serial.println(block.overrun); + } + for (uint16_t i = 0; i < block.count; i++) { + printData(&Serial, &block.data[i]); + } + } + Serial.println(F("Done")); +} +//------------------------------------------------------------------------------ +// log data +void logData() { + createBinFile(); + recordBinFile(); + renameBinFile(); +} +//------------------------------------------------------------------------------ +void openBinFile() { + char name[FILE_NAME_DIM]; + strcpy(name, binName); + Serial.println(F("\nEnter two digit version")); + Serial.write(name, BASE_NAME_SIZE); + for (int i = 0; i < 2; i++) { + while (!Serial.available()) { + SysCall::yield(); + } + char c = Serial.read(); + Serial.write(c); + if (c < '0' || c > '9') { + Serial.println(F("\nInvalid digit")); + return; + } + name[BASE_NAME_SIZE + i] = c; + } + Serial.println(&name[BASE_NAME_SIZE+2]); + if (!sd.exists(name)) { + Serial.println(F("File does not exist")); + return; + } + binFile.close(); + strcpy(binName, name); + if (!binFile.open(binName, O_READ)) { + Serial.println(F("open failed")); + return; + } + Serial.println(F("File opened")); +} +//------------------------------------------------------------------------------ +void recordBinFile() { + const uint8_t QUEUE_DIM = BUFFER_BLOCK_COUNT + 1; + // Index of last queue location. + const uint8_t QUEUE_LAST = QUEUE_DIM - 1; + + // Allocate extra buffer space. + block_t block[BUFFER_BLOCK_COUNT - 1]; + + block_t* curBlock = 0; + + block_t* emptyStack[BUFFER_BLOCK_COUNT]; + uint8_t emptyTop; + uint8_t minTop; + + block_t* fullQueue[QUEUE_DIM]; + uint8_t fullHead = 0; + uint8_t fullTail = 0; + + // Use SdFat's internal buffer. + emptyStack[0] = (block_t*)sd.vol()->cacheClear(); + if (emptyStack[0] == 0) { + error("cacheClear failed"); + } + // Put rest of buffers on the empty stack. + for (int i = 1; i < BUFFER_BLOCK_COUNT; i++) { + emptyStack[i] = &block[i - 1]; + } + emptyTop = BUFFER_BLOCK_COUNT; + minTop = BUFFER_BLOCK_COUNT; + + // Start a multiple block write. + if (!sd.card()->writeStart(binFile.firstBlock())) { + error("writeStart failed"); + } + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + Serial.println(F("Logging - type any character to stop")); + bool closeFile = false; + uint32_t bn = 0; + uint32_t maxLatency = 0; + uint32_t overrun = 0; + uint32_t overrunTotal = 0; + uint32_t logTime = micros(); + while(1) { + // Time for next data record. + logTime += LOG_INTERVAL_USEC; + if (Serial.available()) { + closeFile = true; + } + if (closeFile) { + if (curBlock != 0) { + // Put buffer in full queue. + fullQueue[fullHead] = curBlock; + fullHead = fullHead < QUEUE_LAST ? fullHead + 1 : 0; + curBlock = 0; + } + } else { + if (curBlock == 0 && emptyTop != 0) { + curBlock = emptyStack[--emptyTop]; + if (emptyTop < minTop) { + minTop = emptyTop; + } + curBlock->count = 0; + curBlock->overrun = overrun; + overrun = 0; + } + if ((int32_t)(logTime - micros()) < 0) { + error("Rate too fast"); + } + int32_t delta; + do { + delta = micros() - logTime; + } while (delta < 0); + if (curBlock == 0) { + overrun++; + overrunTotal++; + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, HIGH); + } +#if ABORT_ON_OVERRUN + Serial.println(F("Overrun abort")); + break; + #endif // ABORT_ON_OVERRUN + } else { +#if USE_SHARED_SPI + sd.card()->spiStop(); +#endif // USE_SHARED_SPI + acquireData(&curBlock->data[curBlock->count++]); +#if USE_SHARED_SPI + sd.card()->spiStart(); +#endif // USE_SHARED_SPI + if (curBlock->count == DATA_DIM) { + fullQueue[fullHead] = curBlock; + fullHead = fullHead < QUEUE_LAST ? fullHead + 1 : 0; + curBlock = 0; + } + } + } + if (fullHead == fullTail) { + // Exit loop if done. + if (closeFile) { + break; + } + } else if (!sd.card()->isBusy()) { + // Get address of block to write. + block_t* pBlock = fullQueue[fullTail]; + fullTail = fullTail < QUEUE_LAST ? fullTail + 1 : 0; + // Write block to SD. + uint32_t usec = micros(); + if (!sd.card()->writeData((uint8_t*)pBlock)) { + error("write data failed"); + } + usec = micros() - usec; + if (usec > maxLatency) { + maxLatency = usec; + } + // Move block to empty queue. + emptyStack[emptyTop++] = pBlock; + bn++; + if (bn == FILE_BLOCK_COUNT) { + // File full so stop + break; + } + } + } + if (!sd.card()->writeStop()) { + error("writeStop failed"); + } + Serial.print(F("Min Free buffers: ")); + Serial.println(minTop); + Serial.print(F("Max block write usec: ")); + Serial.println(maxLatency); + Serial.print(F("Overruns: ")); + Serial.println(overrunTotal); + // Truncate file if recording stopped early. + if (bn != FILE_BLOCK_COUNT) { + Serial.println(F("Truncating file")); + if (!binFile.truncate(512L * bn)) { + error("Can't truncate file"); + } + } +} +//------------------------------------------------------------------------------ +void recoverTmpFile() { + uint16_t count; + if (!binFile.open(TMP_FILE_NAME, O_RDWR)) { + return; + } + if (binFile.read(&count, 2) != 2 || count != DATA_DIM) { + error("Please delete existing " TMP_FILE_NAME); + } + Serial.println(F("\nRecovering data in tmp file " TMP_FILE_NAME)); + uint32_t bgnBlock = 0; + uint32_t endBlock = binFile.fileSize()/512 - 1; + // find last used block. + while (bgnBlock < endBlock) { + uint32_t midBlock = (bgnBlock + endBlock + 1)/2; + binFile.seekSet(512*midBlock); + if (binFile.read(&count, 2) != 2) error("read"); + if (count == 0 || count > DATA_DIM) { + endBlock = midBlock - 1; + } else { + bgnBlock = midBlock; + } + } + // truncate after last used block. + if (!binFile.truncate(512*(bgnBlock + 1))) { + error("Truncate " TMP_FILE_NAME " failed"); + } + renameBinFile(); +} +//----------------------------------------------------------------------------- +void renameBinFile() { + while (sd.exists(binName)) { + if (binName[BASE_NAME_SIZE + 1] != '9') { + binName[BASE_NAME_SIZE + 1]++; + } else { + binName[BASE_NAME_SIZE + 1] = '0'; + if (binName[BASE_NAME_SIZE] == '9') { + error("Can't create file name"); + } + binName[BASE_NAME_SIZE]++; + } + } + if (!binFile.rename(sd.vwd(), binName)) { + error("Can't rename file"); + } + Serial.print(F("File renamed: ")); + Serial.println(binName); + Serial.print(F("File size: ")); + Serial.print(binFile.fileSize()/512); + Serial.println(F(" blocks")); +} +//------------------------------------------------------------------------------ +void testSensor() { + const uint32_t interval = 200000; + int32_t diff; + data_t data; + Serial.println(F("\nTesting - type any character to stop\n")); + // Wait for Serial Idle. + delay(1000); + printHeader(&Serial); + uint32_t m = micros(); + while (!Serial.available()) { + m += interval; + do { + diff = m - micros(); + } while (diff > 0); + acquireData(&data); + printData(&Serial, &data); + } +} +//------------------------------------------------------------------------------ +void setup(void) { + if (ERROR_LED_PIN >= 0) { + pinMode(ERROR_LED_PIN, OUTPUT); + } + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + Serial.print(F("\nFreeStack: ")); + Serial.println(FreeStack()); + Serial.print(F("Records/block: ")); + Serial.println(DATA_DIM); + if (sizeof(block_t) != 512) { + error("Invalid block size"); + } + // Allow userSetup access to SPI bus. + pinMode(SD_CS_PIN, OUTPUT); + digitalWrite(SD_CS_PIN, HIGH); + + // Setup sensors. + userSetup(); + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(SD_CS_PIN, SD_SCK_MHZ(50))) { + sd.initErrorPrint(&Serial); + fatalBlink(); + } + // recover existing tmp file. + if (sd.exists(TMP_FILE_NAME)) { + Serial.println(F("\nType 'Y' to recover existing tmp file " TMP_FILE_NAME)); + while (!Serial.available()) { + SysCall::yield(); + } + if (Serial.read() == 'Y') { + recoverTmpFile(); + } else { + error("'Y' not typed, please manually delete " TMP_FILE_NAME); + } + } +} +//------------------------------------------------------------------------------ +void loop(void) { + // Read any Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + Serial.println(); + Serial.println(F("type:")); + Serial.println(F("b - open existing bin file")); + Serial.println(F("c - convert file to csv")); + Serial.println(F("d - dump data to Serial")); + Serial.println(F("e - overrun error details")); + Serial.println(F("l - list files")); + Serial.println(F("r - record data")); + Serial.println(F("t - test without logging")); + while(!Serial.available()) { + SysCall::yield(); + } +#if WDT_YIELD_TIME_MICROS + Serial.println(F("LowLatencyLogger can not run with watchdog timer")); + SysCall::halt(); +#endif + + char c = tolower(Serial.read()); + + // Discard extra Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, LOW); + } + if (c == 'b') { + openBinFile(); + } else if (c == 'c') { + binaryToCsv(); + } else if (c == 'd') { + dumpData(); + } else if (c == 'e') { + checkOverrun(); + } else if (c == 'l') { + Serial.println(F("\nls:")); + sd.ls(&Serial, LS_SIZE); + } else if (c == 'r') { + logData(); + } else if (c == 't') { + testSensor(); + } else { + Serial.println(F("Invalid entry")); + } +} \ No newline at end of file diff --git a/libraries/SdFat/examples/LowLatencyLogger/UserFunctions.cpp b/libraries/SdFat/examples/LowLatencyLogger/UserFunctions.cpp new file mode 100644 index 0000000..559b11c --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLogger/UserFunctions.cpp @@ -0,0 +1,41 @@ +#include "UserTypes.h" +// User data functions. Modify these functions for your data items. + +// Start time for data +static uint32_t startMicros; + +// Acquire a data record. +void acquireData(data_t* data) { + data->time = micros(); + for (int i = 0; i < ADC_DIM; i++) { + data->adc[i] = analogRead(i); + } +} + +// Print a data record. +void printData(Print* pr, data_t* data) { + if (startMicros == 0) { + startMicros = data->time; + } + pr->print(data->time - startMicros); + for (int i = 0; i < ADC_DIM; i++) { + pr->write(','); + pr->print(data->adc[i]); + } + pr->println(); +} + +// Print data header. +void printHeader(Print* pr) { + startMicros = 0; + pr->print(F("micros")); + for (int i = 0; i < ADC_DIM; i++) { + pr->print(F(",adc")); + pr->print(i); + } + pr->println(); +} + +// Sensor setup +void userSetup() { +} diff --git a/libraries/SdFat/examples/LowLatencyLogger/UserTypes.h b/libraries/SdFat/examples/LowLatencyLogger/UserTypes.h new file mode 100644 index 0000000..7ccae8f --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLogger/UserTypes.h @@ -0,0 +1,15 @@ +#ifndef UserTypes_h +#define UserTypes_h +#include "Arduino.h" +// User data types. Modify for your data items. +#define FILE_BASE_NAME "adc4pin" +const uint8_t ADC_DIM = 4; +struct data_t { + uint32_t time; + uint16_t adc[ADC_DIM]; +}; +void acquireData(data_t* data); +void printData(Print* pr, data_t* data); +void printHeader(Print* pr); +void userSetup(); +#endif // UserTypes_h diff --git a/libraries/SdFat/examples/LowLatencyLoggerADXL345/LowLatencyLogger.ino b/libraries/SdFat/examples/LowLatencyLoggerADXL345/LowLatencyLogger.ino new file mode 100644 index 0000000..35cd382 --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLoggerADXL345/LowLatencyLogger.ino @@ -0,0 +1,655 @@ +/** + * This program logs data to a binary file. Functions are included + * to convert the binary file to a csv text file. + * + * Samples are logged at regular intervals. The maximum logging rate + * depends on the quality of your SD card and the time required to + * read sensor data. This example has been tested at 500 Hz with + * good SD card on an Uno. 4000 HZ is possible on a Due. + * + * If your SD card has a long write latency, it may be necessary to use + * slower sample rates. Using a Mega Arduino helps overcome latency + * problems since 12 512 byte buffers will be used. + * + * Data is written to the file using a SD multiple block write command. + */ +#include +#include "SdFat.h" +#include "FreeStack.h" +#include "UserTypes.h" + +#ifdef __AVR_ATmega328P__ +#include "MinimumSerial.h" +MinimumSerial MinSerial; +#define Serial MinSerial +#endif // __AVR_ATmega328P__ +//============================================================================== +// Start of configuration constants. +//============================================================================== +// Abort run on an overrun. Data before the overrun will be saved. +#define ABORT_ON_OVERRUN 1 +//------------------------------------------------------------------------------ +//Interval between data records in microseconds. +const uint32_t LOG_INTERVAL_USEC = 2000; +//------------------------------------------------------------------------------ +// Set USE_SHARED_SPI non-zero for use of an SPI sensor. +// May not work for some cards. +#ifndef USE_SHARED_SPI +#define USE_SHARED_SPI 0 +#endif // USE_SHARED_SPI +//------------------------------------------------------------------------------ +// Pin definitions. +// +// SD chip select pin. +const uint8_t SD_CS_PIN = SS; +// +// Digital pin to indicate an error, set to -1 if not used. +// The led blinks for fatal errors. The led goes on solid for +// overrun errors and logging continues unless ABORT_ON_OVERRUN +// is non-zero. +#ifdef ERROR_LED_PIN +#undef ERROR_LED_PIN +#endif // ERROR_LED_PIN +const int8_t ERROR_LED_PIN = -1; +//------------------------------------------------------------------------------ +// File definitions. +// +// Maximum file size in blocks. +// The program creates a contiguous file with FILE_BLOCK_COUNT 512 byte blocks. +// This file is flash erased using special SD commands. The file will be +// truncated if logging is stopped early. +const uint32_t FILE_BLOCK_COUNT = 256000; +// +// log file base name if not defined in UserTypes.h +#ifndef FILE_BASE_NAME +#define FILE_BASE_NAME "data" +#endif // FILE_BASE_NAME +//------------------------------------------------------------------------------ +// Buffer definitions. +// +// The logger will use SdFat's buffer plus BUFFER_BLOCK_COUNT-1 additional +// buffers. +// +#ifndef RAMEND +// Assume ARM. Use total of ten 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 10; +// +#elif RAMEND < 0X8FF +#error Too little SRAM +// +#elif RAMEND < 0X10FF +// Use total of two 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 2; +// +#elif RAMEND < 0X20FF +// Use total of four 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 4; +// +#else // RAMEND +// Use total of 12 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 12; +#endif // RAMEND +//============================================================================== +// End of configuration constants. +//============================================================================== +// Temporary log file. Will be deleted if a reset or power failure occurs. +#define TMP_FILE_NAME FILE_BASE_NAME "##.bin" + +// Size of file base name. +const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1; +const uint8_t FILE_NAME_DIM = BASE_NAME_SIZE + 7; +char binName[FILE_NAME_DIM] = FILE_BASE_NAME "00.bin"; + +SdFat sd; + +SdBaseFile binFile; + +// Number of data records in a block. +const uint16_t DATA_DIM = (512 - 4)/sizeof(data_t); + +//Compute fill so block size is 512 bytes. FILL_DIM may be zero. +const uint16_t FILL_DIM = 512 - 4 - DATA_DIM*sizeof(data_t); + +struct block_t { + uint16_t count; + uint16_t overrun; + data_t data[DATA_DIM]; + uint8_t fill[FILL_DIM]; +}; +//============================================================================== +// Error messages stored in flash. +#define error(msg) {sd.errorPrint(&Serial, F(msg));fatalBlink();} +//------------------------------------------------------------------------------ +// +void fatalBlink() { + while (true) { + SysCall::yield(); + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, HIGH); + delay(200); + digitalWrite(ERROR_LED_PIN, LOW); + delay(200); + } + } +} +//------------------------------------------------------------------------------ +// read data file and check for overruns +void checkOverrun() { + bool headerPrinted = false; + block_t block; + uint32_t bn = 0; + + if (!binFile.isOpen()) { + Serial.println(); + Serial.println(F("No current binary file")); + return; + } + binFile.rewind(); + Serial.println(); + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + Serial.println(F("Checking overrun errors - type any character to stop")); + while (binFile.read(&block, 512) == 512) { + if (block.count == 0) { + break; + } + if (block.overrun) { + if (!headerPrinted) { + Serial.println(); + Serial.println(F("Overruns:")); + Serial.println(F("fileBlockNumber,sdBlockNumber,overrunCount")); + headerPrinted = true; + } + Serial.print(bn); + Serial.print(','); + Serial.print(binFile.firstBlock() + bn); + Serial.print(','); + Serial.println(block.overrun); + } + bn++; + } + if (!headerPrinted) { + Serial.println(F("No errors found")); + } else { + Serial.println(F("Done")); + } +} +//----------------------------------------------------------------------------- +// Convert binary file to csv file. +void binaryToCsv() { + uint8_t lastPct = 0; + block_t block; + uint32_t t0 = millis(); + uint32_t syncCluster = 0; + SdFile csvFile; + char csvName[FILE_NAME_DIM]; + + if (!binFile.isOpen()) { + Serial.println(); + Serial.println(F("No current binary file")); + return; + } + Serial.println(); + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + + // Create a new csvFile. + strcpy(csvName, binName); + strcpy(&csvName[BASE_NAME_SIZE + 3], "csv"); + + if (!csvFile.open(csvName, O_WRITE | O_CREAT | O_TRUNC)) { + error("open csvFile failed"); + } + binFile.rewind(); + Serial.print(F("Writing: ")); + Serial.print(csvName); + Serial.println(F(" - type any character to stop")); + printHeader(&csvFile); + uint32_t tPct = millis(); + while (!Serial.available() && binFile.read(&block, 512) == 512) { + uint16_t i; + if (block.count == 0 || block.count > DATA_DIM) { + break; + } + if (block.overrun) { + csvFile.print(F("OVERRUN,")); + csvFile.println(block.overrun); + } + for (i = 0; i < block.count; i++) { + printData(&csvFile, &block.data[i]); + } + if (csvFile.curCluster() != syncCluster) { + csvFile.sync(); + syncCluster = csvFile.curCluster(); + } + if ((millis() - tPct) > 1000) { + uint8_t pct = binFile.curPosition()/(binFile.fileSize()/100); + if (pct != lastPct) { + tPct = millis(); + lastPct = pct; + Serial.print(pct, DEC); + Serial.println('%'); + } + } + if (Serial.available()) { + break; + } + } + csvFile.close(); + Serial.print(F("Done: ")); + Serial.print(0.001*(millis() - t0)); + Serial.println(F(" Seconds")); +} +//----------------------------------------------------------------------------- +void createBinFile() { + // max number of blocks to erase per erase call + const uint32_t ERASE_SIZE = 262144L; + uint32_t bgnBlock, endBlock; + + // Delete old tmp file. + if (sd.exists(TMP_FILE_NAME)) { + Serial.println(F("Deleting tmp file " TMP_FILE_NAME)); + if (!sd.remove(TMP_FILE_NAME)) { + error("Can't remove tmp file"); + } + } + // Create new file. + Serial.println(F("\nCreating new file")); + binFile.close(); + if (!binFile.createContiguous(TMP_FILE_NAME, 512 * FILE_BLOCK_COUNT)) { + error("createContiguous failed"); + } + // Get the address of the file on the SD. + if (!binFile.contiguousRange(&bgnBlock, &endBlock)) { + error("contiguousRange failed"); + } + // Flash erase all data in the file. + Serial.println(F("Erasing all data")); + uint32_t bgnErase = bgnBlock; + uint32_t endErase; + while (bgnErase < endBlock) { + endErase = bgnErase + ERASE_SIZE; + if (endErase > endBlock) { + endErase = endBlock; + } + if (!sd.card()->erase(bgnErase, endErase)) { + error("erase failed"); + } + bgnErase = endErase + 1; + } +} +//------------------------------------------------------------------------------ +// dump data file to Serial +void dumpData() { + block_t block; + if (!binFile.isOpen()) { + Serial.println(); + Serial.println(F("No current binary file")); + return; + } + binFile.rewind(); + Serial.println(); + Serial.println(F("Type any character to stop")); + delay(1000); + printHeader(&Serial); + while (!Serial.available() && binFile.read(&block , 512) == 512) { + if (block.count == 0) { + break; + } + if (block.overrun) { + Serial.print(F("OVERRUN,")); + Serial.println(block.overrun); + } + for (uint16_t i = 0; i < block.count; i++) { + printData(&Serial, &block.data[i]); + } + } + Serial.println(F("Done")); +} +//------------------------------------------------------------------------------ +// log data +void logData() { + createBinFile(); + recordBinFile(); + renameBinFile(); +} +//------------------------------------------------------------------------------ +void openBinFile() { + char name[FILE_NAME_DIM]; + strcpy(name, binName); + Serial.println(F("\nEnter two digit version")); + Serial.write(name, BASE_NAME_SIZE); + for (int i = 0; i < 2; i++) { + while (!Serial.available()) { + SysCall::yield(); + } + char c = Serial.read(); + Serial.write(c); + if (c < '0' || c > '9') { + Serial.println(F("\nInvalid digit")); + return; + } + name[BASE_NAME_SIZE + i] = c; + } + Serial.println(&name[BASE_NAME_SIZE+2]); + if (!sd.exists(name)) { + Serial.println(F("File does not exist")); + return; + } + binFile.close(); + strcpy(binName, name); + if (!binFile.open(binName, O_READ)) { + Serial.println(F("open failed")); + return; + } + Serial.println(F("File opened")); +} +//------------------------------------------------------------------------------ +void recordBinFile() { + const uint8_t QUEUE_DIM = BUFFER_BLOCK_COUNT + 1; + // Index of last queue location. + const uint8_t QUEUE_LAST = QUEUE_DIM - 1; + + // Allocate extra buffer space. + block_t block[BUFFER_BLOCK_COUNT - 1]; + + block_t* curBlock = 0; + + block_t* emptyStack[BUFFER_BLOCK_COUNT]; + uint8_t emptyTop; + uint8_t minTop; + + block_t* fullQueue[QUEUE_DIM]; + uint8_t fullHead = 0; + uint8_t fullTail = 0; + + // Use SdFat's internal buffer. + emptyStack[0] = (block_t*)sd.vol()->cacheClear(); + if (emptyStack[0] == 0) { + error("cacheClear failed"); + } + // Put rest of buffers on the empty stack. + for (int i = 1; i < BUFFER_BLOCK_COUNT; i++) { + emptyStack[i] = &block[i - 1]; + } + emptyTop = BUFFER_BLOCK_COUNT; + minTop = BUFFER_BLOCK_COUNT; + + // Start a multiple block write. + if (!sd.card()->writeStart(binFile.firstBlock())) { + error("writeStart failed"); + } + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + Serial.println(F("Logging - type any character to stop")); + bool closeFile = false; + uint32_t bn = 0; + uint32_t maxLatency = 0; + uint32_t overrun = 0; + uint32_t overrunTotal = 0; + uint32_t logTime = micros(); + while(1) { + // Time for next data record. + logTime += LOG_INTERVAL_USEC; + if (Serial.available()) { + closeFile = true; + } + if (closeFile) { + if (curBlock != 0) { + // Put buffer in full queue. + fullQueue[fullHead] = curBlock; + fullHead = fullHead < QUEUE_LAST ? fullHead + 1 : 0; + curBlock = 0; + } + } else { + if (curBlock == 0 && emptyTop != 0) { + curBlock = emptyStack[--emptyTop]; + if (emptyTop < minTop) { + minTop = emptyTop; + } + curBlock->count = 0; + curBlock->overrun = overrun; + overrun = 0; + } + if ((int32_t)(logTime - micros()) < 0) { + error("Rate too fast"); + } + int32_t delta; + do { + delta = micros() - logTime; + } while (delta < 0); + if (curBlock == 0) { + overrun++; + overrunTotal++; + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, HIGH); + } +#if ABORT_ON_OVERRUN + Serial.println(F("Overrun abort")); + break; + #endif // ABORT_ON_OVERRUN + } else { +#if USE_SHARED_SPI + sd.card()->spiStop(); +#endif // USE_SHARED_SPI + acquireData(&curBlock->data[curBlock->count++]); +#if USE_SHARED_SPI + sd.card()->spiStart(); +#endif // USE_SHARED_SPI + if (curBlock->count == DATA_DIM) { + fullQueue[fullHead] = curBlock; + fullHead = fullHead < QUEUE_LAST ? fullHead + 1 : 0; + curBlock = 0; + } + } + } + if (fullHead == fullTail) { + // Exit loop if done. + if (closeFile) { + break; + } + } else if (!sd.card()->isBusy()) { + // Get address of block to write. + block_t* pBlock = fullQueue[fullTail]; + fullTail = fullTail < QUEUE_LAST ? fullTail + 1 : 0; + // Write block to SD. + uint32_t usec = micros(); + if (!sd.card()->writeData((uint8_t*)pBlock)) { + error("write data failed"); + } + usec = micros() - usec; + if (usec > maxLatency) { + maxLatency = usec; + } + // Move block to empty queue. + emptyStack[emptyTop++] = pBlock; + bn++; + if (bn == FILE_BLOCK_COUNT) { + // File full so stop + break; + } + } + } + if (!sd.card()->writeStop()) { + error("writeStop failed"); + } + Serial.print(F("Min Free buffers: ")); + Serial.println(minTop); + Serial.print(F("Max block write usec: ")); + Serial.println(maxLatency); + Serial.print(F("Overruns: ")); + Serial.println(overrunTotal); + // Truncate file if recording stopped early. + if (bn != FILE_BLOCK_COUNT) { + Serial.println(F("Truncating file")); + if (!binFile.truncate(512L * bn)) { + error("Can't truncate file"); + } + } +} +//------------------------------------------------------------------------------ +void recoverTmpFile() { + uint16_t count; + if (!binFile.open(TMP_FILE_NAME, O_RDWR)) { + return; + } + if (binFile.read(&count, 2) != 2 || count != DATA_DIM) { + error("Please delete existing " TMP_FILE_NAME); + } + Serial.println(F("\nRecovering data in tmp file " TMP_FILE_NAME)); + uint32_t bgnBlock = 0; + uint32_t endBlock = binFile.fileSize()/512 - 1; + // find last used block. + while (bgnBlock < endBlock) { + uint32_t midBlock = (bgnBlock + endBlock + 1)/2; + binFile.seekSet(512*midBlock); + if (binFile.read(&count, 2) != 2) error("read"); + if (count == 0 || count > DATA_DIM) { + endBlock = midBlock - 1; + } else { + bgnBlock = midBlock; + } + } + // truncate after last used block. + if (!binFile.truncate(512*(bgnBlock + 1))) { + error("Truncate " TMP_FILE_NAME " failed"); + } + renameBinFile(); +} +//----------------------------------------------------------------------------- +void renameBinFile() { + while (sd.exists(binName)) { + if (binName[BASE_NAME_SIZE + 1] != '9') { + binName[BASE_NAME_SIZE + 1]++; + } else { + binName[BASE_NAME_SIZE + 1] = '0'; + if (binName[BASE_NAME_SIZE] == '9') { + error("Can't create file name"); + } + binName[BASE_NAME_SIZE]++; + } + } + if (!binFile.rename(sd.vwd(), binName)) { + error("Can't rename file"); + } + Serial.print(F("File renamed: ")); + Serial.println(binName); + Serial.print(F("File size: ")); + Serial.print(binFile.fileSize()/512); + Serial.println(F(" blocks")); +} +//------------------------------------------------------------------------------ +void testSensor() { + const uint32_t interval = 200000; + int32_t diff; + data_t data; + Serial.println(F("\nTesting - type any character to stop\n")); + // Wait for Serial Idle. + delay(1000); + printHeader(&Serial); + uint32_t m = micros(); + while (!Serial.available()) { + m += interval; + do { + diff = m - micros(); + } while (diff > 0); + acquireData(&data); + printData(&Serial, &data); + } +} +//------------------------------------------------------------------------------ +void setup(void) { + if (ERROR_LED_PIN >= 0) { + pinMode(ERROR_LED_PIN, OUTPUT); + } + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + Serial.print(F("\nFreeStack: ")); + Serial.println(FreeStack()); + Serial.print(F("Records/block: ")); + Serial.println(DATA_DIM); + if (sizeof(block_t) != 512) { + error("Invalid block size"); + } + // Allow userSetup access to SPI bus. + pinMode(SD_CS_PIN, OUTPUT); + digitalWrite(SD_CS_PIN, HIGH); + + // Setup sensors. + userSetup(); + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(SD_CS_PIN, SD_SCK_MHZ(50))) { + sd.initErrorPrint(&Serial); + fatalBlink(); + } + // recover existing tmp file. + if (sd.exists(TMP_FILE_NAME)) { + Serial.println(F("\nType 'Y' to recover existing tmp file " TMP_FILE_NAME)); + while (!Serial.available()) { + SysCall::yield(); + } + if (Serial.read() == 'Y') { + recoverTmpFile(); + } else { + error("'Y' not typed, please manually delete " TMP_FILE_NAME); + } + } +} +//------------------------------------------------------------------------------ +void loop(void) { + // Read any Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + Serial.println(); + Serial.println(F("type:")); + Serial.println(F("b - open existing bin file")); + Serial.println(F("c - convert file to csv")); + Serial.println(F("d - dump data to Serial")); + Serial.println(F("e - overrun error details")); + Serial.println(F("l - list files")); + Serial.println(F("r - record data")); + Serial.println(F("t - test without logging")); + while(!Serial.available()) { + SysCall::yield(); + } +#if WDT_YIELD_TIME_MICROS + Serial.println(F("LowLatencyLogger can not run with watchdog timer")); + SysCall::halt(); +#endif + + char c = tolower(Serial.read()); + + // Discard extra Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, LOW); + } + if (c == 'b') { + openBinFile(); + } else if (c == 'c') { + binaryToCsv(); + } else if (c == 'd') { + dumpData(); + } else if (c == 'e') { + checkOverrun(); + } else if (c == 'l') { + Serial.println(F("\nls:")); + sd.ls(&Serial, LS_SIZE); + } else if (c == 'r') { + logData(); + } else if (c == 't') { + testSensor(); + } else { + Serial.println(F("Invalid entry")); + } +} \ No newline at end of file diff --git a/libraries/SdFat/examples/LowLatencyLoggerADXL345/LowLatencyLoggerADXL345.ino b/libraries/SdFat/examples/LowLatencyLoggerADXL345/LowLatencyLoggerADXL345.ino new file mode 100644 index 0000000..91c8fcc --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLoggerADXL345/LowLatencyLoggerADXL345.ino @@ -0,0 +1 @@ +// Empty file with name LowLatencyLoggerADXL345.ino to make IDE happy. \ No newline at end of file diff --git a/libraries/SdFat/examples/LowLatencyLoggerADXL345/UserFunctions.cpp b/libraries/SdFat/examples/LowLatencyLoggerADXL345/UserFunctions.cpp new file mode 100644 index 0000000..71d624f --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLoggerADXL345/UserFunctions.cpp @@ -0,0 +1,70 @@ +#include "UserTypes.h" +// User data functions. Modify these functions for your data items. + +// Start time for data +static uint32_t startMicros; + +const uint8_t ADXL345_CS = 9; + +const uint8_t POWER_CTL = 0x2D; //Power Control Register +const uint8_t DATA_FORMAT = 0x31; +const uint8_t DATAX0 = 0x32; //X-Axis Data 0 +const uint8_t DATAX1 = 0x33; //X-Axis Data 1 +const uint8_t DATAY0 = 0x34; //Y-Axis Data 0 +const uint8_t DATAY1 = 0x35; //Y-Axis Data 1 +const uint8_t DATAZ0 = 0x36; //Z-Axis Data 0 +const uint8_t DATAZ1 = 0x37; //Z-Axis Data 1 + +void writeADXL345Register(const uint8_t registerAddress, const uint8_t value) { + // Max SPI clock frequency is 5 MHz with CPOL = 1 and CPHA = 1. + SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE3)); + digitalWrite(ADXL345_CS, LOW); + SPI.transfer(registerAddress); + SPI.transfer(value); + digitalWrite(ADXL345_CS, HIGH); + SPI.endTransaction(); +} + +void userSetup() { + SPI.begin(); + pinMode(ADXL345_CS, OUTPUT); + digitalWrite(ADXL345_CS, HIGH); + //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register. + writeADXL345Register(DATA_FORMAT, 0x01); + //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register. + writeADXL345Register(POWER_CTL, 0x08); //Measurement mode +} + +// Acquire a data record. +void acquireData(data_t* data) { + // Max SPI clock frequency is 5 MHz with CPOL = 1 and CPHA = 1. + SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE3)); + data->time = micros(); + digitalWrite(ADXL345_CS, LOW); + // Read multiple bytes so or 0XC0 with address. + SPI.transfer(DATAX0 | 0XC0); + data->accel[0] = SPI.transfer(0) | (SPI.transfer(0) << 8); + data->accel[1] = SPI.transfer(0) | (SPI.transfer(0) << 8); + data->accel[2] = SPI.transfer(0) | (SPI.transfer(0) << 8); + digitalWrite(ADXL345_CS, HIGH); + SPI.endTransaction(); +} + +// Print a data record. +void printData(Print* pr, data_t* data) { + if (startMicros == 0) { + startMicros = data->time; + } + pr->print(data->time - startMicros); + for (int i = 0; i < ACCEL_DIM; i++) { + pr->write(','); + pr->print(data->accel[i]); + } + pr->println(); +} + +// Print data header. +void printHeader(Print* pr) { + startMicros = 0; + pr->println(F("micros,ax,ay,az")); +} diff --git a/libraries/SdFat/examples/LowLatencyLoggerADXL345/UserTypes.h b/libraries/SdFat/examples/LowLatencyLoggerADXL345/UserTypes.h new file mode 100644 index 0000000..56bc873 --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLoggerADXL345/UserTypes.h @@ -0,0 +1,17 @@ +#ifndef UserTypes_h +#define UserTypes_h +#include "Arduino.h" +#include "SPI.h" +#define USE_SHARED_SPI 1 +#define FILE_BASE_NAME "ADXL4G" +// User data types. Modify for your data items. +const uint8_t ACCEL_DIM = 3; +struct data_t { + uint32_t time; + int16_t accel[ACCEL_DIM]; +}; +void acquireData(data_t* data); +void printData(Print* pr, data_t* data); +void printHeader(Print* pr); +void userSetup(); +#endif // UserTypes_h diff --git a/libraries/SdFat/examples/LowLatencyLoggerADXL345/readme.txt b/libraries/SdFat/examples/LowLatencyLoggerADXL345/readme.txt new file mode 100644 index 0000000..a68ba78 --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLoggerADXL345/readme.txt @@ -0,0 +1 @@ +Test of shared SPI for LowLatencyLogger. \ No newline at end of file diff --git a/libraries/SdFat/examples/LowLatencyLoggerMPU6050/LowLatencyLogger.ino b/libraries/SdFat/examples/LowLatencyLoggerMPU6050/LowLatencyLogger.ino new file mode 100644 index 0000000..35cd382 --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLoggerMPU6050/LowLatencyLogger.ino @@ -0,0 +1,655 @@ +/** + * This program logs data to a binary file. Functions are included + * to convert the binary file to a csv text file. + * + * Samples are logged at regular intervals. The maximum logging rate + * depends on the quality of your SD card and the time required to + * read sensor data. This example has been tested at 500 Hz with + * good SD card on an Uno. 4000 HZ is possible on a Due. + * + * If your SD card has a long write latency, it may be necessary to use + * slower sample rates. Using a Mega Arduino helps overcome latency + * problems since 12 512 byte buffers will be used. + * + * Data is written to the file using a SD multiple block write command. + */ +#include +#include "SdFat.h" +#include "FreeStack.h" +#include "UserTypes.h" + +#ifdef __AVR_ATmega328P__ +#include "MinimumSerial.h" +MinimumSerial MinSerial; +#define Serial MinSerial +#endif // __AVR_ATmega328P__ +//============================================================================== +// Start of configuration constants. +//============================================================================== +// Abort run on an overrun. Data before the overrun will be saved. +#define ABORT_ON_OVERRUN 1 +//------------------------------------------------------------------------------ +//Interval between data records in microseconds. +const uint32_t LOG_INTERVAL_USEC = 2000; +//------------------------------------------------------------------------------ +// Set USE_SHARED_SPI non-zero for use of an SPI sensor. +// May not work for some cards. +#ifndef USE_SHARED_SPI +#define USE_SHARED_SPI 0 +#endif // USE_SHARED_SPI +//------------------------------------------------------------------------------ +// Pin definitions. +// +// SD chip select pin. +const uint8_t SD_CS_PIN = SS; +// +// Digital pin to indicate an error, set to -1 if not used. +// The led blinks for fatal errors. The led goes on solid for +// overrun errors and logging continues unless ABORT_ON_OVERRUN +// is non-zero. +#ifdef ERROR_LED_PIN +#undef ERROR_LED_PIN +#endif // ERROR_LED_PIN +const int8_t ERROR_LED_PIN = -1; +//------------------------------------------------------------------------------ +// File definitions. +// +// Maximum file size in blocks. +// The program creates a contiguous file with FILE_BLOCK_COUNT 512 byte blocks. +// This file is flash erased using special SD commands. The file will be +// truncated if logging is stopped early. +const uint32_t FILE_BLOCK_COUNT = 256000; +// +// log file base name if not defined in UserTypes.h +#ifndef FILE_BASE_NAME +#define FILE_BASE_NAME "data" +#endif // FILE_BASE_NAME +//------------------------------------------------------------------------------ +// Buffer definitions. +// +// The logger will use SdFat's buffer plus BUFFER_BLOCK_COUNT-1 additional +// buffers. +// +#ifndef RAMEND +// Assume ARM. Use total of ten 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 10; +// +#elif RAMEND < 0X8FF +#error Too little SRAM +// +#elif RAMEND < 0X10FF +// Use total of two 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 2; +// +#elif RAMEND < 0X20FF +// Use total of four 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 4; +// +#else // RAMEND +// Use total of 12 512 byte buffers. +const uint8_t BUFFER_BLOCK_COUNT = 12; +#endif // RAMEND +//============================================================================== +// End of configuration constants. +//============================================================================== +// Temporary log file. Will be deleted if a reset or power failure occurs. +#define TMP_FILE_NAME FILE_BASE_NAME "##.bin" + +// Size of file base name. +const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1; +const uint8_t FILE_NAME_DIM = BASE_NAME_SIZE + 7; +char binName[FILE_NAME_DIM] = FILE_BASE_NAME "00.bin"; + +SdFat sd; + +SdBaseFile binFile; + +// Number of data records in a block. +const uint16_t DATA_DIM = (512 - 4)/sizeof(data_t); + +//Compute fill so block size is 512 bytes. FILL_DIM may be zero. +const uint16_t FILL_DIM = 512 - 4 - DATA_DIM*sizeof(data_t); + +struct block_t { + uint16_t count; + uint16_t overrun; + data_t data[DATA_DIM]; + uint8_t fill[FILL_DIM]; +}; +//============================================================================== +// Error messages stored in flash. +#define error(msg) {sd.errorPrint(&Serial, F(msg));fatalBlink();} +//------------------------------------------------------------------------------ +// +void fatalBlink() { + while (true) { + SysCall::yield(); + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, HIGH); + delay(200); + digitalWrite(ERROR_LED_PIN, LOW); + delay(200); + } + } +} +//------------------------------------------------------------------------------ +// read data file and check for overruns +void checkOverrun() { + bool headerPrinted = false; + block_t block; + uint32_t bn = 0; + + if (!binFile.isOpen()) { + Serial.println(); + Serial.println(F("No current binary file")); + return; + } + binFile.rewind(); + Serial.println(); + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + Serial.println(F("Checking overrun errors - type any character to stop")); + while (binFile.read(&block, 512) == 512) { + if (block.count == 0) { + break; + } + if (block.overrun) { + if (!headerPrinted) { + Serial.println(); + Serial.println(F("Overruns:")); + Serial.println(F("fileBlockNumber,sdBlockNumber,overrunCount")); + headerPrinted = true; + } + Serial.print(bn); + Serial.print(','); + Serial.print(binFile.firstBlock() + bn); + Serial.print(','); + Serial.println(block.overrun); + } + bn++; + } + if (!headerPrinted) { + Serial.println(F("No errors found")); + } else { + Serial.println(F("Done")); + } +} +//----------------------------------------------------------------------------- +// Convert binary file to csv file. +void binaryToCsv() { + uint8_t lastPct = 0; + block_t block; + uint32_t t0 = millis(); + uint32_t syncCluster = 0; + SdFile csvFile; + char csvName[FILE_NAME_DIM]; + + if (!binFile.isOpen()) { + Serial.println(); + Serial.println(F("No current binary file")); + return; + } + Serial.println(); + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + + // Create a new csvFile. + strcpy(csvName, binName); + strcpy(&csvName[BASE_NAME_SIZE + 3], "csv"); + + if (!csvFile.open(csvName, O_WRITE | O_CREAT | O_TRUNC)) { + error("open csvFile failed"); + } + binFile.rewind(); + Serial.print(F("Writing: ")); + Serial.print(csvName); + Serial.println(F(" - type any character to stop")); + printHeader(&csvFile); + uint32_t tPct = millis(); + while (!Serial.available() && binFile.read(&block, 512) == 512) { + uint16_t i; + if (block.count == 0 || block.count > DATA_DIM) { + break; + } + if (block.overrun) { + csvFile.print(F("OVERRUN,")); + csvFile.println(block.overrun); + } + for (i = 0; i < block.count; i++) { + printData(&csvFile, &block.data[i]); + } + if (csvFile.curCluster() != syncCluster) { + csvFile.sync(); + syncCluster = csvFile.curCluster(); + } + if ((millis() - tPct) > 1000) { + uint8_t pct = binFile.curPosition()/(binFile.fileSize()/100); + if (pct != lastPct) { + tPct = millis(); + lastPct = pct; + Serial.print(pct, DEC); + Serial.println('%'); + } + } + if (Serial.available()) { + break; + } + } + csvFile.close(); + Serial.print(F("Done: ")); + Serial.print(0.001*(millis() - t0)); + Serial.println(F(" Seconds")); +} +//----------------------------------------------------------------------------- +void createBinFile() { + // max number of blocks to erase per erase call + const uint32_t ERASE_SIZE = 262144L; + uint32_t bgnBlock, endBlock; + + // Delete old tmp file. + if (sd.exists(TMP_FILE_NAME)) { + Serial.println(F("Deleting tmp file " TMP_FILE_NAME)); + if (!sd.remove(TMP_FILE_NAME)) { + error("Can't remove tmp file"); + } + } + // Create new file. + Serial.println(F("\nCreating new file")); + binFile.close(); + if (!binFile.createContiguous(TMP_FILE_NAME, 512 * FILE_BLOCK_COUNT)) { + error("createContiguous failed"); + } + // Get the address of the file on the SD. + if (!binFile.contiguousRange(&bgnBlock, &endBlock)) { + error("contiguousRange failed"); + } + // Flash erase all data in the file. + Serial.println(F("Erasing all data")); + uint32_t bgnErase = bgnBlock; + uint32_t endErase; + while (bgnErase < endBlock) { + endErase = bgnErase + ERASE_SIZE; + if (endErase > endBlock) { + endErase = endBlock; + } + if (!sd.card()->erase(bgnErase, endErase)) { + error("erase failed"); + } + bgnErase = endErase + 1; + } +} +//------------------------------------------------------------------------------ +// dump data file to Serial +void dumpData() { + block_t block; + if (!binFile.isOpen()) { + Serial.println(); + Serial.println(F("No current binary file")); + return; + } + binFile.rewind(); + Serial.println(); + Serial.println(F("Type any character to stop")); + delay(1000); + printHeader(&Serial); + while (!Serial.available() && binFile.read(&block , 512) == 512) { + if (block.count == 0) { + break; + } + if (block.overrun) { + Serial.print(F("OVERRUN,")); + Serial.println(block.overrun); + } + for (uint16_t i = 0; i < block.count; i++) { + printData(&Serial, &block.data[i]); + } + } + Serial.println(F("Done")); +} +//------------------------------------------------------------------------------ +// log data +void logData() { + createBinFile(); + recordBinFile(); + renameBinFile(); +} +//------------------------------------------------------------------------------ +void openBinFile() { + char name[FILE_NAME_DIM]; + strcpy(name, binName); + Serial.println(F("\nEnter two digit version")); + Serial.write(name, BASE_NAME_SIZE); + for (int i = 0; i < 2; i++) { + while (!Serial.available()) { + SysCall::yield(); + } + char c = Serial.read(); + Serial.write(c); + if (c < '0' || c > '9') { + Serial.println(F("\nInvalid digit")); + return; + } + name[BASE_NAME_SIZE + i] = c; + } + Serial.println(&name[BASE_NAME_SIZE+2]); + if (!sd.exists(name)) { + Serial.println(F("File does not exist")); + return; + } + binFile.close(); + strcpy(binName, name); + if (!binFile.open(binName, O_READ)) { + Serial.println(F("open failed")); + return; + } + Serial.println(F("File opened")); +} +//------------------------------------------------------------------------------ +void recordBinFile() { + const uint8_t QUEUE_DIM = BUFFER_BLOCK_COUNT + 1; + // Index of last queue location. + const uint8_t QUEUE_LAST = QUEUE_DIM - 1; + + // Allocate extra buffer space. + block_t block[BUFFER_BLOCK_COUNT - 1]; + + block_t* curBlock = 0; + + block_t* emptyStack[BUFFER_BLOCK_COUNT]; + uint8_t emptyTop; + uint8_t minTop; + + block_t* fullQueue[QUEUE_DIM]; + uint8_t fullHead = 0; + uint8_t fullTail = 0; + + // Use SdFat's internal buffer. + emptyStack[0] = (block_t*)sd.vol()->cacheClear(); + if (emptyStack[0] == 0) { + error("cacheClear failed"); + } + // Put rest of buffers on the empty stack. + for (int i = 1; i < BUFFER_BLOCK_COUNT; i++) { + emptyStack[i] = &block[i - 1]; + } + emptyTop = BUFFER_BLOCK_COUNT; + minTop = BUFFER_BLOCK_COUNT; + + // Start a multiple block write. + if (!sd.card()->writeStart(binFile.firstBlock())) { + error("writeStart failed"); + } + Serial.print(F("FreeStack: ")); + Serial.println(FreeStack()); + Serial.println(F("Logging - type any character to stop")); + bool closeFile = false; + uint32_t bn = 0; + uint32_t maxLatency = 0; + uint32_t overrun = 0; + uint32_t overrunTotal = 0; + uint32_t logTime = micros(); + while(1) { + // Time for next data record. + logTime += LOG_INTERVAL_USEC; + if (Serial.available()) { + closeFile = true; + } + if (closeFile) { + if (curBlock != 0) { + // Put buffer in full queue. + fullQueue[fullHead] = curBlock; + fullHead = fullHead < QUEUE_LAST ? fullHead + 1 : 0; + curBlock = 0; + } + } else { + if (curBlock == 0 && emptyTop != 0) { + curBlock = emptyStack[--emptyTop]; + if (emptyTop < minTop) { + minTop = emptyTop; + } + curBlock->count = 0; + curBlock->overrun = overrun; + overrun = 0; + } + if ((int32_t)(logTime - micros()) < 0) { + error("Rate too fast"); + } + int32_t delta; + do { + delta = micros() - logTime; + } while (delta < 0); + if (curBlock == 0) { + overrun++; + overrunTotal++; + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, HIGH); + } +#if ABORT_ON_OVERRUN + Serial.println(F("Overrun abort")); + break; + #endif // ABORT_ON_OVERRUN + } else { +#if USE_SHARED_SPI + sd.card()->spiStop(); +#endif // USE_SHARED_SPI + acquireData(&curBlock->data[curBlock->count++]); +#if USE_SHARED_SPI + sd.card()->spiStart(); +#endif // USE_SHARED_SPI + if (curBlock->count == DATA_DIM) { + fullQueue[fullHead] = curBlock; + fullHead = fullHead < QUEUE_LAST ? fullHead + 1 : 0; + curBlock = 0; + } + } + } + if (fullHead == fullTail) { + // Exit loop if done. + if (closeFile) { + break; + } + } else if (!sd.card()->isBusy()) { + // Get address of block to write. + block_t* pBlock = fullQueue[fullTail]; + fullTail = fullTail < QUEUE_LAST ? fullTail + 1 : 0; + // Write block to SD. + uint32_t usec = micros(); + if (!sd.card()->writeData((uint8_t*)pBlock)) { + error("write data failed"); + } + usec = micros() - usec; + if (usec > maxLatency) { + maxLatency = usec; + } + // Move block to empty queue. + emptyStack[emptyTop++] = pBlock; + bn++; + if (bn == FILE_BLOCK_COUNT) { + // File full so stop + break; + } + } + } + if (!sd.card()->writeStop()) { + error("writeStop failed"); + } + Serial.print(F("Min Free buffers: ")); + Serial.println(minTop); + Serial.print(F("Max block write usec: ")); + Serial.println(maxLatency); + Serial.print(F("Overruns: ")); + Serial.println(overrunTotal); + // Truncate file if recording stopped early. + if (bn != FILE_BLOCK_COUNT) { + Serial.println(F("Truncating file")); + if (!binFile.truncate(512L * bn)) { + error("Can't truncate file"); + } + } +} +//------------------------------------------------------------------------------ +void recoverTmpFile() { + uint16_t count; + if (!binFile.open(TMP_FILE_NAME, O_RDWR)) { + return; + } + if (binFile.read(&count, 2) != 2 || count != DATA_DIM) { + error("Please delete existing " TMP_FILE_NAME); + } + Serial.println(F("\nRecovering data in tmp file " TMP_FILE_NAME)); + uint32_t bgnBlock = 0; + uint32_t endBlock = binFile.fileSize()/512 - 1; + // find last used block. + while (bgnBlock < endBlock) { + uint32_t midBlock = (bgnBlock + endBlock + 1)/2; + binFile.seekSet(512*midBlock); + if (binFile.read(&count, 2) != 2) error("read"); + if (count == 0 || count > DATA_DIM) { + endBlock = midBlock - 1; + } else { + bgnBlock = midBlock; + } + } + // truncate after last used block. + if (!binFile.truncate(512*(bgnBlock + 1))) { + error("Truncate " TMP_FILE_NAME " failed"); + } + renameBinFile(); +} +//----------------------------------------------------------------------------- +void renameBinFile() { + while (sd.exists(binName)) { + if (binName[BASE_NAME_SIZE + 1] != '9') { + binName[BASE_NAME_SIZE + 1]++; + } else { + binName[BASE_NAME_SIZE + 1] = '0'; + if (binName[BASE_NAME_SIZE] == '9') { + error("Can't create file name"); + } + binName[BASE_NAME_SIZE]++; + } + } + if (!binFile.rename(sd.vwd(), binName)) { + error("Can't rename file"); + } + Serial.print(F("File renamed: ")); + Serial.println(binName); + Serial.print(F("File size: ")); + Serial.print(binFile.fileSize()/512); + Serial.println(F(" blocks")); +} +//------------------------------------------------------------------------------ +void testSensor() { + const uint32_t interval = 200000; + int32_t diff; + data_t data; + Serial.println(F("\nTesting - type any character to stop\n")); + // Wait for Serial Idle. + delay(1000); + printHeader(&Serial); + uint32_t m = micros(); + while (!Serial.available()) { + m += interval; + do { + diff = m - micros(); + } while (diff > 0); + acquireData(&data); + printData(&Serial, &data); + } +} +//------------------------------------------------------------------------------ +void setup(void) { + if (ERROR_LED_PIN >= 0) { + pinMode(ERROR_LED_PIN, OUTPUT); + } + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + Serial.print(F("\nFreeStack: ")); + Serial.println(FreeStack()); + Serial.print(F("Records/block: ")); + Serial.println(DATA_DIM); + if (sizeof(block_t) != 512) { + error("Invalid block size"); + } + // Allow userSetup access to SPI bus. + pinMode(SD_CS_PIN, OUTPUT); + digitalWrite(SD_CS_PIN, HIGH); + + // Setup sensors. + userSetup(); + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(SD_CS_PIN, SD_SCK_MHZ(50))) { + sd.initErrorPrint(&Serial); + fatalBlink(); + } + // recover existing tmp file. + if (sd.exists(TMP_FILE_NAME)) { + Serial.println(F("\nType 'Y' to recover existing tmp file " TMP_FILE_NAME)); + while (!Serial.available()) { + SysCall::yield(); + } + if (Serial.read() == 'Y') { + recoverTmpFile(); + } else { + error("'Y' not typed, please manually delete " TMP_FILE_NAME); + } + } +} +//------------------------------------------------------------------------------ +void loop(void) { + // Read any Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + Serial.println(); + Serial.println(F("type:")); + Serial.println(F("b - open existing bin file")); + Serial.println(F("c - convert file to csv")); + Serial.println(F("d - dump data to Serial")); + Serial.println(F("e - overrun error details")); + Serial.println(F("l - list files")); + Serial.println(F("r - record data")); + Serial.println(F("t - test without logging")); + while(!Serial.available()) { + SysCall::yield(); + } +#if WDT_YIELD_TIME_MICROS + Serial.println(F("LowLatencyLogger can not run with watchdog timer")); + SysCall::halt(); +#endif + + char c = tolower(Serial.read()); + + // Discard extra Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + + if (ERROR_LED_PIN >= 0) { + digitalWrite(ERROR_LED_PIN, LOW); + } + if (c == 'b') { + openBinFile(); + } else if (c == 'c') { + binaryToCsv(); + } else if (c == 'd') { + dumpData(); + } else if (c == 'e') { + checkOverrun(); + } else if (c == 'l') { + Serial.println(F("\nls:")); + sd.ls(&Serial, LS_SIZE); + } else if (c == 'r') { + logData(); + } else if (c == 't') { + testSensor(); + } else { + Serial.println(F("Invalid entry")); + } +} \ No newline at end of file diff --git a/libraries/SdFat/examples/LowLatencyLoggerMPU6050/LowLatencyLoggerMPU6050.ino b/libraries/SdFat/examples/LowLatencyLoggerMPU6050/LowLatencyLoggerMPU6050.ino new file mode 100644 index 0000000..53bfe06 --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLoggerMPU6050/LowLatencyLoggerMPU6050.ino @@ -0,0 +1,2 @@ +// Empty file with name LowLatencyLoggerMPU6050.ino to make IDE happy. + diff --git a/libraries/SdFat/examples/LowLatencyLoggerMPU6050/UserFunctions.cpp b/libraries/SdFat/examples/LowLatencyLoggerMPU6050/UserFunctions.cpp new file mode 100644 index 0000000..606a40d --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLoggerMPU6050/UserFunctions.cpp @@ -0,0 +1,51 @@ +// User data functions. Modify these functions for your data items. +#include "UserTypes.h" +#include "Wire.h" +#include "I2Cdev.h" +#include "MPU6050.h" +//------------------------------------------------------------------------------ +MPU6050 mpu; +static uint32_t startMicros; +// Acquire a data record. +void acquireData(data_t* data) { + data->time = micros(); + mpu.getMotion6(&data->ax, &data->ay, &data->az, + &data->gx, &data->gy, &data->gz); +} + +// setup AVR I2C +void userSetup() { +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(); + Wire.setClock(400000); +#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); +#endif + mpu.initialize(); +} + +// Print a data record. +void printData(Print* pr, data_t* data) { + if (startMicros == 0) { + startMicros = data->time; + } + pr->print(data->time- startMicros); + pr->write(','); + pr->print(data->ax); + pr->write(','); + pr->print(data->ay); + pr->write(','); + pr->print(data->az); + pr->write(','); + pr->print(data->gx); + pr->write(','); + pr->print(data->gy); + pr->write(','); + pr->println(data->gz); +} + +// Print data header. +void printHeader(Print* pr) { + startMicros = 0; + pr->println(F("micros,ax,ay,az,gx,gy,gz")); +} diff --git a/libraries/SdFat/examples/LowLatencyLoggerMPU6050/UserTypes.h b/libraries/SdFat/examples/LowLatencyLoggerMPU6050/UserTypes.h new file mode 100644 index 0000000..73c2a42 --- /dev/null +++ b/libraries/SdFat/examples/LowLatencyLoggerMPU6050/UserTypes.h @@ -0,0 +1,18 @@ +#ifndef UserTypes_h +#define UserTypes_h +#include "Arduino.h" +#define FILE_BASE_NAME "mpuraw" +struct data_t { + unsigned long time; + int16_t ax; + int16_t ay; + int16_t az; + int16_t gx; + int16_t gy; + int16_t gz; +}; +void acquireData(data_t* data); +void printData(Print* pr, data_t* data); +void printHeader(Print* pr); +void userSetup(); +#endif // UserTypes_h diff --git a/libraries/SdFat/examples/OpenNext/OpenNext.ino b/libraries/SdFat/examples/OpenNext/OpenNext.ino new file mode 100644 index 0000000..65dee76 --- /dev/null +++ b/libraries/SdFat/examples/OpenNext/OpenNext.ino @@ -0,0 +1,54 @@ +/* + * Print size, modify date/time, and name for all files in root. + */ +#include +#include "SdFat.h" + +// SD default chip select pin. +const uint8_t chipSelect = SS; + +// file system object +SdFat sd; + +SdFile file; +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + + Serial.println("Type any character to start"); + while (!Serial.available()) { + SysCall::yield(); + } + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // Open next file in root. The volume working directory, vwd, is root. + // Warning, openNext starts at the current position of sd.vwd() so a + // rewind may be neccessary in your application. + sd.vwd()->rewind(); + while (file.openNext(sd.vwd(), O_READ)) { + file.printFileSize(&Serial); + Serial.write(' '); + file.printModifyDateTime(&Serial); + Serial.write(' '); + file.printName(&Serial); + if (file.isDir()) { + // Indicate a directory. + Serial.write('/'); + } + Serial.println(); + file.close(); + } + Serial.println("Done!"); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/examples/PrintBenchmark/PrintBenchmark.ino b/libraries/SdFat/examples/PrintBenchmark/PrintBenchmark.ino new file mode 100644 index 0000000..4bd39dd --- /dev/null +++ b/libraries/SdFat/examples/PrintBenchmark/PrintBenchmark.ino @@ -0,0 +1,151 @@ +/* + * This program is a simple Print benchmark. + */ +#include +#include "SdFat.h" +#include "FreeStack.h" + +// SD chip select pin +const uint8_t chipSelect = SS; + +// number of lines to print +const uint16_t N_PRINT = 20000; + +// file system +SdFat sd; + +// test file +SdFile file; + +// Serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// store error strings in flash to save RAM +#define error(s) sd.errorHalt(F(s)) +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } +} +//------------------------------------------------------------------------------ +void loop() { + uint32_t maxLatency; + uint32_t minLatency; + uint32_t totalLatency; + + // Read any existing Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + // F stores strings in flash to save RAM + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + delay(400); // catch Due reset problem + + cout << F("FreeStack: ") << FreeStack() << endl; + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + cout << F("Type is FAT") << int(sd.vol()->fatType()) << endl; + + cout << F("Starting print test. Please wait.\n\n"); + + // do write test + for (int test = 0; test < 6; test++) { + char fileName[13] = "bench0.txt"; + fileName[5] = '0' + test; + // open or create file - truncate existing file. + if (!file.open(fileName, O_CREAT | O_TRUNC | O_RDWR)) { + error("open failed"); + } + maxLatency = 0; + minLatency = 999999; + totalLatency = 0; + switch(test) { + case 0: + cout << F("Test of println(uint16_t)\n"); + break; + + case 1: + cout << F("Test of printField(uint16_t, char)\n"); + break; + + case 2: + cout << F("Test of println(uint32_t)\n"); + break; + + case 3: + cout << F("Test of printField(uint32_t, char)\n"); + break; + case 4: + cout << F("Test of println(float)\n"); + break; + + case 5: + cout << F("Test of printField(float, char)\n"); + break; + } + + uint32_t t = millis(); + for (uint16_t i = 0; i < N_PRINT; i++) { + uint32_t m = micros(); + + switch(test) { + case 0: + file.println(i); + break; + + case 1: + file.printField(i, '\n'); + break; + + case 2: + file.println(12345678UL + i); + break; + + case 3: + file.printField(12345678UL + i, '\n'); + break; + + case 4: + file.println((float)0.01*i); + break; + + case 5: + file.printField((float)0.01*i, '\n'); + break; + } + if (file.getWriteError()) { + error("write failed"); + } + m = micros() - m; + if (maxLatency < m) { + maxLatency = m; + } + if (minLatency > m) { + minLatency = m; + } + totalLatency += m; + } + file.close(); + t = millis() - t; + double s = file.fileSize(); + cout << F("Time ") << 0.001*t << F(" sec\n"); + cout << F("File size ") << 0.001*s << F(" KB\n"); + cout << F("Write ") << s/t << F(" KB/sec\n"); + cout << F("Maximum latency: ") << maxLatency; + cout << F(" usec, Minimum Latency: ") << minLatency; + cout << F(" usec, Avg Latency: "); + cout << totalLatency/N_PRINT << F(" usec\n\n"); + } + cout << F("Done!\n\n"); +} diff --git a/libraries/SdFat/examples/QuickStart/QuickStart.ino b/libraries/SdFat/examples/QuickStart/QuickStart.ino new file mode 100644 index 0000000..e295011 --- /dev/null +++ b/libraries/SdFat/examples/QuickStart/QuickStart.ino @@ -0,0 +1,166 @@ +// Quick hardware test for SPI card access. +// +#include +#include "SdFat.h" +// +// Set DISABLE_CHIP_SELECT to disable a second SPI device. +// For example, with the Ethernet shield, set DISABLE_CHIP_SELECT +// to 10 to disable the Ethernet controller. +const int8_t DISABLE_CHIP_SELECT = -1; +// +// Test with reduced SPI speed for breadboards. SD_SCK_MHZ(4) will select +// the highest speed supported by the board that is not over 4 MHz. +// Change SPI_SPEED to SD_SCK_MHZ(50) for best performance. +#define SPI_SPEED SD_SCK_MHZ(4) +//------------------------------------------------------------------------------ +// File system object. +SdFat sd; + +// Serial streams +ArduinoOutStream cout(Serial); + +// input buffer for line +char cinBuf[40]; +ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); + +// SD card chip select +int chipSelect; + +void cardOrSpeed() { + cout << F("Try another SD card or reduce the SPI bus speed.\n"); + cout << F("Edit SPI_SPEED in this program to change it.\n"); +} + +void reformatMsg() { + cout << F("Try reformatting the card. For best results use\n"); + cout << F("the SdFormatter program in SdFat/examples or download\n"); + cout << F("and use SDFormatter from www.sdcard.org/downloads.\n"); +} + +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + cout << F("\nSPI pins:\n"); + cout << F("MISO: ") << int(MISO) << endl; + cout << F("MOSI: ") << int(MOSI) << endl; + cout << F("SCK: ") << int(SCK) << endl; + cout << F("SS: ") << int(SS) << endl; + + if (DISABLE_CHIP_SELECT < 0) { + cout << F( + "\nBe sure to edit DISABLE_CHIP_SELECT if you have\n" + "a second SPI device. For example, with the Ethernet\n" + "shield, DISABLE_CHIP_SELECT should be set to 10\n" + "to disable the Ethernet controller.\n"); + } + cout << F( + "\nSD chip select is the key hardware option.\n" + "Common values are:\n" + "Arduino Ethernet shield, pin 4\n" + "Sparkfun SD shield, pin 8\n" + "Adafruit SD shields and modules, pin 10\n"); +} + +bool firstTry = true; +void loop() { + // Read any existing Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + + if (!firstTry) { + cout << F("\nRestarting\n"); + } + firstTry = false; + + cout << F("\nEnter the chip select pin number: "); + while (!Serial.available()) { + SysCall::yield(); + } + cin.readline(); + if (cin >> chipSelect) { + cout << chipSelect << endl; + } else { + cout << F("\nInvalid pin number\n"); + return; + } + if (DISABLE_CHIP_SELECT < 0) { + cout << F( + "\nAssuming the SD is the only SPI device.\n" + "Edit DISABLE_CHIP_SELECT to disable another device.\n"); + } else { + cout << F("\nDisabling SPI device on pin "); + cout << int(DISABLE_CHIP_SELECT) << endl; + pinMode(DISABLE_CHIP_SELECT, OUTPUT); + digitalWrite(DISABLE_CHIP_SELECT, HIGH); + } + if (!sd.begin(chipSelect, SPI_SPEED)) { + if (sd.card()->errorCode()) { + cout << F( + "\nSD initialization failed.\n" + "Do not reformat the card!\n" + "Is the card correctly inserted?\n" + "Is chipSelect set to the correct value?\n" + "Does another SPI device need to be disabled?\n" + "Is there a wiring/soldering problem?\n"); + cout << F("\nerrorCode: ") << hex << showbase; + cout << int(sd.card()->errorCode()); + cout << F(", errorData: ") << int(sd.card()->errorData()); + cout << dec << noshowbase << endl; + return; + } + cout << F("\nCard successfully initialized.\n"); + if (sd.vol()->fatType() == 0) { + cout << F("Can't find a valid FAT16/FAT32 partition.\n"); + reformatMsg(); + return; + } + if (!sd.vwd()->isOpen()) { + cout << F("Can't open root directory.\n"); + reformatMsg(); + return; + } + cout << F("Can't determine error type\n"); + return; + } + cout << F("\nCard successfully initialized.\n"); + cout << endl; + + uint32_t size = sd.card()->cardSize(); + if (size == 0) { + cout << F("Can't determine the card size.\n"); + cardOrSpeed(); + return; + } + uint32_t sizeMB = 0.000512 * size + 0.5; + cout << F("Card size: ") << sizeMB; + cout << F(" MB (MB = 1,000,000 bytes)\n"); + cout << endl; + cout << F("Volume is FAT") << int(sd.vol()->fatType()); + cout << F(", Cluster size (bytes): ") << 512L * sd.vol()->blocksPerCluster(); + cout << endl << endl; + + cout << F("Files found (date time size name):\n"); + sd.ls(LS_R | LS_DATE | LS_SIZE); + + if ((sizeMB > 1100 && sd.vol()->blocksPerCluster() < 64) + || (sizeMB < 2200 && sd.vol()->fatType() == 32)) { + cout << F("\nThis card should be reformatted for best performance.\n"); + cout << F("Use a cluster size of 32 KB for cards larger than 1 GB.\n"); + cout << F("Only cards larger than 2 GB should be formatted FAT32.\n"); + reformatMsg(); + return; + } + // Read any extra Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + cout << F("\nSuccess! Type any character to restart.\n"); + while (!Serial.available()) { + SysCall::yield(); + } +} \ No newline at end of file diff --git a/libraries/SdFat/examples/RawWrite/RawWrite.ino b/libraries/SdFat/examples/RawWrite/RawWrite.ino new file mode 100644 index 0000000..97ff9a5 --- /dev/null +++ b/libraries/SdFat/examples/RawWrite/RawWrite.ino @@ -0,0 +1,179 @@ +/* + * This program illustrates raw write functions in SdFat that + * can be used for high speed data logging. + * + * This program simulates logging from a source that produces + * data at a constant rate of RATE_KB_PER_SEC. + * + * Note: Apps should create a very large file then truncates it + * to the length that is used for a logging. It only takes + * a few seconds to erase a 500 MB file since the card only + * marks the blocks as erased; no data transfer is required. + */ +#include +#include "SdFat.h" +#include "FreeStack.h" + +// SD chip select pin +const uint8_t chipSelect = SS; + +const uint32_t RATE_KB_PER_SEC = 100; + +const uint32_t TEST_TIME_SEC = 100; + +// Time between printing progress dots +const uint32_t DOT_TIME_MS = 5000UL; + +// number of blocks in the contiguous file +const uint32_t BLOCK_COUNT = (1000*RATE_KB_PER_SEC*TEST_TIME_SEC + 511)/512; + +// file system +SdFat sd; + +// test file +SdFile file; + +// file extent +uint32_t bgnBlock, endBlock; + +// Serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// store error strings in flash to save RAM +#define error(s) sd.errorHalt(F(s)) +//------------------------------------------------------------------------------ +void setup(void) { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } +} +//------------------------------------------------------------------------------ +void loop(void) { + // Read any extra Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + // F stores strings in flash to save RAM + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + + cout << F("FreeStack: ") << FreeStack() << endl; + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // delete possible existing file + sd.remove("RawWrite.txt"); + + // create a contiguous file + if (!file.createContiguous("RawWrite.txt", 512UL*BLOCK_COUNT)) { + error("createContiguous failed"); + } + // get the location of the file's blocks + if (!file.contiguousRange(&bgnBlock, &endBlock)) { + error("contiguousRange failed"); + } + //*********************NOTE************************************** + // NO SdFile calls are allowed while cache is used for raw writes + //*************************************************************** + + // clear the cache and use it as a 512 byte buffer + uint8_t* pCache = (uint8_t*)sd.vol()->cacheClear(); + + // fill cache with eight lines of 64 bytes each + memset(pCache, ' ', 512); + for (uint16_t i = 0; i < 512; i += 64) { + // put line number at end of line then CR/LF + pCache[i + 61] = '0' + (i/64); + pCache[i + 62] = '\r'; + pCache[i + 63] = '\n'; + } + + cout << F("Start raw write of ") << file.fileSize()/1000UL << F(" KB\n"); + cout << F("Target rate: ") << RATE_KB_PER_SEC << F(" KB/sec\n"); + cout << F("Target time: ") << TEST_TIME_SEC << F(" seconds\n"); + + // tell card to setup for multiple block write with pre-erase + if (!sd.card()->writeStart(bgnBlock, BLOCK_COUNT)) { + error("writeStart failed"); + } + // init stats + + delay(1000); + uint32_t dotCount = 0; + uint32_t maxQueuePrint = 0; + uint32_t maxWriteTime = 0; + uint32_t minWriteTime = 9999999; + uint32_t totalWriteTime = 0; + uint32_t maxQueueSize = 0; + uint32_t nWrite = 0; + uint32_t b = 0; + + // write data + uint32_t startTime = millis(); + while (nWrite < BLOCK_COUNT) { + uint32_t nProduced = RATE_KB_PER_SEC*(millis() - startTime)/512UL; + uint32_t queueSize = nProduced - nWrite; + if (queueSize == 0) continue; + if (queueSize > maxQueueSize) { + maxQueueSize = queueSize; + } + if ((millis() - startTime - dotCount*DOT_TIME_MS) > DOT_TIME_MS) { + if (maxQueueSize != maxQueuePrint) { + cout << F("\nQ: ") << maxQueueSize << endl; + maxQueuePrint = maxQueueSize; + } else { + cout << "."; + if (++dotCount%10 == 0) { + cout << endl; + } + } + } + // put block number at start of first line in block + uint32_t n = b++; + for (int8_t d = 5; d >= 0; d--) { + pCache[d] = n || d == 5 ? n % 10 + '0' : ' '; + n /= 10; + } + // write a 512 byte block + uint32_t tw = micros(); + if (!sd.card()->writeData(pCache)) { + error("writeData failed"); + } + tw = micros() - tw; + totalWriteTime += tw; + // check for max write time + if (tw > maxWriteTime) { + maxWriteTime = tw; + } + if (tw < minWriteTime) { + minWriteTime = tw; + } + nWrite++; + } + uint32_t endTime = millis(); + uint32_t avgWriteTime = totalWriteTime/BLOCK_COUNT; + // end multiple block write mode + if (!sd.card()->writeStop()) { + error("writeStop failed"); + } + + cout << F("\nDone\n"); + cout << F("maxQueueSize: ") << maxQueueSize << endl; + cout << F("Elapsed time: ") << setprecision(3)<< 1.e-3*(endTime - startTime); + cout << F(" seconds\n"); + cout << F("Min block write time: ") << minWriteTime << F(" micros\n"); + cout << F("Max block write time: ") << maxWriteTime << F(" micros\n"); + cout << F("Avg block write time: ") << avgWriteTime << F(" micros\n"); + // close file for next pass of loop + file.close(); + Serial.println(); +} \ No newline at end of file diff --git a/libraries/SdFat/examples/ReadCsv/ReadCsv.ino b/libraries/SdFat/examples/ReadCsv/ReadCsv.ino new file mode 100644 index 0000000..4979acc --- /dev/null +++ b/libraries/SdFat/examples/ReadCsv/ReadCsv.ino @@ -0,0 +1,212 @@ + +// Functions to read a CSV text file one field at a time. +// +#include +#include + +// next line for SD.h +//#include + +// next two lines for SdFat +#include +SdFat SD; + +#define CS_PIN SS + +// example can use comma or semicolon +#define CSV_DELIM ',' + +File file; + +/* + * Read a file one field at a time. + * + * file - File to read. + * + * str - Character array for the field. + * + * size - Size of str array. + * + * delim - csv delimiter. + * + * return - negative value for failure. + * delimiter, '\n' or zero(EOF) for success. + */ +int csvReadText(File* file, char* str, size_t size, char delim) { + char ch; + int rtn; + size_t n = 0; + while (true) { + // check for EOF + if (!file->available()) { + rtn = 0; + break; + } + if (file->read(&ch, 1) != 1) { + // read error + rtn = -1; + break; + } + // Delete CR. + if (ch == '\r') { + continue; + } + if (ch == delim || ch == '\n') { + rtn = ch; + break; + } + if ((n+1) >= size) { + // string too long + rtn = -2; + n--; + break; + } + str[n++] = ch; + } + str[n] = '\0'; + return rtn; +} +//------------------------------------------------------------------------------ +int csvReadInt32(File* file, int32_t* num, char delim) { + char buf[20]; + char* ptr; + int rtn = csvReadText(file, buf, sizeof(buf), delim); + if (rtn < 0) return rtn; + *num = strtol(buf, &ptr, 10); + if (buf == ptr) return -3; + while(isspace(*ptr)) ptr++; + return *ptr == 0 ? rtn : -4; +} +//------------------------------------------------------------------------------ +int csvReadInt16(File* file, int16_t* num, char delim) { + int32_t tmp; + int rtn = csvReadInt32(file, &tmp, delim); + if (rtn < 0) return rtn; + if (tmp < INT_MIN || tmp > INT_MAX) return -5; + *num = tmp; + return rtn; +} +//------------------------------------------------------------------------------ +int csvReadUint32(File* file, uint32_t* num, char delim) { + char buf[20]; + char* ptr; + int rtn = csvReadText(file, buf, sizeof(buf), delim); + if (rtn < 0) return rtn; + *num = strtoul(buf, &ptr, 10); + if (buf == ptr) return -3; + while(isspace(*ptr)) ptr++; + return *ptr == 0 ? rtn : -4; +} +//------------------------------------------------------------------------------ +int csvReadUint16(File* file, uint16_t* num, char delim) { + uint32_t tmp; + int rtn = csvReadUint32(file, &tmp, delim); + if (rtn < 0) return rtn; + if (tmp > UINT_MAX) return -5; + *num = tmp; + return rtn; +} +//------------------------------------------------------------------------------ +int csvReadDouble(File* file, double* num, char delim) { + char buf[20]; + char* ptr; + int rtn = csvReadText(file, buf, sizeof(buf), delim); + if (rtn < 0) return rtn; + *num = strtod(buf, &ptr); + if (buf == ptr) return -3; + while(isspace(*ptr)) ptr++; + return *ptr == 0 ? rtn : -4; +} +//------------------------------------------------------------------------------ +int csvReadFloat(File* file, float* num, char delim) { + double tmp; + int rtn = csvReadDouble(file, &tmp, delim); + if (rtn < 0)return rtn; + // could test for too large. + *num = tmp; + return rtn; +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + yield(); + } + Serial.println("Type any character to start"); + while (!Serial.available()) { + yield(); + } + // Initialize the SD. + if (!SD.begin(CS_PIN)) { + Serial.println("begin failed"); + return; + } + // Remove existing file. + SD.remove("READTEST.TXT"); + + // Create the file. + file = SD.open("READTEST.TXT", FILE_WRITE); + if (!file) { + Serial.println("open failed"); + return; + } + // Write test data. + file.print(F( +#if CSV_DELIM == ',' + "36,23.20,20.70,57.60,79.50,01:08:14,23.06.16\r\n" + "37,23.21,20.71,57.61,79.51,02:08:14,23.07.16\r\n" +#elif CSV_DELIM == ';' + "36;23.20;20.70;57.60;79.50;01:08:14;23.06.16\r\n" + "37;23.21;20.71;57.61;79.51;02:08:14;23.07.16\r\n" +#else +#error "Bad CSV_DELIM" +#endif +)); + + // Rewind the file for read. + file.seek(0); + + // Read the file and print fields. + int16_t tcalc; + float t1, t2, h1, h2; + // Must be dim 9 to allow for zero byte. + char timeS[9], dateS[9]; + while (file.available()) { + if (csvReadInt16(&file, &tcalc, CSV_DELIM) != CSV_DELIM + || csvReadFloat(&file, &t1, CSV_DELIM) != CSV_DELIM + || csvReadFloat(&file, &t2, CSV_DELIM) != CSV_DELIM + || csvReadFloat(&file, &h1, CSV_DELIM) != CSV_DELIM + || csvReadFloat(&file, &h2, CSV_DELIM) != CSV_DELIM + || csvReadText(&file, timeS, sizeof(timeS), CSV_DELIM) != CSV_DELIM + || csvReadText(&file, dateS, sizeof(dateS), CSV_DELIM) != '\n') { + Serial.println("read error"); + int ch; + int nr = 0; + // print part of file after error. + while ((ch = file.read()) > 0 && nr++ < 100) { + Serial.write(ch); + } + break; + } + Serial.print(tcalc); + Serial.print(CSV_DELIM); + Serial.print(t1); + Serial.print(CSV_DELIM); + Serial.print(t2); + Serial.print(CSV_DELIM); + Serial.print(h1); + Serial.print(CSV_DELIM); + Serial.print(h2); + Serial.print(CSV_DELIM); + Serial.print(timeS); + Serial.print(CSV_DELIM); + Serial.println(dateS); + } + file.close(); +} +//------------------------------------------------------------------------------ +void loop() { +} + diff --git a/libraries/SdFat/examples/ReadCsvArray/ReadCsvArray.ino b/libraries/SdFat/examples/ReadCsvArray/ReadCsvArray.ino new file mode 100644 index 0000000..b837a89 --- /dev/null +++ b/libraries/SdFat/examples/ReadCsvArray/ReadCsvArray.ino @@ -0,0 +1,139 @@ +// Read a two dimensional array from a CSV file. +// +#include +#include +#define CS_PIN SS + +// 5 X 4 array +#define ROW_DIM 5 +#define COL_DIM 4 + +SdFat SD; +File file; + +/* + * Read a file one field at a time. + * + * file - File to read. + * + * str - Character array for the field. + * + * size - Size of str array. + * + * delim - String containing field delimiters. + * + * return - length of field including terminating delimiter. + * + * Note, the last character of str will not be a delimiter if + * a read error occurs, the field is too long, or the file + * does not end with a delimiter. Consider this an error + * if not at end-of-file. + * + */ +size_t readField(File* file, char* str, size_t size, const char* delim) { + char ch; + size_t n = 0; + while ((n + 1) < size && file->read(&ch, 1) == 1) { + // Delete CR. + if (ch == '\r') { + continue; + } + str[n++] = ch; + if (strchr(delim, ch)) { + break; + } + } + str[n] = '\0'; + return n; +} +//------------------------------------------------------------------------------ +#define errorHalt(msg) {Serial.println(F(msg)); SysCall::halt();} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + Serial.println("Type any character to start"); + while (!Serial.available()) { + SysCall::yield(); + } + // Initialize the SD. + if (!SD.begin(CS_PIN)) { + errorHalt("begin failed"); + } + // Create or open the file. + file = SD.open("READNUM.TXT", FILE_WRITE); + if (!file) { + errorHalt("open failed"); + } + // Rewind file so test data is not appended. + file.rewind(); + + // Write test data. + file.print(F( + "11,12,13,14\r\n" + "21,22,23,24\r\n" + "31,32,33,34\r\n" + "41,42,43,44\r\n" + "51,52,53,54" // Allow missing endl at eof. + )); + + // Rewind the file for read. + file.rewind(); + + // Array for data. + int array[ROW_DIM][COL_DIM]; + int i = 0; // First array index. + int j = 0; // Second array index + size_t n; // Length of returned field with delimiter. + char str[20]; // Must hold longest field with delimiter and zero byte. + char *ptr; // Test for valid field. + + // Read the file and store the data. + + for (i = 0; i < ROW_DIM; i++) { + for (j = 0; j < COL_DIM; j++) { + n = readField(&file, str, sizeof(str), ",\n"); + if (n == 0) { + errorHalt("Too few lines"); + } + array[i][j] = strtol(str, &ptr, 10); + if (ptr == str) { + errorHalt("bad number"); + } + while (*ptr == ' ') { + ptr++; + } + if (*ptr != ',' && *ptr != '\n' && *ptr != '\0') { + errorHalt("extra characters in field"); + } + if (j < (COL_DIM-1) && str[n-1] != ',') { + errorHalt("line with too few fields"); + } + } + // Allow missing endl at eof. + if (str[n-1] != '\n' && file.available()) { + errorHalt("missing endl"); + } + } + + // Print the array. + for (i = 0; i < ROW_DIM; i++) { + for (j = 0; j < COL_DIM; j++) { + if (j) { + Serial.print(' '); + } + Serial.print(array[i][j]); + } + Serial.println(); + } + Serial.println("Done"); + file.close(); +} +//------------------------------------------------------------------------------ +void loop() { +} + diff --git a/libraries/SdFat/examples/ReadCsvStream/ReadCsvStream.ino b/libraries/SdFat/examples/ReadCsvStream/ReadCsvStream.ino new file mode 100644 index 0000000..a07611e --- /dev/null +++ b/libraries/SdFat/examples/ReadCsvStream/ReadCsvStream.ino @@ -0,0 +1,120 @@ +/* + * This example reads a simple CSV, comma-separated values, file. + * Each line of the file has a label and three values, a long and two floats. + */ +#include +#include "SdFat.h" + +// SD chip select pin +const uint8_t chipSelect = SS; + +// file system object +SdFat sd; + +// create Serial stream +ArduinoOutStream cout(Serial); + +char fileName[] = "testfile.csv"; +//------------------------------------------------------------------------------ +// store error strings in flash to save RAM +#define error(s) sd.errorHalt(F(s)) +//------------------------------------------------------------------------------ +// read and print CSV test file +void readFile() { + long lg = 0; + float f1, f2; + char text[10]; + char c1, c2, c3; // space for commas. + + // open input file + ifstream sdin(fileName); + + // check for open error + if (!sdin.is_open()) { + error("open"); + } + + // read until input fails + while (1) { + // Get text field. + sdin.get(text, sizeof(text), ','); + + // Assume EOF if fail. + if (sdin.fail()) { + break; + } + + // Get commas and numbers. + sdin >> c1 >> lg >> c2 >> f1 >> c3 >> f2; + + // Skip CR/LF. + sdin.skipWhite(); + + if (sdin.fail()) { + error("bad input"); + } + + // error in line if not commas + if (c1 != ',' || c2 != ',' || c3 != ',') { + error("comma"); + } + + // print in six character wide columns + cout << text << setw(6) << lg << setw(6) << f1 << setw(6) << f2 << endl; + } + // Error in an input line if file is not at EOF. + if (!sdin.eof()) { + error("readFile"); + } +} +//------------------------------------------------------------------------------ +// write test file +void writeFile() { + + // create or open and truncate output file + ofstream sdout(fileName); + + // write file from string stored in flash + sdout << F( + "Line 1,1,2.3,4.5\n" + "Line 2,6,7.8,9.0\n" + "Line 3,9,8.7,6.5\n" + "Line 4,-4,-3.2,-1\n") << flush; + + // check for any errors + if (!sdout) { + error("writeFile"); + } + + sdout.close(); +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // create test file + writeFile(); + + cout << endl; + + // read and print test + readFile(); + + cout << "\nDone!" << endl; +} +void loop() {} \ No newline at end of file diff --git a/libraries/SdFat/examples/ReadWrite/ReadWrite.ino b/libraries/SdFat/examples/ReadWrite/ReadWrite.ino new file mode 100644 index 0000000..15b6c98 --- /dev/null +++ b/libraries/SdFat/examples/ReadWrite/ReadWrite.ino @@ -0,0 +1,81 @@ +/* + SD card read/write + + This example shows how to read and write data to and from an SD card file + The circuit: + * SD card attached to SPI bus as follows: + ** MOSI - pin 11 + ** MISO - pin 12 + ** CLK - pin 13 + + created Nov 2010 + by David A. Mellis + modified 9 Apr 2012 + by Tom Igoe + + This example code is in the public domain. + + */ + +#include +//#include +#include "SdFat.h" +SdFat SD; + +#define SD_CS_PIN SS +File myFile; + +void setup() { + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + + Serial.print("Initializing SD card..."); + + if (!SD.begin(SD_CS_PIN)) { + Serial.println("initialization failed!"); + return; + } + Serial.println("initialization done."); + + // open the file. note that only one file can be open at a time, + // so you have to close this one before opening another. + myFile = SD.open("test.txt", FILE_WRITE); + + // if the file opened okay, write to it: + if (myFile) { + Serial.print("Writing to test.txt..."); + myFile.println("testing 1, 2, 3."); + // close the file: + myFile.close(); + Serial.println("done."); + } else { + // if the file didn't open, print an error: + Serial.println("error opening test.txt"); + } + + // re-open the file for reading: + myFile = SD.open("test.txt"); + if (myFile) { + Serial.println("test.txt:"); + + // read from the file until there's nothing else in it: + while (myFile.available()) { + Serial.write(myFile.read()); + } + // close the file: + myFile.close(); + } else { + // if the file didn't open, print an error: + Serial.println("error opening test.txt"); + } +} + +void loop() { + // nothing happens after setup +} + + diff --git a/libraries/SdFat/examples/STM32Test/STM32Test.ino b/libraries/SdFat/examples/STM32Test/STM32Test.ino new file mode 100644 index 0000000..5da3165 --- /dev/null +++ b/libraries/SdFat/examples/STM32Test/STM32Test.ino @@ -0,0 +1,176 @@ +/* + * Example use of two SPI ports on an STM32 board. + * Note SPI speed is limited to 18 MHz. + */ +#include +#include "SdFat.h" +#include "FreeStack.h" + +// set ENABLE_EXTENDED_TRANSFER_CLASS non-zero to use faster EX classes + +// Use first SPI port +SdFat sd1(1); +// SdFatEX sd1(1); +const uint8_t SD1_CS = PA4; // chip select for sd1 + +// Use second SPI port +SdFat sd2(2); +// SdFatEX sd2(2); +const uint8_t SD2_CS = PB12; // chip select for sd2 + +const uint8_t BUF_DIM = 100; +uint8_t buf[BUF_DIM]; + +const uint32_t FILE_SIZE = 1000000; +const uint16_t NWRITE = FILE_SIZE/BUF_DIM; +//------------------------------------------------------------------------------ +// print error msg, any SD error codes, and halt. +// store messages in flash +#define errorExit(msg) errorHalt(F(msg)) +#define initError(msg) initErrorHalt(F(msg)) +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + Serial.print(F("FreeStack: ")); + + Serial.println(FreeStack()); + + // fill buffer with known data + for (size_t i = 0; i < sizeof(buf); i++) { + buf[i] = i; + } + + Serial.println(F("type any character to start")); + while (!Serial.available()) { + SysCall::yield(); + } + + // initialize the first card + if (!sd1.begin(SD1_CS, SD_SCK_MHZ(18))) { + sd1.initError("sd1:"); + } + // create Dir1 on sd1 if it does not exist + if (!sd1.exists("/Dir1")) { + if (!sd1.mkdir("/Dir1")) { + sd1.errorExit("sd1.mkdir"); + } + } + // initialize the second card + if (!sd2.begin(SD2_CS, SD_SCK_MHZ(18))) { + sd2.initError("sd2:"); + } +// create Dir2 on sd2 if it does not exist + if (!sd2.exists("/Dir2")) { + if (!sd2.mkdir("/Dir2")) { + sd2.errorExit("sd2.mkdir"); + } + } + // list root directory on both cards + Serial.println(F("------sd1 root-------")); + sd1.ls(); + Serial.println(F("------sd2 root-------")); + sd2.ls(); + + // make /Dir1 the default directory for sd1 + if (!sd1.chdir("/Dir1")) { + sd1.errorExit("sd1.chdir"); + } + // remove test.bin from /Dir1 directory of sd1 + if (sd1.exists("test.bin")) { + if (!sd1.remove("test.bin")) { + sd2.errorExit("remove test.bin"); + } + } + // make /Dir2 the default directory for sd2 + if (!sd2.chdir("/Dir2")) { + sd2.errorExit("sd2.chdir"); + } + // remove rename.bin from /Dir2 directory of sd2 + if (sd2.exists("rename.bin")) { + if (!sd2.remove("rename.bin")) { + sd2.errorExit("remove rename.bin"); + } + } + // list current directory on both cards + Serial.println(F("------sd1 Dir1-------")); + sd1.ls(); + Serial.println(F("------sd2 Dir2-------")); + sd2.ls(); + Serial.println(F("---------------------")); + + // set the current working directory for open() to sd1 + sd1.chvol(); + + // create or open /Dir1/test.bin and truncate it to zero length + SdFile file1; + if (!file1.open("test.bin", O_RDWR | O_CREAT | O_TRUNC)) { + sd1.errorExit("file1"); + } + Serial.println(F("Writing test.bin to sd1")); + + // write data to /Dir1/test.bin on sd1 + for (uint16_t i = 0; i < NWRITE; i++) { + if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { + sd1.errorExit("sd1.write"); + } + } + // set the current working directory for open() to sd2 + sd2.chvol(); + + // create or open /Dir2/copy.bin and truncate it to zero length + SdFile file2; + if (!file2.open("copy.bin", O_WRITE | O_CREAT | O_TRUNC)) { + sd2.errorExit("file2"); + } + Serial.println(F("Copying test.bin to copy.bin")); + + // copy file1 to file2 + file1.rewind(); + uint32_t t = millis(); + + while (1) { + int n = file1.read(buf, sizeof(buf)); + if (n < 0) { + sd1.errorExit("read1"); + } + if (n == 0) { + break; + } + if ((int)file2.write(buf, n) != n) { + sd2.errorExit("write2"); + } + } + t = millis() - t; + Serial.print(F("File size: ")); + Serial.println(file2.fileSize()); + Serial.print(F("Copy time: ")); + Serial.print(t); + Serial.println(F(" millis")); + // close test.bin + file1.close(); + file2.close(); + // list current directory on both cards + Serial.println(F("------sd1 -------")); + sd1.ls("/", LS_R | LS_DATE | LS_SIZE); + Serial.println(F("------sd2 -------")); + sd2.ls("/", LS_R | LS_DATE | LS_SIZE); + Serial.println(F("---------------------")); + Serial.println(F("Renaming copy.bin")); + // rename the copy + if (!sd2.rename("copy.bin", "rename.bin")) { + sd2.errorExit("sd2.rename"); + } + // list current directory on both cards + Serial.println(F("------sd1 -------")); + sd1.ls("/", LS_R | LS_DATE | LS_SIZE); + Serial.println(F("------sd2 -------")); + sd2.ls("/", LS_R | LS_DATE | LS_SIZE); + Serial.println(F("---------------------")); + Serial.println(F("Done")); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/examples/SdFormatter/SdFormatter.ino b/libraries/SdFat/examples/SdFormatter/SdFormatter.ino new file mode 100644 index 0000000..a0b9ba6 --- /dev/null +++ b/libraries/SdFat/examples/SdFormatter/SdFormatter.ino @@ -0,0 +1,551 @@ +/* + * This program will format an SD or SDHC card. + * Warning all data will be deleted! + * + * For SD/SDHC cards larger than 64 MB this + * program attempts to match the format + * generated by SDFormatter available here: + * + * http://www.sdcard.org/consumers/formatter/ + * + * For smaller cards this program uses FAT16 + * and SDFormatter uses FAT12. + */ + +// Set USE_SDIO to zero for SPI card access. +#define USE_SDIO 0 +// +// Change the value of chipSelect if your hardware does +// not use the default value, SS. Common values are: +// Arduino Ethernet shield: pin 4 +// Sparkfun SD shield: pin 8 +// Adafruit SD shields and modules: pin 10 +const uint8_t chipSelect = SS; + +// Initialize at highest supported speed not over 50 MHz. +// Reduce max speed if errors occur. +#define SPI_SPEED SD_SCK_MHZ(50) + +// Print extra info for debug if DEBUG_PRINT is nonzero +#define DEBUG_PRINT 0 +#include +#include "SdFat.h" +#if DEBUG_PRINT +#include "FreeStack.h" +#endif // DEBUG_PRINT + +// Serial output stream +ArduinoOutStream cout(Serial); + +#if USE_SDIO +// Use faster SdioCardEX +SdioCardEX card; +// SdioCard card; +#else // USE_SDIO +Sd2Card card; +#endif // USE_SDIO + +uint32_t cardSizeBlocks; +uint32_t cardCapacityMB; + +// cache for SD block +cache_t cache; + +// MBR information +uint8_t partType; +uint32_t relSector; +uint32_t partSize; + +// Fake disk geometry +uint8_t numberOfHeads; +uint8_t sectorsPerTrack; + +// FAT parameters +uint16_t reservedSectors; +uint8_t sectorsPerCluster; +uint32_t fatStart; +uint32_t fatSize; +uint32_t dataStart; + +// constants for file system structure +uint16_t const BU16 = 128; +uint16_t const BU32 = 8192; + +// strings needed in file system structures +char noName[] = "NO NAME "; +char fat16str[] = "FAT16 "; +char fat32str[] = "FAT32 "; +//------------------------------------------------------------------------------ +#define sdError(msg) {cout << F("error: ") << F(msg) << endl; sdErrorHalt();} +//------------------------------------------------------------------------------ +void sdErrorHalt() { + if (card.errorCode()) { + cout << F("SD error: ") << hex << int(card.errorCode()); + cout << ',' << int(card.errorData()) << dec << endl; + } + SysCall::halt(); +} +//------------------------------------------------------------------------------ +#if DEBUG_PRINT +void debugPrint() { + cout << F("FreeStack: ") << FreeStack() << endl; + cout << F("partStart: ") << relSector << endl; + cout << F("partSize: ") << partSize << endl; + cout << F("reserved: ") << reservedSectors << endl; + cout << F("fatStart: ") << fatStart << endl; + cout << F("fatSize: ") << fatSize << endl; + cout << F("dataStart: ") << dataStart << endl; + cout << F("clusterCount: "); + cout << ((relSector + partSize - dataStart)/sectorsPerCluster) << endl; + cout << endl; + cout << F("Heads: ") << int(numberOfHeads) << endl; + cout << F("Sectors: ") << int(sectorsPerTrack) << endl; + cout << F("Cylinders: "); + cout << cardSizeBlocks/(numberOfHeads*sectorsPerTrack) << endl; +} +#endif // DEBUG_PRINT +//------------------------------------------------------------------------------ +// write cached block to the card +uint8_t writeCache(uint32_t lbn) { + return card.writeBlock(lbn, cache.data); +} +//------------------------------------------------------------------------------ +// initialize appropriate sizes for SD capacity +void initSizes() { + if (cardCapacityMB <= 6) { + sdError("Card is too small."); + } else if (cardCapacityMB <= 16) { + sectorsPerCluster = 2; + } else if (cardCapacityMB <= 32) { + sectorsPerCluster = 4; + } else if (cardCapacityMB <= 64) { + sectorsPerCluster = 8; + } else if (cardCapacityMB <= 128) { + sectorsPerCluster = 16; + } else if (cardCapacityMB <= 1024) { + sectorsPerCluster = 32; + } else if (cardCapacityMB <= 32768) { + sectorsPerCluster = 64; + } else { + // SDXC cards + sectorsPerCluster = 128; + } + + cout << F("Blocks/Cluster: ") << int(sectorsPerCluster) << endl; + // set fake disk geometry + sectorsPerTrack = cardCapacityMB <= 256 ? 32 : 63; + + if (cardCapacityMB <= 16) { + numberOfHeads = 2; + } else if (cardCapacityMB <= 32) { + numberOfHeads = 4; + } else if (cardCapacityMB <= 128) { + numberOfHeads = 8; + } else if (cardCapacityMB <= 504) { + numberOfHeads = 16; + } else if (cardCapacityMB <= 1008) { + numberOfHeads = 32; + } else if (cardCapacityMB <= 2016) { + numberOfHeads = 64; + } else if (cardCapacityMB <= 4032) { + numberOfHeads = 128; + } else { + numberOfHeads = 255; + } +} +//------------------------------------------------------------------------------ +// zero cache and optionally set the sector signature +void clearCache(uint8_t addSig) { + memset(&cache, 0, sizeof(cache)); + if (addSig) { + cache.mbr.mbrSig0 = BOOTSIG0; + cache.mbr.mbrSig1 = BOOTSIG1; + } +} +//------------------------------------------------------------------------------ +// zero FAT and root dir area on SD +void clearFatDir(uint32_t bgn, uint32_t count) { + clearCache(false); +#if USE_SDIO + for (uint32_t i = 0; i < count; i++) { + if (!card.writeBlock(bgn + i, cache.data)) { + sdError("Clear FAT/DIR writeBlock failed"); + } + if ((i & 0XFF) == 0) { + cout << '.'; + } + } +#else // USE_SDIO + if (!card.writeStart(bgn, count)) { + sdError("Clear FAT/DIR writeStart failed"); + } + for (uint32_t i = 0; i < count; i++) { + if ((i & 0XFF) == 0) { + cout << '.'; + } + if (!card.writeData(cache.data)) { + sdError("Clear FAT/DIR writeData failed"); + } + } + if (!card.writeStop()) { + sdError("Clear FAT/DIR writeStop failed"); + } +#endif // USE_SDIO + cout << endl; +} +//------------------------------------------------------------------------------ +// return cylinder number for a logical block number +uint16_t lbnToCylinder(uint32_t lbn) { + return lbn / (numberOfHeads * sectorsPerTrack); +} +//------------------------------------------------------------------------------ +// return head number for a logical block number +uint8_t lbnToHead(uint32_t lbn) { + return (lbn % (numberOfHeads * sectorsPerTrack)) / sectorsPerTrack; +} +//------------------------------------------------------------------------------ +// return sector number for a logical block number +uint8_t lbnToSector(uint32_t lbn) { + return (lbn % sectorsPerTrack) + 1; +} +//------------------------------------------------------------------------------ +// format and write the Master Boot Record +void writeMbr() { + clearCache(true); + part_t* p = cache.mbr.part; + p->boot = 0; + uint16_t c = lbnToCylinder(relSector); + if (c > 1023) { + sdError("MBR CHS"); + } + p->beginCylinderHigh = c >> 8; + p->beginCylinderLow = c & 0XFF; + p->beginHead = lbnToHead(relSector); + p->beginSector = lbnToSector(relSector); + p->type = partType; + uint32_t endLbn = relSector + partSize - 1; + c = lbnToCylinder(endLbn); + if (c <= 1023) { + p->endCylinderHigh = c >> 8; + p->endCylinderLow = c & 0XFF; + p->endHead = lbnToHead(endLbn); + p->endSector = lbnToSector(endLbn); + } else { + // Too big flag, c = 1023, h = 254, s = 63 + p->endCylinderHigh = 3; + p->endCylinderLow = 255; + p->endHead = 254; + p->endSector = 63; + } + p->firstSector = relSector; + p->totalSectors = partSize; + if (!writeCache(0)) { + sdError("write MBR"); + } +} +//------------------------------------------------------------------------------ +// generate serial number from card size and micros since boot +uint32_t volSerialNumber() { + return (cardSizeBlocks << 8) + micros(); +} +//------------------------------------------------------------------------------ +// format the SD as FAT16 +void makeFat16() { + uint32_t nc; + for (dataStart = 2 * BU16;; dataStart += BU16) { + nc = (cardSizeBlocks - dataStart)/sectorsPerCluster; + fatSize = (nc + 2 + 255)/256; + uint32_t r = BU16 + 1 + 2 * fatSize + 32; + if (dataStart < r) { + continue; + } + relSector = dataStart - r + BU16; + break; + } + // check valid cluster count for FAT16 volume + if (nc < 4085 || nc >= 65525) { + sdError("Bad cluster count"); + } + reservedSectors = 1; + fatStart = relSector + reservedSectors; + partSize = nc * sectorsPerCluster + 2 * fatSize + reservedSectors + 32; + if (partSize < 32680) { + partType = 0X01; + } else if (partSize < 65536) { + partType = 0X04; + } else { + partType = 0X06; + } + // write MBR + writeMbr(); + clearCache(true); + fat_boot_t* pb = &cache.fbs; + pb->jump[0] = 0XEB; + pb->jump[1] = 0X00; + pb->jump[2] = 0X90; + for (uint8_t i = 0; i < sizeof(pb->oemId); i++) { + pb->oemId[i] = ' '; + } + pb->bytesPerSector = 512; + pb->sectorsPerCluster = sectorsPerCluster; + pb->reservedSectorCount = reservedSectors; + pb->fatCount = 2; + pb->rootDirEntryCount = 512; + pb->mediaType = 0XF8; + pb->sectorsPerFat16 = fatSize; + pb->sectorsPerTrack = sectorsPerTrack; + pb->headCount = numberOfHeads; + pb->hidddenSectors = relSector; + pb->totalSectors32 = partSize; + pb->driveNumber = 0X80; + pb->bootSignature = EXTENDED_BOOT_SIG; + pb->volumeSerialNumber = volSerialNumber(); + memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel)); + memcpy(pb->fileSystemType, fat16str, sizeof(pb->fileSystemType)); + // write partition boot sector + if (!writeCache(relSector)) { + sdError("FAT16 write PBS failed"); + } + // clear FAT and root directory + clearFatDir(fatStart, dataStart - fatStart); + clearCache(false); + cache.fat16[0] = 0XFFF8; + cache.fat16[1] = 0XFFFF; + // write first block of FAT and backup for reserved clusters + if (!writeCache(fatStart) + || !writeCache(fatStart + fatSize)) { + sdError("FAT16 reserve failed"); + } +} +//------------------------------------------------------------------------------ +// format the SD as FAT32 +void makeFat32() { + uint32_t nc; + relSector = BU32; + for (dataStart = 2 * BU32;; dataStart += BU32) { + nc = (cardSizeBlocks - dataStart)/sectorsPerCluster; + fatSize = (nc + 2 + 127)/128; + uint32_t r = relSector + 9 + 2 * fatSize; + if (dataStart >= r) { + break; + } + } + // error if too few clusters in FAT32 volume + if (nc < 65525) { + sdError("Bad cluster count"); + } + reservedSectors = dataStart - relSector - 2 * fatSize; + fatStart = relSector + reservedSectors; + partSize = nc * sectorsPerCluster + dataStart - relSector; + // type depends on address of end sector + // max CHS has lbn = 16450560 = 1024*255*63 + if ((relSector + partSize) <= 16450560) { + // FAT32 + partType = 0X0B; + } else { + // FAT32 with INT 13 + partType = 0X0C; + } + writeMbr(); + clearCache(true); + + fat32_boot_t* pb = &cache.fbs32; + pb->jump[0] = 0XEB; + pb->jump[1] = 0X00; + pb->jump[2] = 0X90; + for (uint8_t i = 0; i < sizeof(pb->oemId); i++) { + pb->oemId[i] = ' '; + } + pb->bytesPerSector = 512; + pb->sectorsPerCluster = sectorsPerCluster; + pb->reservedSectorCount = reservedSectors; + pb->fatCount = 2; + pb->mediaType = 0XF8; + pb->sectorsPerTrack = sectorsPerTrack; + pb->headCount = numberOfHeads; + pb->hidddenSectors = relSector; + pb->totalSectors32 = partSize; + pb->sectorsPerFat32 = fatSize; + pb->fat32RootCluster = 2; + pb->fat32FSInfo = 1; + pb->fat32BackBootBlock = 6; + pb->driveNumber = 0X80; + pb->bootSignature = EXTENDED_BOOT_SIG; + pb->volumeSerialNumber = volSerialNumber(); + memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel)); + memcpy(pb->fileSystemType, fat32str, sizeof(pb->fileSystemType)); + // write partition boot sector and backup + if (!writeCache(relSector) + || !writeCache(relSector + 6)) { + sdError("FAT32 write PBS failed"); + } + clearCache(true); + // write extra boot area and backup + if (!writeCache(relSector + 2) + || !writeCache(relSector + 8)) { + sdError("FAT32 PBS ext failed"); + } + fat32_fsinfo_t* pf = &cache.fsinfo; + pf->leadSignature = FSINFO_LEAD_SIG; + pf->structSignature = FSINFO_STRUCT_SIG; + pf->freeCount = 0XFFFFFFFF; + pf->nextFree = 0XFFFFFFFF; + // write FSINFO sector and backup + if (!writeCache(relSector + 1) + || !writeCache(relSector + 7)) { + sdError("FAT32 FSINFO failed"); + } + clearFatDir(fatStart, 2 * fatSize + sectorsPerCluster); + clearCache(false); + cache.fat32[0] = 0x0FFFFFF8; + cache.fat32[1] = 0x0FFFFFFF; + cache.fat32[2] = 0x0FFFFFFF; + // write first block of FAT and backup for reserved clusters + if (!writeCache(fatStart) + || !writeCache(fatStart + fatSize)) { + sdError("FAT32 reserve failed"); + } +} +//------------------------------------------------------------------------------ +// flash erase all data +uint32_t const ERASE_SIZE = 262144L; +void eraseCard() { + cout << endl << F("Erasing\n"); + uint32_t firstBlock = 0; + uint32_t lastBlock; + uint16_t n = 0; + + do { + lastBlock = firstBlock + ERASE_SIZE - 1; + if (lastBlock >= cardSizeBlocks) { + lastBlock = cardSizeBlocks - 1; + } + if (!card.erase(firstBlock, lastBlock)) { + sdError("erase failed"); + } + cout << '.'; + if ((n++)%32 == 31) { + cout << endl; + } + firstBlock += ERASE_SIZE; + } while (firstBlock < cardSizeBlocks); + cout << endl; + + if (!card.readBlock(0, cache.data)) { + sdError("readBlock"); + } + cout << hex << showbase << setfill('0') << internal; + cout << F("All data set to ") << setw(4) << int(cache.data[0]) << endl; + cout << dec << noshowbase << setfill(' ') << right; + cout << F("Erase done\n"); +} +//------------------------------------------------------------------------------ +void formatCard() { + cout << endl; + cout << F("Formatting\n"); + initSizes(); + if (card.type() != SD_CARD_TYPE_SDHC) { + cout << F("FAT16\n"); + makeFat16(); + } else { + cout << F("FAT32\n"); + makeFat32(); + } +#if DEBUG_PRINT + debugPrint(); +#endif // DEBUG_PRINT + cout << F("Format done\n"); +} +//------------------------------------------------------------------------------ +void setup() { + char c; + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + // Discard any extra characters. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + cout << F( + "\n" + "This program can erase and/or format SD/SDHC cards.\n" + "\n" + "Erase uses the card's fast flash erase command.\n" + "Flash erase sets all data to 0X00 for most cards\n" + "and 0XFF for a few vendor's cards.\n" + "\n" + "Cards larger than 2 GB will be formatted FAT32 and\n" + "smaller cards will be formatted FAT16.\n" + "\n" + "Warning, all data on the card will be erased.\n" + "Enter 'Y' to continue: "); + while (!Serial.available()) { + SysCall::yield(); + } + + c = Serial.read(); + cout << c << endl; + if (c != 'Y') { + cout << F("Quiting, you did not enter 'Y'.\n"); + return; + } + // Read any existing Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + + cout << F( + "\n" + "Options are:\n" + "E - erase the card and skip formatting.\n" + "F - erase and then format the card. (recommended)\n" + "Q - quick format the card without erase.\n" + "\n" + "Enter option: "); + + while (!Serial.available()) { + SysCall::yield(); + } + c = Serial.read(); + cout << c << endl; + if (!strchr("EFQ", c)) { + cout << F("Quiting, invalid option entered.") << endl; + return; + } +#if USE_SDIO + if (!card.begin()) { + sdError("card.begin failed"); + } +#else // USE_SDIO + if (!card.begin(chipSelect, SPI_SPEED)) { + cout << F( + "\nSD initialization failure!\n" + "Is the SD card inserted correctly?\n" + "Is chip select correct at the top of this program?\n"); + sdError("card.begin failed"); + } +#endif + cardSizeBlocks = card.cardSize(); + if (cardSizeBlocks == 0) { + sdError("cardSize"); + } + cardCapacityMB = (cardSizeBlocks + 2047)/2048; + + cout << F("Card Size: ") << setprecision(0) << 1.048576*cardCapacityMB; + cout << F(" MB, (MB = 1,000,000 bytes)") << endl; + + if (c == 'E' || c == 'F') { + eraseCard(); + } + if (c == 'F' || c == 'Q') { + formatCard(); + } +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/examples/SdInfo/SdInfo.ino b/libraries/SdFat/examples/SdInfo/SdInfo.ino new file mode 100644 index 0000000..2b42758 --- /dev/null +++ b/libraries/SdFat/examples/SdInfo/SdInfo.ino @@ -0,0 +1,247 @@ +/* + * This program attempts to initialize an SD card and analyze its structure. + */ +#include +#include "SdFat.h" + +// Set USE_SDIO to zero for SPI card access. +#define USE_SDIO 0 +/* + * SD chip select pin. Common values are: + * + * Arduino Ethernet shield, pin 4. + * SparkFun SD shield, pin 8. + * Adafruit SD shields and modules, pin 10. + * Default SD chip select is the SPI SS pin. + */ +const uint8_t SD_CHIP_SELECT = SS; +/* + * Set DISABLE_CHIP_SELECT to disable a second SPI device. + * For example, with the Ethernet shield, set DISABLE_CHIP_SELECT + * to 10 to disable the Ethernet controller. + */ +const int8_t DISABLE_CHIP_SELECT = -1; + +#if USE_SDIO +// Use faster SdioCardEX +SdFatSdioEX sd; +// SdFatSdio sd; +#else // USE_SDIO +SdFat sd; +#endif // USE_SDIO + +// serial output steam +ArduinoOutStream cout(Serial); + +// global for card size +uint32_t cardSize; + +// global for card erase size +uint32_t eraseSize; +//------------------------------------------------------------------------------ +// store error strings in flash +#define sdErrorMsg(msg) sd.errorPrint(F(msg)); +//------------------------------------------------------------------------------ +uint8_t cidDmp() { + cid_t cid; + if (!sd.card()->readCID(&cid)) { + sdErrorMsg("readCID failed"); + return false; + } + cout << F("\nManufacturer ID: "); + cout << hex << int(cid.mid) << dec << endl; + cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl; + cout << F("Product: "); + for (uint8_t i = 0; i < 5; i++) { + cout << cid.pnm[i]; + } + cout << F("\nVersion: "); + cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl; + cout << F("Serial number: ") << hex << cid.psn << dec << endl; + cout << F("Manufacturing date: "); + cout << int(cid.mdt_month) << '/'; + cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl; + cout << endl; + return true; +} +//------------------------------------------------------------------------------ +uint8_t csdDmp() { + csd_t csd; + uint8_t eraseSingleBlock; + if (!sd.card()->readCSD(&csd)) { + sdErrorMsg("readCSD failed"); + return false; + } + if (csd.v1.csd_ver == 0) { + eraseSingleBlock = csd.v1.erase_blk_en; + eraseSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; + } else if (csd.v2.csd_ver == 1) { + eraseSingleBlock = csd.v2.erase_blk_en; + eraseSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low; + } else { + cout << F("csd version error\n"); + return false; + } + eraseSize++; + cout << F("cardSize: ") << 0.000512*cardSize; + cout << F(" MB (MB = 1,000,000 bytes)\n"); + + cout << F("flashEraseSize: ") << int(eraseSize) << F(" blocks\n"); + cout << F("eraseSingleBlock: "); + if (eraseSingleBlock) { + cout << F("true\n"); + } else { + cout << F("false\n"); + } + return true; +} +//------------------------------------------------------------------------------ +// print partition table +uint8_t partDmp() { + mbr_t mbr; + if (!sd.card()->readBlock(0, (uint8_t*)&mbr)) { + sdErrorMsg("read MBR failed"); + return false; + } + for (uint8_t ip = 1; ip < 5; ip++) { + part_t *pt = &mbr.part[ip - 1]; + if ((pt->boot & 0X7F) != 0 || pt->firstSector > cardSize) { + cout << F("\nNo MBR. Assuming Super Floppy format.\n"); + return true; + } + } + cout << F("\nSD Partition Table\n"); + cout << F("part,boot,type,start,length\n"); + for (uint8_t ip = 1; ip < 5; ip++) { + part_t *pt = &mbr.part[ip - 1]; + cout << int(ip) << ',' << hex << int(pt->boot) << ',' << int(pt->type); + cout << dec << ',' << pt->firstSector <<',' << pt->totalSectors << endl; + } + return true; +} +//------------------------------------------------------------------------------ +void volDmp() { + cout << F("\nVolume is FAT") << int(sd.vol()->fatType()) << endl; + cout << F("blocksPerCluster: ") << int(sd.vol()->blocksPerCluster()) << endl; + cout << F("clusterCount: ") << sd.vol()->clusterCount() << endl; + cout << F("freeClusters: "); + uint32_t volFree = sd.vol()->freeClusterCount(); + cout << volFree << endl; + float fs = 0.000512*volFree*sd.vol()->blocksPerCluster(); + cout << F("freeSpace: ") << fs << F(" MB (MB = 1,000,000 bytes)\n"); + cout << F("fatStartBlock: ") << sd.vol()->fatStartBlock() << endl; + cout << F("fatCount: ") << int(sd.vol()->fatCount()) << endl; + cout << F("blocksPerFat: ") << sd.vol()->blocksPerFat() << endl; + cout << F("rootDirStart: ") << sd.vol()->rootDirStart() << endl; + cout << F("dataStartBlock: ") << sd.vol()->dataStartBlock() << endl; + if (sd.vol()->dataStartBlock() % eraseSize) { + cout << F("Data area is not aligned on flash erase boundaries!\n"); + cout << F("Download and use formatter from www.sdcard.org!\n"); + } +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + + // use uppercase in hex and use 0X base prefix + cout << uppercase << showbase << endl; + + // F stores strings in flash to save RAM + cout << F("SdFat version: ") << SD_FAT_VERSION << endl; +#if !USE_SDIO + if (DISABLE_CHIP_SELECT < 0) { + cout << F( + "\nAssuming the SD is the only SPI device.\n" + "Edit DISABLE_CHIP_SELECT to disable another device.\n"); + } else { + cout << F("\nDisabling SPI device on pin "); + cout << int(DISABLE_CHIP_SELECT) << endl; + pinMode(DISABLE_CHIP_SELECT, OUTPUT); + digitalWrite(DISABLE_CHIP_SELECT, HIGH); + } + cout << F("\nAssuming the SD chip select pin is: ") <= 0); + + // F stores strings in flash to save RAM + cout << F("\ntype any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + + uint32_t t = millis(); +#if USE_SDIO + if (!sd.cardBegin()) { + sdErrorMsg("\ncardBegin failed"); + return; + } +#else // USE_SDIO + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.cardBegin(SD_CHIP_SELECT, SD_SCK_MHZ(50))) { + sdErrorMsg("cardBegin failed"); + return; + } + #endif // USE_SDIO + t = millis() - t; + + cardSize = sd.card()->cardSize(); + if (cardSize == 0) { + sdErrorMsg("cardSize failed"); + return; + } + cout << F("\ninit time: ") << t << " ms" << endl; + cout << F("\nCard type: "); + switch (sd.card()->type()) { + case SD_CARD_TYPE_SD1: + cout << F("SD1\n"); + break; + + case SD_CARD_TYPE_SD2: + cout << F("SD2\n"); + break; + + case SD_CARD_TYPE_SDHC: + if (cardSize < 70000000) { + cout << F("SDHC\n"); + } else { + cout << F("SDXC\n"); + } + break; + + default: + cout << F("Unknown\n"); + } + if (!cidDmp()) { + return; + } + if (!csdDmp()) { + return; + } + uint32_t ocr; + if (!sd.card()->readOCR(&ocr)) { + sdErrorMsg("\nreadOCR failed"); + return; + } + cout << F("OCR: ") << hex << ocr << dec << endl; + if (!partDmp()) { + return; + } + if (!sd.fsBegin()) { + sdErrorMsg("\nFile System initialization failed.\n"); + return; + } + volDmp(); +} \ No newline at end of file diff --git a/libraries/SdFat/examples/SoftwareSpi/SoftwareSpi.ino b/libraries/SdFat/examples/SoftwareSpi/SoftwareSpi.ino new file mode 100644 index 0000000..5d5846a --- /dev/null +++ b/libraries/SdFat/examples/SoftwareSpi/SoftwareSpi.ino @@ -0,0 +1,58 @@ +// An example of the SdFatSoftSpi template class. +// This example is for an Adafruit Data Logging Shield on a Mega. +// Software SPI is required on Mega since this shield connects to pins 10-13. +// This example will also run on an Uno and other boards using software SPI. +// +#include +#include "SdFat.h" +#if ENABLE_SOFTWARE_SPI_CLASS // Must be set in SdFat/SdFatConfig.h +// +// Pin numbers in templates must be constants. +const uint8_t SOFT_MISO_PIN = 12; +const uint8_t SOFT_MOSI_PIN = 11; +const uint8_t SOFT_SCK_PIN = 13; +// +// Chip select may be constant or RAM variable. +const uint8_t SD_CHIP_SELECT_PIN = 10; + +// SdFat software SPI template +SdFatSoftSpi sd; + +// Test file. +SdFile file; + +void setup() { + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + Serial.println("Type any character to start"); + while (!Serial.available()) { + SysCall::yield(); + } + + if (!sd.begin(SD_CHIP_SELECT_PIN)) { + sd.initErrorHalt(); + } + + if (!file.open("SoftSPI.txt", O_CREAT | O_RDWR)) { + sd.errorHalt(F("open failed")); + } + file.println(F("This line was printed using software SPI.")); + + file.rewind(); + + while (file.available()) { + Serial.write(file.read()); + } + + file.close(); + + Serial.println(F("Done.")); +} +//------------------------------------------------------------------------------ +void loop() {} +#else // ENABLE_SOFTWARE_SPI_CLASS +#error ENABLE_SOFTWARE_SPI_CLASS must be set non-zero in SdFat/SdFatConfig.h +#endif //ENABLE_SOFTWARE_SPI_CLASS \ No newline at end of file diff --git a/libraries/SdFat/examples/StdioBench/StdioBench.ino b/libraries/SdFat/examples/StdioBench/StdioBench.ino new file mode 100644 index 0000000..d146183 --- /dev/null +++ b/libraries/SdFat/examples/StdioBench/StdioBench.ino @@ -0,0 +1,214 @@ +// Benchmark comparing SdFile and StdioStream. +#include +#include "SdFat.h" + +// Define PRINT_FIELD nonzero to use printField. +#define PRINT_FIELD 0 + +// Number of lines to list on Serial. +#define STDIO_LIST_COUNT 0 +#define VERIFY_CONTENT 0 + +const uint8_t SD_CS_PIN = SS; +SdFat sd; + +SdFile printFile; +StdioStream stdioFile; + +float f[100]; +char buf[20]; +const char* label[] = +{ "uint8_t 0 to 255, 100 times ", "uint16_t 0 to 20000", + "uint32_t 0 to 20000", "uint32_t 1000000000 to 1000010000", + "float nnn.ffff, 10000 times" +}; +//------------------------------------------------------------------------------ +void setup() { + uint32_t printSize; + uint32_t stdioSize = 0; + uint32_t printTime; + uint32_t stdioTime = 0; + + Serial.begin(9600); + while (!Serial) { + SysCall::yield(); + } + + Serial.println(F("Type any character to start")); + while (!Serial.available()) { + SysCall::yield(); + } + Serial.println(F("Starting test")); + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(SD_CS_PIN, SD_SCK_MHZ(50))) { + sd.errorHalt(); + } + + for (uint8_t i = 0; i < 100; i++) { + f[i] = 123.0 + 0.1234*i; + } + + for (uint8_t dataType = 0; dataType < 5; dataType++) { + for (uint8_t fileType = 0; fileType < 2; fileType++) { + if (!fileType) { + if (!printFile.open("print.txt", O_CREAT | O_RDWR | O_TRUNC)) { + Serial.println(F("open fail")); + return; + } + printTime = millis(); + switch (dataType) { + case 0: + for (uint16_t i =0; i < 100; i++) { + for (uint8_t j = 0; j < 255; j++) { + printFile.println(j); + } + } + break; + case 1: + for (uint16_t i = 0; i < 20000; i++) { + printFile.println(i); + } + break; + + case 2: + for (uint32_t i = 0; i < 20000; i++) { + printFile.println(i); + } + break; + + case 3: + for (uint16_t i = 0; i < 10000; i++) { + printFile.println(i + 1000000000UL); + } + break; + + case 4: + for (int j = 0; j < 100; j++) { + for (uint8_t i = 0; i < 100; i++) { + printFile.println(f[i], 4); + } + } + break; + default: + break; + } + printFile.sync(); + printTime = millis() - printTime; + printFile.rewind(); + printSize = printFile.fileSize(); + + } else { + if (!stdioFile.fopen("stream.txt", "w+")) { + Serial.println(F("fopen fail")); + return; + } + stdioTime = millis(); + + switch (dataType) { + case 0: + for (uint16_t i =0; i < 100; i++) { + for (uint8_t j = 0; j < 255; j++) { +#if PRINT_FIELD + stdioFile.printField(j, '\n'); +#else // PRINT_FIELD + stdioFile.println(j); +#endif // PRINT_FIELD + } + } + break; + case 1: + for (uint16_t i = 0; i < 20000; i++) { +#if PRINT_FIELD + stdioFile.printField(i, '\n'); +#else // PRINT_FIELD + stdioFile.println(i); +#endif // PRINT_FIELD + } + break; + + case 2: + for (uint32_t i = 0; i < 20000; i++) { +#if PRINT_FIELD + stdioFile.printField(i, '\n'); +#else // PRINT_FIELD + stdioFile.println(i); +#endif // PRINT_FIELD + } + break; + + case 3: + for (uint16_t i = 0; i < 10000; i++) { + uint32_t n = i + 1000000000UL; +#if PRINT_FIELD + stdioFile.printField(n, '\n'); +#else // PRINT_FIELD + stdioFile.println(n); +#endif // PRINT_FIELD + } + break; + + case 4: + for (int j = 0; j < 100; j++) { + for (uint8_t i = 0; i < 100; i++) { +#if PRINT_FIELD + stdioFile.printField(f[i], '\n', 4); +#else // PRINT_FIELD + stdioFile.println(f[i], 4); +#endif // PRINT_FIELD + } + } + break; + default: + break; + } + stdioFile.fflush(); + stdioTime = millis() - stdioTime; + stdioSize = stdioFile.ftell(); + if (STDIO_LIST_COUNT) { + size_t len; + stdioFile.rewind(); + for (int i = 0; i < STDIO_LIST_COUNT; i++) { + stdioFile.fgets(buf, sizeof(buf), &len); + Serial.print(len); + Serial.print(','); + Serial.print(buf); + } + } + + } + + } + Serial.println(label[dataType]); + if (VERIFY_CONTENT && printSize == stdioSize) { + printFile.rewind(); + stdioFile.rewind(); + for (uint32_t i = 0; i < stdioSize; i++) { + if (printFile.read() != stdioFile.getc()) { + Serial.print(F("Files differ at pos: ")); + Serial.println(i); + return; + } + } + } + + Serial.print(F("fileSize: ")); + if (printSize != stdioSize) { + Serial.print(printSize); + Serial.print(F(" != ")); + } + Serial.println(stdioSize); + Serial.print(F("print millis: ")); + Serial.println(printTime); + Serial.print(F("stdio millis: ")); + Serial.println(stdioTime); + Serial.print(F("ratio: ")); + Serial.println((float)printTime/(float)stdioTime); + Serial.println(); + printFile.close(); + stdioFile.fclose(); + } + Serial.println(F("Done")); +} +void loop() {} \ No newline at end of file diff --git a/libraries/SdFat/examples/TeensySdioDemo/TeensySdioDemo.ino b/libraries/SdFat/examples/TeensySdioDemo/TeensySdioDemo.ino new file mode 100644 index 0000000..988a921 --- /dev/null +++ b/libraries/SdFat/examples/TeensySdioDemo/TeensySdioDemo.ino @@ -0,0 +1,169 @@ +// Simple performance test for Teensy 3.5/3.6 SDHC. +// Demonstrates yield() efficiency. + +// Warning SdFatSdio and SdFatSdioEX normally should +// not both be used in a program. +// Each has its own cache and member variables. + +#include "SdFat.h" + +// 32 KiB buffer. +const size_t BUF_DIM = 32768; + +// 8 MiB file. +const uint32_t FILE_SIZE = 256UL*BUF_DIM; + +SdFatSdio sd; + +SdFatSdioEX sdEx; + +File file; + +uint8_t buf[BUF_DIM]; + +// buffer as uint32_t +uint32_t* buf32 = (uint32_t*)buf; + +// Total usec in read/write calls. +uint32_t totalMicros = 0; +// Time in yield() function. +uint32_t yieldMicros = 0; +// Number of yield calls. +uint32_t yieldCalls = 0; +// Max busy time for single yield call. +uint32_t yieldMaxUsec = 0; +// Control access to the two versions of SdFat. +bool useEx = false; +//----------------------------------------------------------------------------- +bool sdBusy() { + return useEx ? sdEx.card()->isBusy() : sd.card()->isBusy(); +} +//----------------------------------------------------------------------------- +void errorHalt(const char* msg) { + if (useEx) { + sdEx.errorHalt(msg); + } else { + sd.errorHalt(msg); + } +} +//------------------------------------------------------------------------------ +uint32_t kHzSdClk() { + return useEx ? sdEx.card()->kHzSdClk() : sd.card()->kHzSdClk(); +} +//------------------------------------------------------------------------------ +// Replace "weak" system yield() function. +void yield() { + // Only count cardBusy time. + if (!sdBusy()) { + return; + } + uint32_t m = micros(); + yieldCalls++; + while (sdBusy()) { + // Do something here. + } + m = micros() - m; + if (m > yieldMaxUsec) { + yieldMaxUsec = m; + } + yieldMicros += m; +} +//----------------------------------------------------------------------------- +void runTest() { + // Zero Stats + totalMicros = 0; + yieldMicros = 0; + yieldCalls = 0; + yieldMaxUsec = 0; + if (!file.open("TeensyDemo.bin", O_RDWR | O_CREAT)) { + errorHalt("open failed"); + } + Serial.println("\nsize,write,read"); + Serial.println("bytes,KB/sec,KB/sec"); + for (size_t nb = 512; nb <= BUF_DIM; nb *= 2) { + file.truncate(0); + uint32_t nRdWr = FILE_SIZE/nb; + Serial.print(nb); + Serial.print(','); + uint32_t t = micros(); + for (uint32_t n = 0; n < nRdWr; n++) { + // Set start and end of buffer. + buf32[0] = n; + buf32[nb/4 - 1] = n; + if (nb != file.write(buf, nb)) { + errorHalt("write failed"); + } + } + t = micros() - t; + totalMicros += t; + Serial.print(1000.0*FILE_SIZE/t); + Serial.print(','); + file.rewind(); + t = micros(); + + for (uint32_t n = 0; n < nRdWr; n++) { + if ((int)nb != file.read(buf, nb)) { + errorHalt("read failed"); + } + // crude check of data. + if (buf32[0] != n || buf32[nb/4 - 1] != n) { + errorHalt("data check"); + } + } + t = micros() - t; + totalMicros += t; + Serial.println(1000.0*FILE_SIZE/t); + } + file.close(); + Serial.print("\ntotalMicros "); + Serial.println(totalMicros); + Serial.print("yieldMicros "); + Serial.println(yieldMicros); + Serial.print("yieldCalls "); + Serial.println(yieldCalls); + Serial.print("yieldMaxUsec "); + Serial.println(yieldMaxUsec); + Serial.print("kHzSdClk "); + Serial.println(kHzSdClk()); + Serial.println("Done"); +} +//----------------------------------------------------------------------------- +void setup() { + Serial.begin(9600); + while (!Serial) { + } + Serial.println("SdFatSdioEX uses extended multi-block transfers without DMA."); + Serial.println("SdFatSdio uses a traditional DMA SDIO implementation."); + Serial.println("Note the difference is speed and busy yield time.\n"); +} +//----------------------------------------------------------------------------- +void loop() { + do { + delay(10); + } while (Serial.available() && Serial.read()); + + Serial.println("Type '1' for SdFatSdioEX or '2' for SdFatSdio"); + while (!Serial.available()) { + } + char c = Serial.read(); + if (c != '1' && c != '2') { + Serial.println("Invalid input"); + return; + } + if (c =='1') { + useEx = true; + if (!sdEx.begin()) { + sd.initErrorHalt("SdFatSdioEX begin() failed"); + } + // make sdEx the current volume. + sdEx.chvol(); + } else { + useEx = false; + if (!sd.begin()) { + sd.initErrorHalt("SdFatSdio begin() failed"); + } + // make sd the current volume. + sd.chvol(); + } + runTest(); +} \ No newline at end of file diff --git a/libraries/SdFat/examples/Timestamp/Timestamp.ino b/libraries/SdFat/examples/Timestamp/Timestamp.ino new file mode 100644 index 0000000..d0b09d0 --- /dev/null +++ b/libraries/SdFat/examples/Timestamp/Timestamp.ino @@ -0,0 +1,175 @@ +/* + * This program tests the dateTimeCallback() function + * and the timestamp() function. + */ +#include +#include "SdFat.h" + +SdFat sd; + +SdFile file; + +// Default SD chip select is SS pin +const uint8_t chipSelect = SS; + +// create Serial stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// store error strings in flash to save RAM +#define error(s) sd.errorHalt(F(s)) +//------------------------------------------------------------------------------ +/* + * date/time values for debug + * normally supplied by a real-time clock or GPS + */ +// date 1-Oct-14 +uint16_t year = 2014; +uint8_t month = 10; +uint8_t day = 1; + +// time 20:30:40 +uint8_t hour = 20; +uint8_t minute = 30; +uint8_t second = 40; +//------------------------------------------------------------------------------ +/* + * User provided date time callback function. + * See SdFile::dateTimeCallback() for usage. + */ +void dateTime(uint16_t* date, uint16_t* time) { + // User gets date and time from GPS or real-time + // clock in real callback function + + // return date using FAT_DATE macro to format fields + *date = FAT_DATE(year, month, day); + + // return time using FAT_TIME macro to format fields + *time = FAT_TIME(hour, minute, second); +} +//------------------------------------------------------------------------------ +/* + * Function to print all timestamps. + */ +void printTimestamps(SdFile& f) { + dir_t d; + if (!f.dirEntry(&d)) { + error("f.dirEntry failed"); + } + + cout << F("Creation: "); + f.printFatDate(d.creationDate); + cout << ' '; + f.printFatTime(d.creationTime); + cout << endl; + + cout << F("Modify: "); + f.printFatDate(d.lastWriteDate); + cout <<' '; + f.printFatTime(d.lastWriteTime); + cout << endl; + + cout << F("Access: "); + f.printFatDate(d.lastAccessDate); + cout << endl; +} +//------------------------------------------------------------------------------ +void setup(void) { + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // remove files if they exist + sd.remove("callback.txt"); + sd.remove("default.txt"); + sd.remove("stamp.txt"); + + // create a new file with default timestamps + if (!file.open("default.txt", O_CREAT | O_WRITE)) { + error("open default.txt failed"); + } + cout << F("\nOpen with default times\n"); + printTimestamps(file); + + // close file + file.close(); + /* + * Test the date time callback function. + * + * dateTimeCallback() sets the function + * that is called when a file is created + * or when a file's directory entry is + * modified by sync(). + * + * The callback can be disabled by the call + * SdFile::dateTimeCallbackCancel() + */ + // set date time callback function + SdFile::dateTimeCallback(dateTime); + + // create a new file with callback timestamps + if (!file.open("callback.txt", O_CREAT | O_WRITE)) { + error("open callback.txt failed"); + } + cout << ("\nOpen with callback times\n"); + printTimestamps(file); + + // change call back date + day += 1; + + // must add two to see change since FAT second field is 5-bits + second += 2; + + // modify file by writing a byte + file.write('t'); + + // force dir update + file.sync(); + + cout << F("\nTimes after write\n"); + printTimestamps(file); + + // close file + file.close(); + /* + * Test timestamp() function + * + * Cancel callback so sync will not + * change access/modify timestamp + */ + SdFile::dateTimeCallbackCancel(); + + // create a new file with default timestamps + if (!file.open("stamp.txt", O_CREAT | O_WRITE)) { + error("open stamp.txt failed"); + } + // set creation date time + if (!file.timestamp(T_CREATE, 2014, 11, 10, 1, 2, 3)) { + error("set create time failed"); + } + // set write/modification date time + if (!file.timestamp(T_WRITE, 2014, 11, 11, 4, 5, 6)) { + error("set write time failed"); + } + // set access date + if (!file.timestamp(T_ACCESS, 2014, 11, 12, 7, 8, 9)) { + error("set access time failed"); + } + cout << F("\nTimes after timestamp() calls\n"); + printTimestamps(file); + + file.close(); + cout << F("\nDone\n"); +} + +void loop() {} diff --git a/libraries/SdFat/examples/TwoCards/TwoCards.ino b/libraries/SdFat/examples/TwoCards/TwoCards.ino new file mode 100644 index 0000000..d77292c --- /dev/null +++ b/libraries/SdFat/examples/TwoCards/TwoCards.ino @@ -0,0 +1,170 @@ +/* + * Warning This example requires extra RAM and may crash on Uno. + * Example use of two SD cards. + */ +#include +#include "SdFat.h" +#include "FreeStack.h" + +SdFat sd1; +const uint8_t SD1_CS = 10; // chip select for sd1 + +SdFat sd2; +const uint8_t SD2_CS = 4; // chip select for sd2 + +const uint8_t BUF_DIM = 100; +uint8_t buf[BUF_DIM]; + +const uint32_t FILE_SIZE = 1000000; +const uint16_t NWRITE = FILE_SIZE/BUF_DIM; +//------------------------------------------------------------------------------ +// print error msg, any SD error codes, and halt. +// store messages in flash +#define errorExit(msg) errorHalt(F(msg)) +#define initError(msg) initErrorHalt(F(msg)) +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + Serial.print(F("FreeStack: ")); + + Serial.println(FreeStack()); + + // fill buffer with known data + for (size_t i = 0; i < sizeof(buf); i++) { + buf[i] = i; + } + + Serial.println(F("type any character to start")); + while (!Serial.available()) { + SysCall::yield(); + } + + // disable sd2 while initializing sd1 + pinMode(SD2_CS, OUTPUT); + digitalWrite(SD2_CS, HIGH); + + // initialize the first card + if (!sd1.begin(SD1_CS)) { + sd1.initError("sd1:"); + } + // create Dir1 on sd1 if it does not exist + if (!sd1.exists("/Dir1")) { + if (!sd1.mkdir("/Dir1")) { + sd1.errorExit("sd1.mkdir"); + } + } + // initialize the second card + if (!sd2.begin(SD2_CS)) { + sd2.initError("sd2:"); + } +// create Dir2 on sd2 if it does not exist + if (!sd2.exists("/Dir2")) { + if (!sd2.mkdir("/Dir2")) { + sd2.errorExit("sd2.mkdir"); + } + } + // list root directory on both cards + Serial.println(F("------sd1 root-------")); + sd1.ls(); + Serial.println(F("------sd2 root-------")); + sd2.ls(); + + // make /Dir1 the default directory for sd1 + if (!sd1.chdir("/Dir1")) { + sd1.errorExit("sd1.chdir"); + } + + // make /Dir2 the default directory for sd2 + if (!sd2.chdir("/Dir2")) { + sd2.errorExit("sd2.chdir"); + } + + // list current directory on both cards + Serial.println(F("------sd1 Dir1-------")); + sd1.ls(); + Serial.println(F("------sd2 Dir2-------")); + sd2.ls(); + Serial.println(F("---------------------")); + + // remove rename.bin from /Dir2 directory of sd2 + if (sd2.exists("rename.bin")) { + if (!sd2.remove("rename.bin")) { + sd2.errorExit("remove rename.bin"); + } + } + // set the current working directory for open() to sd1 + sd1.chvol(); + + // create or open /Dir1/test.bin and truncate it to zero length + SdFile file1; + if (!file1.open("test.bin", O_RDWR | O_CREAT | O_TRUNC)) { + sd1.errorExit("file1"); + } + Serial.println(F("Writing test.bin to sd1")); + + // write data to /Dir1/test.bin on sd1 + for (uint16_t i = 0; i < NWRITE; i++) { + if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { + sd1.errorExit("sd1.write"); + } + } + // set the current working directory for open() to sd2 + sd2.chvol(); + + // create or open /Dir2/copy.bin and truncate it to zero length + SdFile file2; + if (!file2.open("copy.bin", O_WRITE | O_CREAT | O_TRUNC)) { + sd2.errorExit("file2"); + } + Serial.println(F("Copying test.bin to copy.bin")); + + // copy file1 to file2 + file1.rewind(); + uint32_t t = millis(); + + while (1) { + int n = file1.read(buf, sizeof(buf)); + if (n < 0) { + sd1.errorExit("read1"); + } + if (n == 0) { + break; + } + if ((int)file2.write(buf, n) != n) { + sd2.errorExit("write2"); + } + } + t = millis() - t; + Serial.print(F("File size: ")); + Serial.println(file2.fileSize()); + Serial.print(F("Copy time: ")); + Serial.print(t); + Serial.println(F(" millis")); + // close test.bin + file1.close(); + file2.close(); + // list current directory on both cards + Serial.println(F("------sd1 -------")); + sd1.ls("/", LS_R | LS_DATE | LS_SIZE); + Serial.println(F("------sd2 -------")); + sd2.ls("/", LS_R | LS_DATE | LS_SIZE); + Serial.println(F("---------------------")); + Serial.println(F("Renaming copy.bin")); + // rename the copy + if (!sd2.rename("copy.bin", "rename.bin")) { + sd2.errorExit("sd2.rename"); + } + // list current directory on both cards + Serial.println(F("------sd1 -------")); + sd1.ls("/", LS_R | LS_DATE | LS_SIZE); + Serial.println(F("------sd2 -------")); + sd2.ls("/", LS_R | LS_DATE | LS_SIZE); + Serial.println(F("---------------------")); + Serial.println(F("Done")); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/examples/VolumeFreeSpace/VolumeFreeSpace.ino b/libraries/SdFat/examples/VolumeFreeSpace/VolumeFreeSpace.ino new file mode 100644 index 0000000..229843c --- /dev/null +++ b/libraries/SdFat/examples/VolumeFreeSpace/VolumeFreeSpace.ino @@ -0,0 +1,81 @@ +/* + * This program demonstrates the freeClusterCount() call. + */ +#include +#include "SdFat.h" +/* + * SD chip select pin. Common values are: + * + * Arduino Ethernet shield, pin 4. + * SparkFun SD shield, pin 8. + * Adafruit Datalogging shield, pin 10. + * Default SD chip select is the SPI SS pin. + */ +const uint8_t chipSelect = SS; + +#define TEST_FILE "Cluster.test" +// file system +SdFat sd; + +// test file +SdFile file; + +// Serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void printFreeSpace() { + cout << F("freeClusterCount() call time: "); + uint32_t m = micros(); + uint32_t volFree = sd.vol()->freeClusterCount(); + cout << micros() - m << F(" micros\n"); + cout << F("freeClusters: ") << volFree << setprecision(3) << endl; + float fs = 0.000512*volFree*sd.vol()->blocksPerCluster(); + cout << F("freeSpace: ") << fs << F(" MB (MB = 1,000,000 bytes)\n\n"); +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + if (!MAINTAIN_FREE_CLUSTER_COUNT) { + cout << F("Please edit SdFatConfig.h and set\n"); + cout << F("MAINTAIN_FREE_CLUSTER_COUNT nonzero for\n"); + cout << F("maximum freeClusterCount() performance.\n\n"); + } + // F stores strings in flash to save RAM + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + // Insure no TEST_FILE. + sd.remove(TEST_FILE); + + cout << F("\nFirst call to freeClusterCount scans the FAT.\n\n"); + printFreeSpace(); + + cout << F("Create and write to ") << TEST_FILE << endl; + if (!file.open(TEST_FILE, O_WRITE | O_CREAT)) { + sd.errorHalt(F("Create failed")); + } + file.print(F("Cause a cluster to be allocated")); + file.close(); + + cout << F("\nSecond freeClusterCount call is faster if\n"); + cout << F("MAINTAIN_FREE_CLUSTER_COUNT is nonzero.\n\n"); + + printFreeSpace(); + + cout << F("Remove ") << TEST_FILE << endl << endl; + sd.remove(TEST_FILE); + printFreeSpace(); + cout << F("Done") << endl; +} +//------------------------------------------------------------------------------ +void loop() {} \ No newline at end of file diff --git a/libraries/SdFat/examples/bench/bench.ino b/libraries/SdFat/examples/bench/bench.ino new file mode 100644 index 0000000..3d0970e --- /dev/null +++ b/libraries/SdFat/examples/bench/bench.ino @@ -0,0 +1,221 @@ +/* + * This program is a simple binary write/read benchmark. + */ +#include +#include "SdFat.h" +#include "FreeStack.h" + +// Set USE_SDIO to zero for SPI card access. +#define USE_SDIO 0 + +// SD chip select pin +const uint8_t chipSelect = SS; + +// Size of read/write. +const size_t BUF_SIZE = 512; + +// File size in MB where MB = 1,000,000 bytes. +const uint32_t FILE_SIZE_MB = 5; + +// Write pass count. +const uint8_t WRITE_COUNT = 2; + +// Read pass count. +const uint8_t READ_COUNT = 2; +//============================================================================== +// End of configuration constants. +//------------------------------------------------------------------------------ +// File size in bytes. +const uint32_t FILE_SIZE = 1000000UL*FILE_SIZE_MB; + +uint8_t buf[BUF_SIZE]; + +// file system +#if USE_SDIO +// Traditional DMA version. +// SdFatSdio sd; +// Faster version. +SdFatSdioEX sd; +#else // USE_SDIO +SdFat sd; +#endif // USE_SDIO + +// Set ENABLE_EXTENDED_TRANSFER_CLASS to use extended SD I/O. +// Requires dedicated use of the SPI bus. +// SdFatEX sd; + +// Set ENABLE_SOFTWARE_SPI_CLASS to use software SPI. +// Args are misoPin, mosiPin, sckPin. +// SdFatSoftSpi<6, 7, 5> sd; + +// test file +SdFile file; + +// Serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// Store error strings in flash to save RAM. +#define error(s) sd.errorHalt(F(s)) +//------------------------------------------------------------------------------ +void cidDmp() { + cid_t cid; + if (!sd.card()->readCID(&cid)) { + error("readCID failed"); + } + cout << F("\nManufacturer ID: "); + cout << hex << int(cid.mid) << dec << endl; + cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl; + cout << F("Product: "); + for (uint8_t i = 0; i < 5; i++) { + cout << cid.pnm[i]; + } + cout << F("\nVersion: "); + cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl; + cout << F("Serial number: ") << hex << cid.psn << dec << endl; + cout << F("Manufacturing date: "); + cout << int(cid.mdt_month) << '/'; + cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl; + cout << endl; +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + delay(1000); + cout << F("\nUse a freshly formatted SD for best performance.\n"); + + // use uppercase in hex and use 0X base prefix + cout << uppercase << showbase << endl; +} +//------------------------------------------------------------------------------ +void loop() { + float s; + uint32_t t; + uint32_t maxLatency; + uint32_t minLatency; + uint32_t totalLatency; + + // Discard any input. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + + // F( stores strings in flash to save RAM + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + + cout << F("FreeStack: ") << FreeStack() << endl; + +#if USE_SDIO + if (!sd.begin()) { + sd.initErrorHalt(); + } +#else // USE_SDIO + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } +#endif // USE_SDIO + cout << F("Type is FAT") << int(sd.vol()->fatType()) << endl; + cout << F("Card size: ") << sd.card()->cardSize()*512E-9; + cout << F(" GB (GB = 1E9 bytes)") << endl; + + cidDmp(); + + // open or create file - truncate existing file. + if (!file.open("bench.dat", O_CREAT | O_TRUNC | O_RDWR)) { + error("open failed"); + } + + // fill buf with known data + for (size_t i = 0; i < (BUF_SIZE-2); i++) { + buf[i] = 'A' + (i % 26); + } + buf[BUF_SIZE-2] = '\r'; + buf[BUF_SIZE-1] = '\n'; + + cout << F("File size ") << FILE_SIZE_MB << F(" MB\n"); + cout << F("Buffer size ") << BUF_SIZE << F(" bytes\n"); + cout << F("Starting write test, please wait.") << endl << endl; + + // do write test + uint32_t n = FILE_SIZE/sizeof(buf); + cout < m) { + minLatency = m; + } + totalLatency += m; + } + file.sync(); + t = millis() - t; + s = file.fileSize(); + cout << s/t <<',' << maxLatency << ',' << minLatency; + cout << ',' << totalLatency/n << endl; + } + cout << endl << F("Starting read test, please wait.") << endl; + cout << endl < m) { + minLatency = m; + } + totalLatency += m; + if (buf[BUF_SIZE-1] != '\n') { + error("data check"); + } + } + s = file.fileSize(); + t = millis() - t; + cout << s/t <<',' << maxLatency << ',' << minLatency; + cout << ',' << totalLatency/n << endl; + } + cout << endl << F("Done") << endl; + file.close(); +} \ No newline at end of file diff --git a/libraries/SdFat/examples/dataLogger/dataLogger.ino b/libraries/SdFat/examples/dataLogger/dataLogger.ino new file mode 100644 index 0000000..390273d --- /dev/null +++ b/libraries/SdFat/examples/dataLogger/dataLogger.ino @@ -0,0 +1,150 @@ +/* + * Simple data logger. + */ +#include +#include "SdFat.h" + +// SD chip select pin. Be sure to disable any other SPI devices such as Enet. +const uint8_t chipSelect = SS; + +// Interval between data records in milliseconds. +// The interval must be greater than the maximum SD write latency plus the +// time to acquire and write data to the SD to avoid overrun errors. +// Run the bench example to check the quality of your SD card. +const uint32_t SAMPLE_INTERVAL_MS = 1000; + +// Log file base name. Must be six characters or less. +#define FILE_BASE_NAME "Data" +//------------------------------------------------------------------------------ +// File system object. +SdFat sd; + +// Log file. +SdFile file; + +// Time in micros for next data record. +uint32_t logTime; + +//============================================================================== +// User functions. Edit writeHeader() and logData() for your requirements. + +const uint8_t ANALOG_COUNT = 4; +//------------------------------------------------------------------------------ +// Write data header. +void writeHeader() { + file.print(F("micros")); + for (uint8_t i = 0; i < ANALOG_COUNT; i++) { + file.print(F(",adc")); + file.print(i, DEC); + } + file.println(); +} +//------------------------------------------------------------------------------ +// Log a data record. +void logData() { + uint16_t data[ANALOG_COUNT]; + + // Read all channels to avoid SD write latency between readings. + for (uint8_t i = 0; i < ANALOG_COUNT; i++) { + data[i] = analogRead(i); + } + // Write data to file. Start with log time in micros. + file.print(logTime); + + // Write ADC data to CSV record. + for (uint8_t i = 0; i < ANALOG_COUNT; i++) { + file.write(','); + file.print(data[i]); + } + file.println(); +} +//============================================================================== +// Error messages stored in flash. +#define error(msg) sd.errorHalt(F(msg)) +//------------------------------------------------------------------------------ +void setup() { + const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1; + char fileName[13] = FILE_BASE_NAME "00.csv"; + + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + delay(1000); + + Serial.println(F("Type any character to start")); + while (!Serial.available()) { + SysCall::yield(); + } + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // Find an unused file name. + if (BASE_NAME_SIZE > 6) { + error("FILE_BASE_NAME too long"); + } + while (sd.exists(fileName)) { + if (fileName[BASE_NAME_SIZE + 1] != '9') { + fileName[BASE_NAME_SIZE + 1]++; + } else if (fileName[BASE_NAME_SIZE] != '9') { + fileName[BASE_NAME_SIZE + 1] = '0'; + fileName[BASE_NAME_SIZE]++; + } else { + error("Can't create file name"); + } + } + if (!file.open(fileName, O_CREAT | O_WRITE | O_EXCL)) { + error("file.open"); + } + // Read any Serial data. + do { + delay(10); + } while (Serial.available() && Serial.read() >= 0); + + Serial.print(F("Logging to: ")); + Serial.println(fileName); + Serial.println(F("Type any character to stop")); + + // Write data header. + writeHeader(); + + // Start on a multiple of the sample interval. + logTime = micros()/(1000UL*SAMPLE_INTERVAL_MS) + 1; + logTime *= 1000UL*SAMPLE_INTERVAL_MS; +} +//------------------------------------------------------------------------------ +void loop() { + // Time for next record. + logTime += 1000UL*SAMPLE_INTERVAL_MS; + + // Wait for log time. + int32_t diff; + do { + diff = micros() - logTime; + } while (diff < 0); + + // Check for data rate too high. + if (diff > 10) { + error("Missed data record"); + } + + logData(); + + // Force data to SD and update the directory entry to avoid data loss. + if (!file.sync() || file.getWriteError()) { + error("write error"); + } + + if (Serial.available()) { + // Close file and stop. + file.close(); + Serial.println(F("Done")); + SysCall::halt(); + } +} \ No newline at end of file diff --git a/libraries/SdFat/examples/fgets/fgets.ino b/libraries/SdFat/examples/fgets/fgets.ino new file mode 100644 index 0000000..6d3eb9f --- /dev/null +++ b/libraries/SdFat/examples/fgets/fgets.ino @@ -0,0 +1,87 @@ +// Demo of fgets function to read lines from a file. +#include +#include "SdFat.h" + +// SD chip select pin +const uint8_t chipSelect = SS; + +SdFat sd; +// print stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// store error strings in flash memory +#define error(s) sd.errorHalt(F(s)) +//------------------------------------------------------------------------------ +void demoFgets() { + char line[25]; + int n; + // open test file + SdFile rdfile("fgets.txt", O_READ); + + // check for open error + if (!rdfile.isOpen()) { + error("demoFgets"); + } + + cout << endl << F( + "Lines with '>' end with a '\\n' character\n" + "Lines with '#' do not end with a '\\n' character\n" + "\n"); + + // read lines from the file + while ((n = rdfile.fgets(line, sizeof(line))) > 0) { + if (line[n - 1] == '\n') { + cout << '>' << line; + } else { + cout << '#' << line << endl; + } + } +} +//------------------------------------------------------------------------------ +void makeTestFile() { + // create or open test file + SdFile wrfile("fgets.txt", O_WRITE | O_CREAT | O_TRUNC); + + // check for open error + if (!wrfile.isOpen()) { + error("MakeTestFile"); + } + + // write test file + wrfile.print(F( + "Line with CRLF\r\n" + "Line with only LF\n" + "Long line that will require an extra read\n" + "\n" // empty line + "Line at EOF without NL" + )); + wrfile.close(); +} +//------------------------------------------------------------------------------ +void setup(void) { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + delay(400); // catch Due reset problem + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + makeTestFile(); + + demoFgets(); + + cout << F("\nDone\n"); +} +void loop(void) {} diff --git a/libraries/SdFat/examples/formatting/formatting.ino b/libraries/SdFat/examples/formatting/formatting.ino new file mode 100644 index 0000000..8d50c2b --- /dev/null +++ b/libraries/SdFat/examples/formatting/formatting.ino @@ -0,0 +1,72 @@ +/* + * Print a table with various formatting options + * Format dates + */ +#include +#include "SdFat.h" + +// create Serial stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// print a table to demonstrate format manipulators +void example(void) { + const int max = 10; + const int width = 4; + + for (int row = 1; row <= max; row++) { + for (int col = 1; col <= max; col++) { + cout << setw(width) << row * col << (col == max ? '\n' : ' '); + } + } + cout << endl; +} +//------------------------------------------------------------------------------ +// print a date as mm/dd/yyyy with zero fill in mm and dd +// shows how to set and restore the fill character +void showDate(int m, int d, int y) { + // convert two digit year + if (y < 100) { + y += 2000; + } + + // set new fill to '0' save old fill character + char old = cout.fill('0'); + + // print date + cout << setw(2) << m << '/' << setw(2) << d << '/' << y << endl; + + // restore old fill character + cout.fill(old); +} +//------------------------------------------------------------------------------ +void setup(void) { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + delay(2000); + + cout << endl << "default formatting" << endl; + example(); + + cout << showpos << "showpos" << endl; + example(); + + cout << hex << left << showbase << "hex left showbase" << endl; + example(); + + cout << internal << setfill('0') << uppercase; + cout << "uppercase hex internal showbase fill('0')" < +#include "SdFat.h" + +// SD chip select pin +const uint8_t chipSelect = SS; + +// file system object +SdFat sd; + +// create a serial stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void makeTestFile() { + ofstream sdout("getline.txt"); + // use flash for text to save RAM + sdout << F( + "short line\n" + "\n" + "17 character line\n" + "too long for buffer\n" + "line with no nl"); + + sdout.close(); +} +//------------------------------------------------------------------------------ +void testGetline() { + const int line_buffer_size = 18; + char buffer[line_buffer_size]; + ifstream sdin("getline.txt"); + int line_number = 0; + + while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) { + int count = sdin.gcount(); + if (sdin.fail()) { + cout << "Partial long line"; + sdin.clear(sdin.rdstate() & ~ios_base::failbit); + } else if (sdin.eof()) { + cout << "Partial final line"; // sdin.fail() is false + } else { + count--; // Don’t include newline in count + cout << "Line " << ++line_number; + } + cout << " (" << count << " chars): " << buffer << endl; + } +} +//------------------------------------------------------------------------------ +void setup(void) { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + + // F stores strings in flash to save RAM + cout << F("Type any character to start\n"); + while (!Serial.available()) { + SysCall::yield(); + } + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // make the test file + makeTestFile(); + + // run the example + testGetline(); + cout << "\nDone!\n"; +} +//------------------------------------------------------------------------------ +void loop(void) {} diff --git a/libraries/SdFat/examples/rename/rename.ino b/libraries/SdFat/examples/rename/rename.ino new file mode 100644 index 0000000..81c5d0c --- /dev/null +++ b/libraries/SdFat/examples/rename/rename.ino @@ -0,0 +1,106 @@ +/* + * This program demonstrates use of SdFile::rename() + * and SdFat::rename(). + */ +#include +#include "SdFat.h" + +// SD chip select pin +const uint8_t chipSelect = SS; + +// file system +SdFat sd; + +// Serial print stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// store error strings in flash to save RAM +#define error(s) sd.errorHalt(F(s)) +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + cout << F("Insert an empty SD. Type any character to start.") << endl; + while (!Serial.available()) { + SysCall::yield(); + } + + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + + // Remove file/dirs from previous run. + if (sd.exists("dir2/DIR3/NAME3.txt")) { + cout << F("Removing /dir2/DIR3/NAME3.txt") << endl; + if (!sd.remove("dir2/DIR3/NAME3.txt") || + !sd.rmdir("dir2/DIR3/") || + !sd.rmdir("dir2/")) { + error("remove/rmdir failed"); + } + } + // create a file and write one line to the file + SdFile file("Name1.txt", O_WRITE | O_CREAT); + if (!file.isOpen()) { + error("Name1.txt"); + } + file.println("A test line for Name1.txt"); + + // rename the file name2.txt and add a line. + // sd.vwd() is the volume working directory, root. + if (!file.rename(sd.vwd(), "name2.txt")) { + error("name2.txt"); + } + file.println("A test line for name2.txt"); + + // list files + cout << F("------") << endl; + sd.ls(LS_R); + + // make a new directory - "Dir1" + if (!sd.mkdir("Dir1")) { + error("Dir1"); + } + + // move file into Dir1, rename it NAME3.txt and add a line + if (!file.rename(sd.vwd(), "Dir1/NAME3.txt")) { + error("NAME3.txt"); + } + file.println("A line for Dir1/NAME3.txt"); + + // list files + cout << F("------") << endl; + sd.ls(LS_R); + + // make directory "dir2" + if (!sd.mkdir("dir2")) { + error("dir2"); + } + + // close file before rename(oldPath, newPath) + file.close(); + + // move Dir1 into dir2 and rename it DIR3 + if (!sd.rename("Dir1", "dir2/DIR3")) { + error("dir2/DIR3"); + } + + // open file for append in new location and add a line + if (!file.open("dir2/DIR3/NAME3.txt", O_WRITE | O_APPEND)) { + error("dir2/DIR3/NAME3.txt"); + } + file.println("A line for dir2/DIR3/NAME3.txt"); + file.close(); + + // list files + cout << F("------") << endl; + sd.ls(LS_R); + + cout << F("Done") << endl; +} +void loop() {} diff --git a/libraries/SdFat/examples/wipe/wipe.ino b/libraries/SdFat/examples/wipe/wipe.ino new file mode 100644 index 0000000..6d1bc93 --- /dev/null +++ b/libraries/SdFat/examples/wipe/wipe.ino @@ -0,0 +1,42 @@ +// Example to wipe all data from an already formatted SD. +#include +#include "SdFat.h" +const int chipSelect = SS; + +SdFat sd; + +void setup() { + int c; + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + SysCall::yield(); + } + Serial.println("Type 'Y' to wipe all data."); + while (!Serial.available()) { + SysCall::yield(); + } + c = Serial.read(); + if (c != 'Y') { + sd.errorHalt("Quitting, you did not type 'Y'."); + } + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.initErrorHalt(); + } + // Use wipe() for no dot progress indicator. + if (!sd.wipe(&Serial)) { + sd.errorHalt("Wipe failed."); + } + // Must reinitialize after wipe. + // Initialize at the highest speed supported by the board that is + // not over 50 MHz. Try a lower speed if SPI errors occur. + if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) { + sd.errorHalt("Second init failed."); + } + Serial.println("Done"); +} + +void loop() { +} diff --git a/libraries/SdFat/extras/AnalogBinLoggerExtras/ADC_ENOB.PNG b/libraries/SdFat/extras/AnalogBinLoggerExtras/ADC_ENOB.PNG new file mode 100644 index 0000000..8f23768 Binary files /dev/null and b/libraries/SdFat/extras/AnalogBinLoggerExtras/ADC_ENOB.PNG differ diff --git a/libraries/SdFat/extras/AnalogBinLoggerExtras/ADCdocs/ATmegaADCAccuracy.pdf b/libraries/SdFat/extras/AnalogBinLoggerExtras/ADCdocs/ATmegaADCAccuracy.pdf new file mode 100644 index 0000000..46ede85 Binary files /dev/null and b/libraries/SdFat/extras/AnalogBinLoggerExtras/ADCdocs/ATmegaADCAccuracy.pdf differ diff --git a/libraries/SdFat/extras/AnalogBinLoggerExtras/ADCdocs/ExcelFFT.pdf b/libraries/SdFat/extras/AnalogBinLoggerExtras/ADCdocs/ExcelFFT.pdf new file mode 100644 index 0000000..5e7c94b Binary files /dev/null and b/libraries/SdFat/extras/AnalogBinLoggerExtras/ADCdocs/ExcelFFT.pdf differ diff --git a/libraries/SdFat/extras/AnalogBinLoggerExtras/AdcErrorStudy.txt b/libraries/SdFat/extras/AnalogBinLoggerExtras/AdcErrorStudy.txt new file mode 100644 index 0000000..d24d1f6 --- /dev/null +++ b/libraries/SdFat/extras/AnalogBinLoggerExtras/AdcErrorStudy.txt @@ -0,0 +1,98 @@ +Static Tests of the Arduino Internal ADC. + +Several people have asked about the DC accuracy of the Arduino ADC when used in my data logging applications at slow sample rates. + +Here are my results of some "hobby level" measurements of the Arduino ADC. + +One question is how important is the ADC clock rate. I did measurents for an ADC clock rate of 125 kHz to 2MHz. + +Another question is how much does Noise Reduction Mode help. I did a series of measurements using this mode. + +Noise Reduction Mode only reduced the mean absolute error slightly. + +I do calibration to remove Offset Error and Gain Error. Calibration is very important for good accuracy. + +These tests depend on the Arduino voltage regulator providing a stable voltage during the tests. The Arduino ADC reference voltage is Vcc for these tests. This may not be realistic for practical applications + +Integral Non-linearity (INL) is the main remaining source of error. + +Here are my results for static (DC) tests of the internal ADC for three UNOs. + +The Arduinos are powered by a high quality nine volt power supply. + +These tests measure a DC level so do not include problems due to time jitter, S/H time, and other dynamic errors. +There are several studies of the dynamic behavior of the Arduino ADC that determine ENOB (Effective Number Of Bits). + +I used a shield with a 12-bit MCP4921 DAC to generate voltage levels. This ADC has an output buffer so it provides a very low impedance source. + +I measured the voltage of the DAC with a calibrated 18-bit MCP3422 ADC on the shield. + +I used DAC levels from 20 to 4075 to avoid zero offset errors at low voltages and DAC buffer problems at high voltages. + +Each series of measurements has 4056 data points. + +This is a voltage range of about 0.023 to 4.972 volts. + +I calibrated the Arduino ADC for each series of measurements with a linear fit of the form. + +v = a + b*adcValue + +Errors are the difference between the value measured with the 18-bit ADC and the calibrated value measured with the AVR ADC. + +I also show the results for no calibration, the NoCal column, using the datasheet formula. + +Vin = Vref*adcValue/1024 + + +The rows in the tables tables are. + +Min - minimum error in millivolts + +Max - maximum error in millivolts + +MAE - mean absolute error in millivolts + + +The columns in the tables are: + +Ideal - results for a perfect 10-bit ADC for comparison. + +NoCal - datasheet formula (5/1024)*adcValue with Noise Reduction Mode. + +NR128 - Noise Reduction mode with Prescaler of 128 (ADC clock of 125 kHz). + +PS128 - analogRead with Prescaler of 128 (ADC clock of 125 kHz). + +PS64 - analogRead with Prescaler of 64 (ADC clock of 250 kHz). + +PS32 - analogRead with Prescaler of 32 (ADC clock of 500 kHz). + +PS16 - analogRead with Prescaler of 16 (ADC clock of 1 MHz). + +PS8 - analogRead with Prescaler of 8 (ADC clock of 2 MHz). + + +Results for three UNO Arduinos + + First Arduino - Error Millivolts + + Ideal NoCal NR128 PS128 PS64 PS32 PS16 PS8 +Min -2.44 -2.43 -3.72 -4.01 -3.88 -4.53 -6.57 -27.18 +Max 2.44 11.69 3.74 4.24 4.15 5.17 8.69 23.21 +MAE 1.22 5.02 1.33 1.38 1.37 1.44 1.96 4.11 + + Second Arduino - Error Millivolts + + Ideal NoCal NR128 PS128 PS64 PS32 PS16 PS8 +Min -2.44 -9.24 -4.87 -4.86 -5.05 -5.34 -6.52 -24.04 +Max 2.44 11.62 3.95 4.64 4.69 5.71 8.41 21.29 +MAE 1.22 5.33 1.41 1.43 1.44 1.53 2.02 4.05 + + Third Arduino - Error Millivolts + + Ideal NoCal NR128 PS128 PS64 PS32 PS16 PS8 +Min -2.44 -7.88 -4.12 -4.40 -4.32 -4.41 -6.97 -26.93 +Max 2.44 12.53 3.80 4.04 4.18 5.27 8.84 24.59 +MAE 1.22 4.85 1.29 1.33 1.34 1.42 1.91 4.10 + + diff --git a/libraries/SdFat/extras/AnalogBinLoggerExtras/DATA.png b/libraries/SdFat/extras/AnalogBinLoggerExtras/DATA.png new file mode 100644 index 0000000..a9b31aa Binary files /dev/null and b/libraries/SdFat/extras/AnalogBinLoggerExtras/DATA.png differ diff --git a/libraries/SdFat/extras/AnalogBinLoggerExtras/FFT.png b/libraries/SdFat/extras/AnalogBinLoggerExtras/FFT.png new file mode 100644 index 0000000..dc481a6 Binary files /dev/null and b/libraries/SdFat/extras/AnalogBinLoggerExtras/FFT.png differ diff --git a/libraries/SdFat/extras/AnalogBinLoggerExtras/RateTable.txt b/libraries/SdFat/extras/AnalogBinLoggerExtras/RateTable.txt new file mode 100644 index 0000000..554ba11 --- /dev/null +++ b/libraries/SdFat/extras/AnalogBinLoggerExtras/RateTable.txt @@ -0,0 +1,21 @@ +Maximum Sample Rate Table + + ADC clock kHz + 125 250 500 1000 +pins +1 7692 14286 25000 40000 +2 3810 6667 11111 16667 +3 2572 4790 8421 13559 +4 1942 3636 6452 10526 +5 1559 2930 5229 8602 +6 1303 2454 4396 7273 +7 1119 2111 3791 6299 +8 980 1852 3333 5556 +9 872 1649 2974 4969 +10 786 1487 2685 4494 +11 715 1354 2446 4103 +12 656 1242 2247 3774 +13 606 1148 2078 3493 +14 563 1067 1932 3252 +15 525 996 1806 3042 +16 493 935 1695 2857 diff --git a/libraries/SdFat/extras/AnalogBinLoggerExtras/bintocsv/AnalogBinLogger.h b/libraries/SdFat/extras/AnalogBinLoggerExtras/bintocsv/AnalogBinLogger.h new file mode 100644 index 0000000..da4d448 --- /dev/null +++ b/libraries/SdFat/extras/AnalogBinLoggerExtras/bintocsv/AnalogBinLogger.h @@ -0,0 +1,39 @@ +#ifndef AnalogBinLogger_h +#define AnalogBinLogger_h +//------------------------------------------------------------------------------ +// First block of file. +struct metadata_t { + unsigned long adcFrequency; // ADC clock frequency + unsigned long cpuFrequency; // CPU clock frequency + unsigned long sampleInterval; // Sample interval in CPU cycles. + unsigned long recordEightBits; // Size of ADC values, nonzero for 8-bits. + unsigned long pinCount; // Number of analog pins in a sample. + unsigned long pinNumber[123]; // List of pin numbers in a sample. +}; +//------------------------------------------------------------------------------ +// Data block for 8-bit ADC mode. +const size_t DATA_DIM8 = 508; +struct block8_t { + unsigned short count; // count of data bytes + unsigned short overrun; // count of overruns since last block + unsigned char data[DATA_DIM8]; +}; +//------------------------------------------------------------------------------ +// Data block for 10-bit ADC mode. +const size_t DATA_DIM16 = 254; +struct block16_t { + unsigned short count; // count of data bytes + unsigned short overrun; // count of overruns since last block + unsigned short data[DATA_DIM16]; +}; +//------------------------------------------------------------------------------ +// Data block for PC use +struct adcdata_t { + unsigned short count; // count of data bytes + unsigned short overrun; // count of overruns since last block + union { + unsigned char u8[DATA_DIM8]; + unsigned short u16[DATA_DIM16]; + } data; +}; +#endif // AnalogBinLogger_h \ No newline at end of file diff --git a/libraries/SdFat/extras/AnalogBinLoggerExtras/bintocsv/bintocsv.cpp b/libraries/SdFat/extras/AnalogBinLoggerExtras/bintocsv/bintocsv.cpp new file mode 100644 index 0000000..922644b --- /dev/null +++ b/libraries/SdFat/extras/AnalogBinLoggerExtras/bintocsv/bintocsv.cpp @@ -0,0 +1,82 @@ +#include +#include "AnalogBinLogger.h" +FILE *source; +FILE *destination; +int count = 0; + +int main(int argc, char** argv) { + metadata_t meta; + adcdata_t adc; + // Make sure no padding/size problems. + if (sizeof(meta) != 512 || sizeof(adc) != 512) { + printf("block size error\n"); + return 0; + } + if (argc != 3) { + printf("missing arguments:\n"); + printf("%s binFile csvFile\n", argv[0]); + return 0; + } + source = fopen(argv[1], "rb"); + if (!source) { + printf("open failed for %s\n", argv[1]); + return 0; + } + if (fread(&meta, sizeof(meta), 1, source) != 1) { + printf("read meta data failed\n"); + return 0; + } + if ( meta.pinCount == 0 + || meta.pinCount > (sizeof(meta.pinNumber)/sizeof(meta.pinNumber[0])) + || meta.adcFrequency < 50000 || meta.adcFrequency > 4000000) { + printf("Invalid meta data\n"); + return 0; + } + destination = fopen(argv[2], "w"); + if (!destination) { + printf("open failed for %s\n", argv[2]); + return 0; + } + int pinCount = meta.pinCount; + printf("pinCount: %d\n", pinCount); + printf("Sample pins:"); + for (unsigned i = 0; i < meta.pinCount; i++) { + printf(" %d", meta.pinNumber[i]); + } + printf("\n"); + printf("ADC clock rate: %g kHz\n", 0.001*meta.adcFrequency); + float sampleInterval = (float)meta.sampleInterval/(float)meta.cpuFrequency; + printf("Sample rate: %g per sec\n", 1.0/sampleInterval); + printf("Sample interval: %.4f usec\n", 1.0e6*sampleInterval); + + fprintf(destination, "Interval,%.4f,usec\n", 1.0e6*sampleInterval); + // Write header with pin numbers + for (int i = 0; i < ((int)meta.pinCount - 1); i++) { + fprintf(destination, "pin%d,", meta.pinNumber[i]); + } + fprintf(destination, "pin%d\n", meta.pinNumber[meta.pinCount - 1]); + unsigned maxCount = meta.recordEightBits ? DATA_DIM8 : DATA_DIM16; + while (!feof(source)) { + if (fread(&adc, sizeof(adc), 1, source) != 1) break; + if (adc.count > maxCount) { + printf("****Invalid data block****\n"); + return 0; + } + if (adc.overrun) { + fprintf(destination, "Overruns,%d\n", adc.overrun); + } + for (int i = 0; i < adc.count; i++) { + unsigned value = meta.recordEightBits ? adc.data.u8[i] : adc.data.u16[i]; + if ((i + 1)%pinCount) { + fprintf(destination, "%d,", value); + } else { + fprintf(destination, "%d\n", value); + } + } + count += adc.count; + } + printf("%d ADC values read\n", count); + fclose(source); + fclose(destination); + return 0; +} \ No newline at end of file diff --git a/libraries/SdFat/extras/AnalogBinLoggerExtras/readme.txt b/libraries/SdFat/extras/AnalogBinLoggerExtras/readme.txt new file mode 100644 index 0000000..3ae2ca2 --- /dev/null +++ b/libraries/SdFat/extras/AnalogBinLoggerExtras/readme.txt @@ -0,0 +1,95 @@ +AnalogBinLogger.ino logs analog data to a binary SD file at high rates. + +Samples are logged at regular intervals by using timer1. Timer/Counter1 +Compare Match B is used to trigger the ADC for the first pin in a sample. +The ADC is triggered for remaining sample pins in the ADC conversion complete +interrupt routine. + +Data is captured in the ADC interrupt routine and saved in 512 byte buffers. + +Buffered data is written to the SD in a function called from loop(). The +entire data set is written to a large contiguous file as a single multi-block +write. This reduces write latency problems. + +Many inexpensive SD cards work well at lower rates. I used a $6.00 +SanDisk 4 GB class 4 card for testing. + +SanDisk class 4 cards work well at fairly high rates. I used the 4 GB SanDisk +card to log a single pin at 40,000 samples per second. + +You may need to increase the time between samples if your card has higher +latency. Using a Mega Arduino can help since it has more buffering. + +The bintocsv folder contains a PC program for converting binary files to +CSV files. Build it from the included source files. bintocvs is a command line program. + +bintocsv binFile csvFile + +AnalogBinLogger requires a recent version of the SdFat library. The SdFat +folder contains a beta version I used for development. + +The latest stable version is here: +http://code.google.com/p/sdfatlib/downloads/list + +You also need to install the included BufferedWriter library. It provides +fast text formatting. + +Example data for a 2 kHz sine wave logged at 40,000 samples per second is +shown in DATA.PNG and FFT.PNG shows a FFT of the data. See ExcelFFT.pdf +in the ADCdocs folder for details on calculating a FFT. + +The accuracy of the ADC samples depends on the ADC clock rate. See the +ADC_ENOB.PNG file for a plot of accuracy vs ADC clock frequency. + +See files in the ADCdocs folder for more information on ADC accuracy. + +To modify this program you will need a good knowledge of the Arduino +ADC, timer1 and C++ programming. This is not for the newbie. + +I have an LED and resistor connected to pin 3 to signal fatal errors and +data overruns. Fatal errors are indicated by a blinking led. Overrun errors +are indicated by a solid lit led. The count of samples dropped is written +to the SD and data logging continues. + +You can disable the error led feature by setting the error pin number negative: + +To use AnalogBinLogger, install these items. + +Place the BufferWriter and SdFat folders in your sketchbook libraries folder. + +Place the AnalogIsrLogger folder in your sketchbook folder. + +You must edit the configuration constants at the beginning of the program +to set the sample pins, sample rate, and other configuration values. + +Initially the program is setup to log the first five analog pins at 5000 +samples per second. Change these values to suit your needs. + +See RateTable.txt for maximum allowed sample rates vs pin count and ADC clock +frequency. + +The program has four commands: + +c - convert file to CSV +d - dump data to Serial +e - overrun error details +r - record ADC data + +All commands can be terminated by entering a character from the serial monitor. + +The c command converts the current binary file to a text file. Entering a +character on the serial monitor terminates the command. + +The d command converts the binary file to text and displays it on the serial +monitor. Entering a character on the serial monitor terminates the command. + +The e command displays details about overruns in the current binary file. +Data overruns happen when data samples are lost due to long write latency +of the SD. + +The r command will record ADC data to a binary file. It will terminate +when a character is entered on the serial monitor or the the maximum file +block count has been reached. + +A number of program options can be set by changing constants at the beginning +of the program. \ No newline at end of file diff --git a/libraries/SdFat/extras/MainPage/SdFatmainpage.h b/libraries/SdFat/extras/MainPage/SdFatmainpage.h new file mode 100644 index 0000000..b3c7346 --- /dev/null +++ b/libraries/SdFat/extras/MainPage/SdFatmainpage.h @@ -0,0 +1,399 @@ +/* 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 + * . + */ + +/** +\mainpage Arduino %SdFat Library +
Copyright © 2012, 2013, 2014, 2015, 2016 by William Greiman +
+ +\section Intro Introduction +The Arduino %SdFat Library is a minimal implementation of FAT16 and FAT32 +file systems on SD flash memory cards. Standard SD and high capacity SDHC +cards are supported. + +Experimental support for FAT12 can be enabled by setting FAT12_SUPPORT +nonzero in SdFatConfig.h. + +The %SdFat library supports Long %File Names or short 8.3 names. +Edit the SdFatConfig.h file to select short or long file names. + +The main classes in %SdFat are SdFat, SdFatEX, SdFatSoftSpi, SdFatSoftSpiEX, +SdBaseFile, SdFile, File, StdioStream, \ref fstream, \ref ifstream, +and \ref ofstream. + +The SdFat, SdFatEX, SdFatSoftSpi and SdFatSoftSpiEX classes maintain a +FAT volume, a current working directory, and simplify initialization +of other classes. The SdFat and SdFatEX classes uses a fast custom hardware SPI +implementation. The SdFatSoftSpi and SdFatSoftSpiEX classes uses software SPI. + +the SdFatEX and SdFatSoftSpiEX use extended multi-block I/O for enhanced +performance. These classes must have exclusive use of the SPI bus. + +The SdBaseFile class provides basic file access functions such as open(), +binary read(), binary write(), close(), remove(), and sync(). SdBaseFile +is the smallest file class. + +The SdFile class has all the SdBaseFile class functions plus the Arduino +Print class functions. + +The File class has all the SdBaseFile functions plus the functions in +the Arduino SD.h File class. This provides compatibility with the +Arduino SD.h library. + +The StdioStream class implements functions similar to Linux/Unix standard +buffered input/output. + +The \ref fstream class implements C++ iostreams for both reading and writing +text files. + +The \ref ifstream class implements C++ iostreams for reading text files. + +The \ref ofstream class implements C++ iostreams for writing text files. + +The classes \ref ifstream, \ref ofstream, \ref istream, and \ref ostream +follow the C++ \ref iostream standard when possible. + +There are many tutorials and much documentation about using C++ iostreams +on the web. + +http://www.cplusplus.com/ is a good C++ site for learning iostreams. + +The classes \ref ibufstream and \ref obufstream format and parse character + strings in memory buffers. + +the classes ArduinoInStream and ArduinoOutStream provide iostream functions +for Serial, LiquidCrystal, and other devices. + +A number of example are provided in the %SdFat/examples folder. These were +developed to test %SdFat and illustrate its use. + +\section Install Installation + +You must manually install SdFat by copying the SdFat folder from the download +package to the Arduino libraries folder in your sketch folder. + +See the Manual installation section of this guide. + +http://arduino.cc/en/Guide/Libraries + +\section SDconfig SdFat Configuration + +Several configuration options may be changed by editing the SdFatConfig.h +file in the %SdFat folder. + +Set USE_LONG_FILE_NAMES nonzero to enable Long %File Names. By default, +Long %File Names are enabled. For the leanest fastest library disable +Long %File Names. Long %File names require extra flash but no extra RAM. +Opening Long %File Names can be slower than opening Short %File Names. +Data read and write performance is not changed by the type of %File Name. + +If the symbol ENABLE_EXTENDED_TRANSFER_CLASS is nonzero, the class SdFatEX +will be defined. If the symbol ENABLE_SOFTWARE_SPI_CLASS is also nonzero, +the class SdFatSoftSpiEX will be defined. +These classes used extended multi-block SD I/O for better performance. +the SPI bus may not be shared with other devices in this mode. + +Set USE_STANDARD_SPI_LIBRARY and ENABLE_SOFTWARE_SPI_CLASS to +enable various SPI options. set USE_STANDARD_SPI_LIBRARY to use the standard +Arduino SPI library. set ENABLE_SOFTWARE_SPI_CLASS to enable the SdFatSoftSpi +class which uses software SPI. + +To enable SD card CRC checking set USE_SD_CRC nonzero. + +Set FAT12_SUPPORT nonzero to enable use of FAT12 volumes. +FAT12 has not been well tested and requires additional flash. + +\section SDPath Paths and Working Directories + +Relative paths in SdFat are resolved in a manner similar to Windows. + +Each instance of SdFat has a current directory. In SdFat this directory +is called the volume working directory, vwd. Initially this directory is +the root directory for the volume. + +The volume working directory is changed by calling SdFat::chdir(path). + +The call sd.chdir("/2014") will change the volume working directory +for sd to "/2014", assuming "/2014" exists. + +Relative paths for SdFat member functions are resolved by starting at +the volume working directory. + +For example, the call sd.mkdir("April") will create the directory +"/2014/April" assuming the volume working directory is "/2014". + +SdFat has a current working directory, cwd, that is used to resolve paths +for file.open() calls. + +For a single SD card the current working directory is always the volume +working directory for that card. + +For multiple SD cards the current working directory is set to the volume +working directory of a card by calling the SdFat::chvol() member function. +The chvol() call is like the Windows \: command. + +The call sd2.chvol() will set the current working directory to the volume +working directory for sd2. + +If the volume working directory for sd2 is "/music" the call + +file.open("BigBand.wav", O_READ); + +will then open "/music/BigBand.wav" on sd2. + +The following functions are used to change or get current directories. +See the html documentation for more information. +@code +bool SdFat::chdir(bool set_cwd = false); +bool SdFat::chdir(const char* path, bool set_cwd = false); +void SdFat::chvol(); +SdBaseFile* SdFat::vwd(); +static SdBaseFile* SdBaseFile::cwd(); +@endcode + +\section SDcard SD\SDHC Cards + +Arduinos access SD cards using the cards SPI protocol. PCs, Macs, and +most consumer devices use the 4-bit parallel SD protocol. A card that +functions well on A PC or Mac may not work well on the Arduino. + +Most cards have good SPI read performance but cards vary widely in SPI +write performance. Write performance is limited by how efficiently the +card manages internal erase/remapping operations. The Arduino cannot +optimize writes to reduce erase operations because of its limit RAM. + +SanDisk cards generally have good write performance. They seem to have +more internal RAM buffering than other cards and therefore can limit +the number of flash erase operations that the Arduino forces due to its +limited RAM. + +\section Hardware Hardware Configuration + +%SdFat was developed using an +
Adafruit Industries +Data Logging Shield. + +The hardware interface to the SD card should not use a resistor based level +shifter. %SdFat sets the SPI bus frequency to 8 MHz which results in signal +rise times that are too slow for the edge detectors in many newer SD card +controllers when resistor voltage dividers are used. + +The 5 to 3.3 V level shifter for 5 V Arduinos should be IC based like the +74HC4050N based circuit shown in the file SdLevel.png. The Adafruit Wave Shield +uses a 74AHC125N. Gravitech sells SD and MicroSD Card Adapters based on the +74LCX245. + +If you are using a resistor based level shifter and are having problems try +setting the SPI bus frequency to 4 MHz. This can be done by using +card.init(SPI_HALF_SPEED) to initialize the SD card. + +A feature to use software SPI is available. Software SPI is slower +than hardware SPI but allows any digital pins to be used. See +SdFatConfig.h for software SPI definitions. + +\section comment Bugs and Comments + +If you wish to report bugs or have comments, send email to +fat16lib@sbcglobal.net. If possible, include a simple program that illustrates +the bug or problem. + +\section Trouble Troubleshooting + +The two example programs QuickStart, and SdInfo are useful for troubleshooting. + +A message like this from SdInfo with erorCode 0X1 indicates the SD card +is not seen by SdFat. This is often caused by a wiring error and reformatting +the card will not solve the problem. +
+cardBegin failed
+SD errorCode: 0X1
+SD errorData: 0XFF
+
+Here is a similar message from QuickStart: +
+SD initialization failed.
+Do not reformat the card!
+Is the card correctly inserted?
+Is chipSelect set to the correct value?
+Does another SPI device need to be disabled?
+Is there a wiring/soldering problem?
+
+errorCode: 0x1, errorData: 0xff
+
+Here is a message from QuickStart that indicates a formatting problem: +
+Card successfully initialized.
+Can't find a valid FAT16/FAT32 partition.
+Try reformatting the card.  For best results use
+the SdFormatter program in SdFat/examples or download
+and use SDFormatter from www.sdcard.org/downloads.
+
+ +The best source of recent information and help is the Arduino forum. + +http://arduino.cc/forum/ + +Also search the Adafruit forum. + +http://forums.adafruit.com/ + +If you are using a Teensy try. + +http://forum.pjrc.com/forum.php + +\section SdFatClass SdFat Usage + +SdFat supports Long File Names. Long names in SdFat are limited to 7-bit +ASCII characters in the range 0X20 - 0XFE The following are reserved characters: +
    +
  • < (less than) +
  • > (greater than) +
  • : (colon) +
  • " (double quote) +
  • / (forward slash) +
  • \ (backslash) +
  • | (vertical bar or pipe) +
  • ? (question mark) +
  • * (asterisk) +
+%SdFat uses a slightly restricted form of short names. +Short names are limited to 8 characters followed by an optional period (.) +and extension of up to 3 characters. The characters may be any combination +of letters and digits. The following special characters are also allowed: + +$ % ' - _ @ ~ ` ! ( ) { } ^ # & + +Short names are always converted to upper case and their original case +value is lost. Files that have a base-name where all characters have the +same case and an extension where all characters have the same case will +display properly. Examples this type name are UPPER.low, lower.TXT, +UPPER.TXT, and lower.txt. + +An application which writes to a file using print(), println() or +write() must close the file or call sync() at the appropriate time to +force data and directory information to be written to the SD Card. + +Applications must use care calling sync() sync() +since 2048 bytes of I/O is required to update file and +directory information. This includes writing the current data block, reading +the block that contains the directory entry for update, writing the directory +block back and reading back the current data block. + +It is possible to open a file with two or more instances of a file object. +A file may be corrupted if data is written to the file by more than one +instance of a file object. + +\section HowTo How to format SD Cards as FAT Volumes + +The best way to restore an SD card's format on a PC or Mac is to use +SDFormatter which can be downloaded from: + +http://www.sdcard.org/downloads + +A formatter program, SdFormatter.ino, is included in the +%SdFat/examples/SdFormatter directory. This program attempts to +emulate SD Association's SDFormatter. + +SDFormatter aligns flash erase boundaries with file +system structures which reduces write latency and file system overhead. + +The PC/Mac SDFormatter does not have an option for FAT type so it may format +very small cards as FAT12. Use the SdFat formatter to force FAT16 +formatting of small cards. + +Do not format the SD card with an OS utility, OS utilities do not format SD +cards in conformance with the SD standard. + +You should use a freshly formatted SD card for best performance. FAT +file systems become slower if many files have been created and deleted. +This is because the directory entry for a deleted file is marked as deleted, +but is not deleted. When a new file is created, these entries must be scanned +before creating the file. Also files can become +fragmented which causes reads and writes to be slower. + +\section ExampleFilder Examples + +A number of examples are provided in the SdFat/examples folder. +See the html documentation for a list. + +To access these examples from the Arduino development environment +go to: %File -> Examples -> %SdFat -> \ + +Compile, upload to your Arduino and click on Serial Monitor to run +the example. + +Here is a list: + +AnalogBinLogger - Fast AVR ADC logger - see the AnalogBinLoggerExtras folder. + +bench - A read/write benchmark. + +dataLogger - A simple modifiable data logger. + +DirectoryFunctions - Demo of chdir(), ls(), mkdir(), and rmdir(). + +fgets - Demo of the fgets read line/string function. + +formating - Print a table with various formatting options. + +getline - Example of getline from section 27.7.1.3 of the C++ standard. + +LongFileName - Example use of openNext, printName, and open by index. + +LowLatencyLogger - A data logger for higher data rates. ADC version. + +LowLatencyLoggerADXL345 - A data logger for higher data rates. ADXL345 SPI. + +LowLatencyLoggerMPU6050 - A data logger for higher data rates. MPU6050 I2C. + +OpenNext - Open all files in the root dir and print their filename. + +PrintBenchmark - A simple benchmark for printing to a text file. + +QuickStart - A program to quickly test your SD card and SD shield/module. + +RawWrite - A test of raw write functions for contiguous files. + +ReadCsv - Function to read a CSV text file one field at a time. + +ReadCsvStream - Read a comma-separated value file using iostream extractors. + +ReadCsvArray - Read a two dimensional array from a CSV file. + +ReadWrite - Compatibility test of Arduino SD ReadWrite example. + +rename - A demo of SdFat::rename(old, new) and SdFile::rename(dirFile, newPath). + +SdFormatter - This program will format an SD or SDHC card. + +SoftwareSpi - Simple demonstration of the SdFatSoftSpi template class. + +SdInfo - Initialize an SD card and analyze its structure for trouble shooting. + +StdioBench - Demo and test of stdio style stream. + +Timestamp - Sets file create, modify, and access timestamps. + +TwoCards - Example using two SD cards. + +VolumeFreeSpace - Demonstrate the freeClusterCount() call. + +wipe - Example to wipe all data from an already formatted SD. + */ diff --git a/libraries/SdFat/extras/SdFat.html b/libraries/SdFat/extras/SdFat.html new file mode 100644 index 0000000..a01f20b --- /dev/null +++ b/libraries/SdFat/extras/SdFat.html @@ -0,0 +1,10 @@ + + +A web page that points a browser to a different page + + + + +Your browser didn't automatically redirect. Open html/index.html manually. + + diff --git a/libraries/SdFat/extras/SdFatTestSuite/SdFatTestSuite.cpp b/libraries/SdFat/extras/SdFatTestSuite/SdFatTestSuite.cpp new file mode 100644 index 0000000..396bf49 --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/SdFatTestSuite.cpp @@ -0,0 +1,82 @@ +/* Arduino SdFat Library + * Copyright (C) 2011 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 + * . + */ +#include +static uint16_t failCount; +static uint16_t testCount; +static Print* testOut = &Serial; +//------------------------------------------------------------------------------ +static size_t strlenPGM(PGM_P str) { + PGM_P end = str; + while (pgm_read_byte(end++)) {} + return end - str; +} +//------------------------------------------------------------------------------ +void testBegin() { + Serial.begin(9600); + while (!Serial) {} // wait for leonardo + testOut = &Serial; + Serial.println(F("Type any character to begin.")); + while (Serial.read() <= 0) {} + delay(200); // Catch Due reset problem + + testOut->print(F("FreeRam: ")); + testOut->println(FreeRam()); + testOut->println(); + failCount = 0; + testCount = 0; +} +//------------------------------------------------------------------------------ +void testEnd() { + testOut->println(); + testOut->println(F("Compiled: " __DATE__ " " __TIME__)); + testOut->print(F("FreeRam: ")); + testOut->println(FreeRam()); + testOut->print(F("Test count: ")); + testOut->println(testCount); + testOut->print(F("Fail count: ")); + testOut->println(failCount); +} +//------------------------------------------------------------------------------ +static void testResult(bool b, uint8_t n) { + while (n++ < 60) testOut->write(' '); + if (b) { + testOut->println(F("..ok")); + } else { + testOut->println(F("FAIL")); + failCount++; + } + testCount++; +} +//------------------------------------------------------------------------------ +void testVerify_P(char* result, PGM_P expect) { + testOut->write('"'); + testOut->print(result); + testOut->print("\",\""); + testOut->print((const __FlashStringHelper*)expect); + testOut->write('"'); + uint8_t n = strlen(result) + strlenPGM(expect) + 5; + testResult(!strcmp_P(result, expect), n); +} +//------------------------------------------------------------------------------ +void testVerify_P(bool b, PGM_P msg) { + testOut->print((const __FlashStringHelper*)msg); + uint8_t n = strlenPGM(msg); + testResult(b, n); +} diff --git a/libraries/SdFat/extras/SdFatTestSuite/SdFatTestSuite.h b/libraries/SdFat/extras/SdFatTestSuite/SdFatTestSuite.h new file mode 100644 index 0000000..736f67f --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/SdFatTestSuite.h @@ -0,0 +1,45 @@ +/* Arduino SdFat Library + * Copyright (C) 2011 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 SdFatTestSuite_h +#define SdFatTestSuite_h +#include +#include + +#if defined(__arm__) && !defined(strcmp_P) +#define strcmp_P(a, b) strcmp((a), (b)) +#endif // strcmp_P + +#if defined(__arm__) && !defined(strncpy_P) +#define strncpy_P(s, t, n) strncpy(s, t, n) +#endif // strncpy_P + +#if defined(__arm__) && !defined(strlen_P) +#define strlen_P(str) strlen(str) +#endif // strlen_P + +#define testVerifyBool(result) testVerify_P(result, PSTR(#result)) +#define testVerifyMsg(result, msg) testVerify_P(result, PSTR(msg)) +#define testVerifyStr(result, expect) testVerify_P(result, PSTR(expect)) + +void testBegin(); +void testEnd(); +void testVerify_P(bool b, PGM_P msg); +void testVerify_P(char* result, PGM_P expect); +#endif // SdFatTestSuite_h diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/ATS_SD_File/ATS_SD_File.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/ATS_SD_File/ATS_SD_File.ino new file mode 100644 index 0000000..822534f --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/ATS_SD_File/ATS_SD_File.ino @@ -0,0 +1,105 @@ +// modified from ArduinoTestSuite 0022 by William Greiman +// Tests writing to and reading from a file, in particular the +// the Stream implementation (e.g. read() and peek()). + +#include +#include +#include +SdFat SD; +#define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) +void setup() { + boolean b; + SdFile f; + uint32_t fs; + + testBegin(); + + ATS_PrintTestStatus("SD.begin()", b = SD.begin()); + if (!b) goto done; + + SD.remove("test.txt"); + + f.open("test.txt", FILE_WRITE); + ATS_PrintTestStatus("SD.open()", f.isOpen()); + if (!f.isOpen()) goto done; + + f.print("abc"); + f.print("de"); + f.close(); + + f.open("test.txt", FILE_WRITE); + ATS_PrintTestStatus("SD.open()", f.isOpen()); + if (!f.isOpen()) goto done; + + f.print("fgh"); + f.close(); + + f.open("test.txt", O_READ); + ATS_PrintTestStatus("SD.open()", f.isOpen()); + if (!f.isOpen()) goto done; + fs =f.fileSize(); + ATS_PrintTestStatus("read()", f.read() == 'a'); + ATS_PrintTestStatus("peek()", f.peek() == 'b'); + ATS_PrintTestStatus("read()", f.read() == 'b'); + ATS_PrintTestStatus("read()", f.read() == 'c'); + ATS_PrintTestStatus("peek()", f.peek() == 'd'); + ATS_PrintTestStatus("peek()", f.peek() == 'd'); + ATS_PrintTestStatus("peek()", f.peek() == 'd'); + ATS_PrintTestStatus("peek()", f.peek() == 'd'); + ATS_PrintTestStatus("read()", f.read() == 'd'); + ATS_PrintTestStatus("available()", f.curPosition() != fs); + ATS_PrintTestStatus("read()", f.read() == 'e'); + ATS_PrintTestStatus("available()", f.curPosition() != fs); + ATS_PrintTestStatus("peek()", f.peek() == 'f'); + ATS_PrintTestStatus("read()", f.read() == 'f'); + ATS_PrintTestStatus("peek()", f.peek() == 'g'); + ATS_PrintTestStatus("available()", f.curPosition() != fs); + ATS_PrintTestStatus("peek()", f.peek() == 'g'); + ATS_PrintTestStatus("read()", f.read() == 'g'); + ATS_PrintTestStatus("available()", f.curPosition() != fs); + ATS_PrintTestStatus("available()", f.curPosition() != fs); + ATS_PrintTestStatus("available()", f.curPosition() != fs); + ATS_PrintTestStatus("peek()", f.peek() == 'h'); + ATS_PrintTestStatus("read()", f.read() == 'h'); + ATS_PrintTestStatus("available()", f.curPosition() == fs); + ATS_PrintTestStatus("peek()", f.peek() == -1); + ATS_PrintTestStatus("read()", f.read() == -1); + ATS_PrintTestStatus("peek()", f.peek() == -1); + ATS_PrintTestStatus("read()", f.read() == -1); + + f.close(); + + SD.remove("test2.txt"); + + f.open("test2.txt", FILE_WRITE); + ATS_PrintTestStatus("SD.open()", f.isOpen()); + if (!f.isOpen()) goto done; + + f.print("ABC"); + f.close(); + + f.open("test.txt", O_READ); + ATS_PrintTestStatus("SD.open()", f.isOpen()); + if (!f.isOpen()) goto done; + + ATS_PrintTestStatus("peek()", f.peek() == 'a'); + + f.close(); + + f.open("test2.txt", O_READ); + ATS_PrintTestStatus("SD.open()", f.isOpen()); + if (!f.isOpen()) goto done; + + ATS_PrintTestStatus("peek()", f.peek() == 'A'); + ATS_PrintTestStatus("read()", f.read() == 'A'); + + f.close(); + +done: + testEnd(); + +} + +void loop() {} + + diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/ATS_SD_Files/ATS_SD_Files.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/ATS_SD_Files/ATS_SD_Files.ino new file mode 100644 index 0000000..6bb2c81 --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/ATS_SD_Files/ATS_SD_Files.ino @@ -0,0 +1,75 @@ +// modified from ArduinoTestSuite 0022 by William Greiman +#include +#include +#include +SdFat SD; +#define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) + +void setup() { + boolean b; + SdFile f; + + testBegin(); + + ATS_PrintTestStatus("SD.begin()", b = SD.begin()); + if (!b) goto done; + + ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf.txt")); + ATS_PrintTestStatus("SD.open()", f.open("asdf.txt", FILE_WRITE)); f.close(); + ATS_PrintTestStatus("SD.exists()", SD.exists("asdf.txt")); + ATS_PrintTestStatus("SD.exists()", SD.exists("/asdf.txt")); + ATS_PrintTestStatus("SD.remove()", SD.remove("asdf.txt")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf.txt")); + + ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf")); + ATS_PrintTestStatus("SD.mkdir()", SD.mkdir("asdf")); + ATS_PrintTestStatus("SD.exists()", SD.exists("asdf")); + ATS_PrintTestStatus("SD.exists()", SD.exists("/asdf")); + ATS_PrintTestStatus("SD.exists()", SD.exists("asdf/")); + ATS_PrintTestStatus("SD.rmdir()", SD.rmdir("asdf")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf")); + + ATS_PrintTestStatus("SD.mkdir()", SD.mkdir("x/y/z")); + ATS_PrintTestStatus("SD.exists()", SD.exists("x")); + ATS_PrintTestStatus("SD.exists()", SD.exists("x/")); + ATS_PrintTestStatus("SD.exists()", SD.exists("x/y")); + ATS_PrintTestStatus("SD.exists()", SD.exists("x/y/")); + ATS_PrintTestStatus("SD.exists()", SD.exists("x/y/z")); + ATS_PrintTestStatus("SD.exists()", SD.exists("x/y/z/")); + ATS_PrintTestStatus("SD.exists()", SD.exists("/x/y/z/")); + ATS_PrintTestStatus("SD.rmdir()", SD.rmdir("x/y/z")); + ATS_PrintTestStatus("SD.exists()", SD.exists("x")); + ATS_PrintTestStatus("SD.exists()", SD.exists("x/y")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("x/y/z")); + ATS_PrintTestStatus("SD.rmdir()", SD.rmdir("x/y/")); + ATS_PrintTestStatus("SD.exists()", SD.exists("x")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("x/y")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("x/y/z")); + ATS_PrintTestStatus("SD.rmdir()", SD.rmdir("/x")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("x")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("x/y")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("x/y/z")); + + ATS_PrintTestStatus("!SD.open()", !(f.open("asdf/asdf.txt", FILE_WRITE))); f.close(); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf.txt")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf/asdf.txt")); + ATS_PrintTestStatus("SD.mkdir()", SD.mkdir("asdf")); + ATS_PrintTestStatus("SD.exists()", SD.exists("asdf")); + ATS_PrintTestStatus("SD.open()", f.open("asdf/asdf.txt", FILE_WRITE)); f.close(); + ATS_PrintTestStatus("SD.exists()", SD.exists("asdf/asdf.txt")); + ATS_PrintTestStatus("!SD.rmdir()", !SD.rmdir("asdf")); + ATS_PrintTestStatus("SD.exists()", SD.exists("asdf")); + ATS_PrintTestStatus("SD.exists()", SD.exists("asdf/asdf.txt")); + ATS_PrintTestStatus("SD.remove()", SD.remove("asdf/asdf.txt")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf/asdf.txt")); + ATS_PrintTestStatus("SD.exists()", SD.exists("asdf")); + ATS_PrintTestStatus("SD.rmdir()", SD.rmdir("asdf")); + ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf")); + +done: + + testEnd(); + +} +void loop() {} diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/ATS_SD_Seek/ATS_SD_Seek.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/ATS_SD_Seek/ATS_SD_Seek.ino new file mode 100644 index 0000000..81e1d73 --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/ATS_SD_Seek/ATS_SD_Seek.ino @@ -0,0 +1,108 @@ +// modified from ArduinoTestSuite 0022 by William Greiman +// Tests writing to and reading from a file, in particular the +// the Stream implementation (e.g. read() and peek()). +#include +#include +#include +SdFat SD; +#define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) + +void setup() { + boolean b; + SdFile f; + + testBegin(); + + ATS_PrintTestStatus("SD.begin()", b = SD.begin()); + if (!b) goto done; + + SD.remove("test.txt"); + + f.open("test.txt", FILE_WRITE); + ATS_PrintTestStatus("SD.open()", f.isOpen()); + if (!f.isOpen()) goto done; + + ATS_PrintTestStatus("initial position", f.curPosition() == 0); + ATS_PrintTestStatus("initial size", f.fileSize() == 0); + + f.print("0123456789"); + + ATS_PrintTestStatus("position after writing", f.curPosition() == 10); + ATS_PrintTestStatus("size after writing", f.fileSize() == 10); + + f.seekSet(0); + + ATS_PrintTestStatus("size after seek", f.fileSize() == 10); + ATS_PrintTestStatus("position after seek", f.curPosition() == 0); + + f.seekSet(7); + + ATS_PrintTestStatus("position after seek", f.curPosition() == 7); + ATS_PrintTestStatus("reading after seek", f.read() == '7'); + ATS_PrintTestStatus("position after reading after seeking", f.curPosition() == 8); + ATS_PrintTestStatus("reading after reading after seeking", f.read() == '8'); + + f.seekSet(3); + + ATS_PrintTestStatus("position after seeking", f.curPosition() == 3); + ATS_PrintTestStatus("peeking after seeking", f.peek() == '3'); + ATS_PrintTestStatus("position after peeking after seeking", f.curPosition() == 3); + ATS_PrintTestStatus("peeking after peeking after seeking", f.peek() == '3'); + ATS_PrintTestStatus("position after peeking after seeking", f.curPosition() == 3); + ATS_PrintTestStatus("peeking after peeking after seeking", f.read() == '3'); + ATS_PrintTestStatus("position after peeking after seeking", f.curPosition() == 4); + + f.seekSet(1); + + ATS_PrintTestStatus("position after seeking", f.curPosition() == 1); + ATS_PrintTestStatus("peeking after seeking", f.peek() == '1'); + + f.seekSet(4); + + ATS_PrintTestStatus("position after seeking", f.curPosition() == 4); + ATS_PrintTestStatus("peeking after seeking", f.peek() == '4'); + + f.seekSet(7); + + ATS_PrintTestStatus("position()", f.curPosition() == 7); + ATS_PrintTestStatus("read()", f.read() == '7'); + + f.seekSet(0); + f.peek(); + f.print("AB"); + + ATS_PrintTestStatus("position()", f.curPosition() == 2); + ATS_PrintTestStatus("size()", f.fileSize() == 10); + ATS_PrintTestStatus("read()", f.read() == '2'); + + f.seekSet(0); + + ATS_PrintTestStatus("read()", f.read() == 'A'); + ATS_PrintTestStatus("read()", f.read() == 'B'); + ATS_PrintTestStatus("read()", f.read() == '2'); + + f.close(); + + f.open("test.txt", O_READ); + ATS_PrintTestStatus("SD.open()", f.isOpen()); + if (!f.isOpen()) goto done; + + ATS_PrintTestStatus("position()", f.curPosition() == 0); + ATS_PrintTestStatus("size()", f.fileSize() == 10); + ATS_PrintTestStatus("peek()", f.peek() == 'A'); + ATS_PrintTestStatus("read()", f.read() == 'A'); + + f.seekSet(4); + + ATS_PrintTestStatus("position()", f.curPosition() == 4); + ATS_PrintTestStatus("size()", f.fileSize() == 10); + ATS_PrintTestStatus("peek()", f.peek() == '4'); + ATS_PrintTestStatus("read()", f.read() == '4'); + + f.close(); + +done: + testEnd(); +} + +void loop() {} \ No newline at end of file diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/StressTest/StressTest.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/StressTest/StressTest.ino new file mode 100644 index 0000000..11fb804 --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/StressTest/StressTest.ino @@ -0,0 +1,76 @@ +// This stress test will create and write files until the SD is full. +#include +#include + +// SD chip select pin. +const uint8_t SD_CS_PIN = SS; + +// Set write buffer size. +#ifdef __arm__ +#ifndef CORE_TEENSY +// Due +const size_t BUF_SIZE = 32768; +#else // CORE_TEENSY +// Teensy 3.0 +const size_t BUF_SIZE = 8192; +#endif // CORE_TEENSY +#elif defined(RAMEND) && RAMEND > 5000 +// AVR with more than 4 KB RAM +const size_t BUF_SIZE = 4096; +#else // __arm__ +// other +const size_t BUF_SIZE = 512; +#endif // __arm__ + +const size_t FILE_SIZE_KB = 10240; +const uint16_t BUFS_PER_FILE = (1024L*FILE_SIZE_KB/BUF_SIZE); + +SdFat sd; + +SdFile file; + +uint8_t buf[BUF_SIZE]; +char name[13]; +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + Serial.print("BUF_SIZE "); + Serial.println(BUF_SIZE); + Serial.println("Type any character to start"); + while (Serial.read() < 0) {} + + if (!sd.begin(SD_CS_PIN))sd.errorHalt("sd.begin"); + + // Fill buf with known value. + for (size_t i = 0; i < BUF_SIZE; i++) buf[i] = i; + + // Wait to begin. + do {delay(10);} while (Serial.read() >= 0); + Serial.println("Type any character to stop after next file"); +} +//------------------------------------------------------------------------------ +void loop() { + // Free KB on SD. + uint32_t freeKB = sd.vol()->freeClusterCount()*sd.vol()->blocksPerCluster()/2; + + Serial.print("Free KB: "); + Serial.println(freeKB); + if (freeKB < 2*FILE_SIZE_KB) { + Serial.println(" Done!"); + while(1); + } + sprintf(name, "%lu.DAT", freeKB); + if (!file.open(name, O_WRITE | O_CREAT | O_TRUNC)) { + sd.errorHalt("Open error!"); + } + for (uint16_t i = 0; i < BUFS_PER_FILE; i++) { + if (file.write(buf, BUF_SIZE) != BUF_SIZE) { + sd.errorHalt("Write error!"); + } + } + file.close(); + if (Serial.available()) { + Serial.println("Stopped!"); + while(1); + } +} \ No newline at end of file diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/TestMkdir/TestMkdir.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/TestMkdir/TestMkdir.ino new file mode 100644 index 0000000..458de9f --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/TestMkdir/TestMkdir.ino @@ -0,0 +1,138 @@ +/* + * This sketch is a test of subdirectory and file creation. + * It also tests allocation of clusters to directories. + * + * It will create two subdirectories and create enough files + * to force the allocation of a cluster to each directory. + * + * More than 3000 files may be created on a FAT32 volume. + * + * Note: Some cards may 'stutter' others just get slow due + * to the number of flash erases this program causes. + */ +#include +#include +#include + +const uint8_t SD_CHIP_SELECT = SS; + +SdFat sd; + +// store error strings in flash to save RAM +#define error(s) sd.errorHalt(F(s)) + +/* + * create enough files to force a cluster to be allocated to dir. + */ +void dirAllocTest(FatFile* dir) { + char buf[32], name[32]; + SdFile file; + uint16_t n; + uint32_t size = dir->dirSize(); + + // create files and write name to file + for (n = 0; ; n++){ + // make file name + sprintf(name, "%u.TXT", n); + + // open start time + uint32_t t0 = millis(); + if (!file.open(dir, name, O_WRITE | O_CREAT | O_EXCL)) { + error("open for write failed"); + } + + // open end time and write start time + uint32_t t1 = millis(); + // write file name to file + file.print(name); + if (!file.close()) error("close write"); + + // write end time + uint32_t t2 = millis(); + Serial.print(F("WR ")); + Serial.print(n); + Serial.write(' '); + + // print time to create file + Serial.print(t1 - t0); + Serial.write(' '); + + // print time to write file + Serial.println(t2 - t1); + + // directory size will change when a cluster is added + if (dir->curPosition() > size) break; + } + + // read files and check content + for (uint16_t i = 0; i <= n; i++) { + sprintf(name, "%u.TXT", i); + + // open start time + uint32_t t0 = millis(); + if (!file.open(dir, name, O_READ)) { + error("open for read failed"); + } + + // open end time and read start time + uint32_t t1 = millis(); + int16_t nr = file.read(buf, sizeof(buf)); + if (nr < 5) error("file.read failed"); + + // read end time + uint32_t t2 = millis(); + + // check file content + if (strlen(name) != (size_t)nr || strncmp(name, buf, nr)) { + error("content compare failed"); + } + if (!file.close()) error("close read failed"); + + Serial.print(F("RD ")); + Serial.print(i); + Serial.write(' '); + + // print open time + Serial.print(t1 - t0); + Serial.write(' '); + + // print read time + Serial.println(t2 - t1); + } +} + +void setup() { + Serial.begin(9600); + while (!Serial) {} // wait for Leonardo + Serial.println(F("Type any character to start")); + while (Serial.read() <= 0) {} + delay(200); // Catch Due reset problem + + // initialize the SD card at SPI_FULL_SPEED for best performance. + // try SPI_HALF_SPEED if bus errors occur. + if (!sd.begin(SD_CHIP_SELECT, SPI_FULL_SPEED)) sd.initErrorHalt(); + + uint32_t m = millis(); + // write files to root if FAT32 + if (sd.vol()->fatType() == 32) { + Serial.println(F("Writing files to root")); + dirAllocTest(sd.vwd()); + } + + // create sub1 and write files + SdFile sub1; + if (!sub1.mkdir(sd.vwd(), "SUB1")) error("makdeDir SUB1 failed"); + Serial.println(F("Writing files to SUB1")); + dirAllocTest(&sub1); + + // create sub2 and write files + SdFile sub2; + if (!sub2.mkdir(&sub1, "SUB2")) error("mkdir SUB2 failed"); + Serial.println(F("Writing files to SUB2")); + dirAllocTest(&sub2); + m = millis() - m; + Serial.print(F("Done millis: ")); + Serial.println(m); +} + +void loop() { } \ No newline at end of file diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/TestRmdir/TestRmdir.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/TestRmdir/TestRmdir.ino new file mode 100644 index 0000000..013e921 --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/TestRmdir/TestRmdir.ino @@ -0,0 +1,98 @@ +/* + * This sketch will remove the files and directories + * created by the SdFatMakeDir.pde sketch. + * + * Performance is erratic due to the large number + * of flash erase operations caused by many random + * writes to file structures. + */ +#include +#include +#include + +const uint8_t SD_CHIP_SELECT = SS; + +SdFat sd; + +// store error strings in flash to save RAM +#define error(s) sd.errorHalt(F(s)) + +/* + * remove all files in dir. + */ +void deleteFiles(FatFile* dir) { + char name[32]; + SdFile file; + + // open and delete files + for (uint16_t n = 0; ; n++){ + sprintf(name, "%u.TXT", n); + + // open start time + uint32_t t0 = millis(); + + // assume done if open fails + if (!file.open(dir, name, O_WRITE)) return; + + // open end time and remove start time + uint32_t t1 = millis(); + if (!file.remove()) error("file.remove failed"); + + // remove end time + uint32_t t2 = millis(); + + Serial.print(F("RM ")); + Serial.print(n); + Serial.write(' '); + + // open time + Serial.print(t1 - t0); + Serial.write(' '); + + // remove time + Serial.println(t2 - t1); + } +} + +void setup() { + Serial.begin(9600); + while (!Serial) {} // wait for Leonardo + Serial.println(F("Type any character to start")); + while (Serial.read() <= 0) {} + delay(200); // Catch Due reset problem + + // initialize the SD card at SPI_FULL_SPEED for best performance. + // try SPI_HALF_SPEED if bus errors occur. + if (!sd.begin(SD_CHIP_SELECT, SPI_FULL_SPEED)) sd.initErrorHalt(); + + + // delete files in root if FAT32 + if (sd.vol()->fatType() == 32) { + Serial.println(F("Remove files in root")); + deleteFiles(sd.vwd()); + } + + // open SUB1 and delete files + SdFile sub1; + if (!sub1.open("SUB1", O_READ)) error("open SUB1 failed"); + Serial.println(F("Remove files in SUB1")); + deleteFiles(&sub1); + + // open SUB2 and delete files + SdFile sub2; + if (!sub2.open(&sub1, "SUB2", O_READ)) error("open SUB2 failed"); + Serial.println(F("Remove files in SUB2")); + deleteFiles(&sub2); + + // remove SUB2 + if (!sub2.rmdir()) error("sub2.rmdir failed"); + Serial.println(F("SUB2 removed")); + + // remove SUB1 + if (!sub1.rmdir()) error("sub1.rmdir failed"); + Serial.println(F("SUB1 removed")); + + Serial.println(F("Done")); +} + +void loop() { } diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/fstreamTest/fstreamTest.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/fstreamTest/fstreamTest.ino new file mode 100644 index 0000000..83f2ce5 --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/fstreamTest/fstreamTest.ino @@ -0,0 +1,94 @@ +#include +#include +#include +SdFat sd; +const char *testName = "SDFAT.TST"; +//------------------------------------------------------------------------------ +void fstreamOpen() { + ios::openmode nocreate[] = {ios::in, ios::in | ios::out}; + ios::openmode create[] = + {ios::out, ios::out | ios::app, ios::app, ios::out | ios::trunc, + ios::in | ios::out | ios::trunc, ios::in | ios::out | ios::app, + ios::in | ios::app}; + ios::openmode illegal[] = + {0, ios::trunc, ios::app | ios::trunc, ios::in | ios::app | ios::trunc, + ios::in | ios::trunc, ios::out | ios::app | ios::trunc, + ios::in | ios::out | ios::app | ios::trunc}; + + sd.remove(testName); + fstream file(testName); + testVerifyMsg(!file.is_open()&& !sd.exists(testName), "fstream constructor"); + + for (uint8_t i = 0 ; i < sizeof(nocreate)/sizeof(nocreate[1]); i++) { + file.close(); + sd.remove(testName); + file.open(testName, nocreate[i]); + testVerifyMsg(!sd.exists(testName) && !file.is_open(), "fstream nocreate !exists"); + } + for (uint8_t i = 0 ; i < sizeof(create)/sizeof(create[1]); i++) { + file.close(); + sd.remove(testName); + file.open(testName, create[i]); + testVerifyMsg(sd.exists(testName) && file.is_open(), "fstream create openmode"); + } + for (uint8_t i = 0 ; i < sizeof(illegal)/sizeof(illegal[1]); i++) { + file.close(); + file.open(testName, illegal[i]); + testVerifyMsg(sd.exists(testName) && !file.is_open(), "fstream illegal openmode"); + } + for (uint8_t i = 0 ; i < sizeof(nocreate)/sizeof(nocreate[1]); i++) { + file.close(); + file.open(testName, nocreate[i]); + testVerifyMsg(sd.exists(testName) && file.is_open(), "fstream nocreate exists"); + } +} +//------------------------------------------------------------------------------ +void testPosition() { + sd.remove(testName); + ofstream ofs(testName); + testVerifyBool(ofs.good() && ofs.tellp() == 0); + ofs.seekp(0, ios::end); + testVerifyBool(ofs.good() && ofs.tellp() == 0); + ofs << "abcde"; + testVerifyBool(ofs.good() && ofs.tellp() == 5); + ofs.seekp(4); + testVerifyBool(ofs.good() && ofs.tellp() == 4); + ofs.seekp(-1, ios::cur); + testVerifyBool(ofs.good() && ofs.tellp() == 3); + ofs.close(); + ifstream ifs(testName, ios::ate); + testVerifyBool(ifs.good() && ifs.tellg() == 5); + ifs.seekg(0); + testVerifyBool(ifs.get() == 'a' && ifs.get() == 'b'); + testVerifyBool(ifs.tellg() == 2 && ifs.good()); + ifs.seekg(3, ios::cur); + testVerifyBool(ifs.tellg() == 5 && ifs.good()); + ifs.seekg(4, ios::beg); + testVerifyBool(ifs.good() && ifs.tellg() == 4); + ifs.close(); + ofs.open(testName, ios::app); + testVerifyBool(ofs.good() && ofs.tellp() == 0); + ofs << 'f'; + testVerifyBool(ofs.good() && ofs.tellp() == 6); + ofs.close(); + ofs.open(testName, ios::trunc); + ofs.seekp(0, ios::end); + testVerifyBool(ofs.good() && ofs.tellp() == 0); + ofs << "ABCDEF"; + ofs.close(); + fstream fs(testName); + testVerifyBool(fs.good() && fs.tellp() == 0 && fs.tellg() == 0); + fs.seekg(2); + testVerifyBool(fs.good() && fs.get() == 'C'); +} +//------------------------------------------------------------------------------ +void setup() { + + testBegin(); + if (!sd.begin()) sd.initErrorHalt(); + fstreamOpen(); + testPosition(); + testEnd(); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/istreamTest/istreamTest.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/istreamTest/istreamTest.ino new file mode 100644 index 0000000..3cf4d6d --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/istreamTest/istreamTest.ino @@ -0,0 +1,261 @@ +#include +#include +#include + +char buf[100]; +ibufstream ib; +#define ibInit(s) ibInit_P(PSTR(s)) + +//---------------------------------------------------------- +void ibInit_P(PGM_P p) { + if (strlen_P(p) >= sizeof(buf)) { + ib.init(""); + ib.setstate(ios::badbit); + } else { + ib.clear(); + strncpy_P(buf, p, sizeof(buf)); + ib.init(buf); + } +} +//------------------------------------------------------------------------------ +void istreamBool() { + bool b; + ibInit(" 0 1 2"); + testVerifyBool((ib >> b) && !b); + testVerifyBool((ib >> b) && b); + testVerifyBool(!(ib >> b) && !ib.good()); + + ibInit(" true false err"); + testVerifyBool((ib >> boolalpha >> b) && b && ib.good()); + testVerifyBool((ib >> b) && !b && ib.good()); + testVerifyBool(!(ib >> b) && ib.fail()); + + ibInit("1"); + testVerifyBool((ib >> noboolalpha >> b) && b && ib.eof()); +} +//------------------------------------------------------------------------------ +void istreamChar() { + char c; + signed char sc; + unsigned char uc; + + ibInit("c s u g"); + testVerifyBool((ib >> c) && ib.good() && c == 'c'); + testVerifyBool((ib >> sc) && ib.good() && sc == 's'); + testVerifyBool((ib >> uc) && ib.good() && uc == 'u'); + testVerifyBool(ib.get() == ' '); + testVerifyBool(ib.peek() == 'g' && ib.good()); + testVerifyBool(ib.get() == 'g' && ib.good()); + testVerifyBool(ib.get() == -1 && ib.eof()); +} +//------------------------------------------------------------------------------ +void istreamDouble() { + double f; + ibInit("0 .1 1. 2 3.4 .1e5 1e5 -1E6 +2.3e-3 -123.4567"); + testVerifyBool((ib >> f) && f == 0 && ib.good()); + testVerifyBool((ib >> f) && f == 0.1 && ib.good()); + testVerifyBool((ib >> f) && f == 1.0 && ib.good()); + testVerifyBool((ib >> f) && f == 2.0 && ib.good()); + testVerifyBool((ib >> f) && f == 3.4 && ib.good()); + testVerifyBool((ib >> f) && f == 10000.0 && ib.good()); + testVerifyBool((ib >> f) && f == 1e5 && ib.good()); + testVerifyBool((ib >> f) && f == -1E6 && ib.good()); + testVerifyBool((ib >> f) && f == 2.3e-3 && ib.good()); + testVerifyBool((ib >> f) && fabs(f + 123.4567) < 1e-5 && ib.eof()); + if (fabs(f + 123.4567) >= 1e-5) Serial.println(f, 8); +} +//------------------------------------------------------------------------------ +void istreamFloat() { + float f; + ibInit("0 .1 1. 2 3.4 .1e5 1e5 -1E6 +2.3e-3 -123.4567"); + testVerifyBool((ib >> f) && f == 0 && ib.good()); + testVerifyBool((ib >> f) && f == 0.1f && ib.good()); + testVerifyBool((ib >> f) && f == 1.0 && ib.good()); + testVerifyBool((ib >> f) && f == 2.0 && ib.good()); + testVerifyBool((ib >> f) && f == 3.4f && ib.good()); + testVerifyBool((ib >> f) && f == 10000.0 && ib.good()); + testVerifyBool((ib >> f) && f == 1e5 && ib.good()); + testVerifyBool((ib >> f) && f == -1E6 && ib.good()); + testVerifyBool((ib >> f) && f == 2.3e-3f && ib.good()); + testVerifyBool((ib >> f) && fabs(f + 123.4567f) < 1e-5 && ib.eof()); + if (fabs(f + 123.4567) >= 1e-5) Serial.println(f, 8); +} +//------------------------------------------------------------------------------ +void istreamGet() { + char s[4]; + ibInit("ab c"); + testVerifyBool(ib.get() == 'a' && ib.good() && ib.gcount() == 1); + testVerifyBool(ib.get() == 'b' && ib.good() && ib.gcount() == 1); + testVerifyBool(ib.get() == ' ' && ib.good() && ib.gcount() == 1); + testVerifyBool(ib.get() == 'c' && ib.good() && ib.gcount() == 1); + testVerifyBool(ib.get() == -1 && ib.eof() && ib.gcount() == 0); + + ibInit("ab\ncdef"); + ib.get(s, sizeof(s)); + testVerifyBool(ib.good() && ib.gcount() == 2); + testVerifyStr(s, "ab"); + testVerifyBool(ib.get() == '\n' && ib.good() && ib.gcount() == 1); + ib.get(s, sizeof(s)); + testVerifyBool(ib.good() && ib.gcount() == 3); + testVerifyStr(s, "cde"); + ib.get(s, sizeof(s)); + testVerifyBool(ib.eof() && ib.gcount() == 1); + testVerifyStr(s, "f"); + + ibInit( + "short line\n" + "\n" + "17 character line\n" + "too long for buffer\n" + "line with no nl" + ); + char buf[18]; + ib.getline(buf, sizeof(buf)); + testVerifyBool(ib.good() && ib.gcount() == 11); + testVerifyStr(buf, "short line"); + ib.getline(buf, sizeof(buf)); + testVerifyBool(ib.good() && ib.gcount() == 1 && buf[0] == '\0'); + ib.getline(buf, sizeof(buf)); + testVerifyBool(ib.good() && ib.gcount() == 18); + testVerifyStr(buf, "17 character line"); + ib.getline(buf, sizeof(buf)); + testVerifyBool(ib.fail() && !ib.eof() && ib.gcount() == 17); + testVerifyStr(buf, "too long for buff"); + ib.clear(); + ib.getline(buf, sizeof(buf)); + testVerifyBool(ib.good() && !ib.eof() && ib.gcount() == 3); + testVerifyStr(buf, "er"); + ib.getline(buf, sizeof(buf)); + testVerifyBool(!ib.fail() && ib.eof() && ib.gcount() == 15); + testVerifyStr(buf, "line with no nl"); +} +//------------------------------------------------------------------------------ +void istreamNumber() { + short s; + signed short ss; + unsigned short us; + int i; + signed int si; + unsigned int ui; + long l; + signed long sl; + unsigned long ul; + + ibInit("-32769"); + testVerifyBool(!(ib >> s) && ib.fail()); + ibInit("-32768 0 32767 32768"); + testVerifyBool((ib >> s) && s == -32768 && ib.good()); + testVerifyBool((ib >> s) && s == 0 && ib.good()); + testVerifyBool((ib >> s) && s == 32767 && ib.good()); + testVerifyBool(!(ib >> s) && ib.fail()); + + ibInit("-32769"); + testVerifyBool(!(ib >> ss) && ib.fail()); + ibInit("-32768 0 32767 32768"); + testVerifyBool((ib >> ss) && ss == -32768 && ib.good()); + testVerifyBool((ib >> ss) && ss == 0 && ib.good()); + testVerifyBool((ib >> ss) && ss == 32767 && ib.good()); + testVerifyBool(!(ib >> ss) && ib.fail()); + + ibInit("0 65535 65536"); + testVerifyBool((ib >> us) && us == 0 && ib.good()); + testVerifyBool((ib >> us) && us == 65535 && ib.good()); + testVerifyBool(!(ib >> us) && ib.fail()); + +if (sizeof(int) == 2) { + ibInit("-32769"); + testVerifyBool(!(ib >> i) && ib.fail()); + ibInit("-32768 0 32767 32768"); + testVerifyBool((ib >> i) && i == -32768 && ib.good()); + testVerifyBool((ib >> i) && i == 0 && ib.good()); + testVerifyBool((ib >> i) && i == 32767 && ib.good()); + testVerifyBool(!(ib >> i) && ib.fail()); + + ibInit("-32769"); + testVerifyBool(!(ib >> si) && ib.fail()); + ibInit("-32768 0 32767 32768"); + testVerifyBool((ib >> si) && si == -32768 && ib.good()); + testVerifyBool((ib >> si) && si == 0 && ib.good()); + testVerifyBool((ib >> si) && si == 32767 && ib.good()); + testVerifyBool(!(ib >> si) && ib.fail()); + + ibInit("0 65535 65536"); + testVerifyBool((ib >> ui) && ui == 0 && ib.good()); + testVerifyBool((ib >> ui) && ui == 65535 && ib.good()); + testVerifyBool(!(ib >> ui) && ib.fail()); + } else { + ibInit("-2147483649"); + testVerifyBool(!(ib >> i) && ib.fail()); + ibInit("-2147483648 0 2147483647 2147483648"); + testVerifyBool((ib >> i) && i == -2147483648 && ib.good()); + testVerifyBool((ib >> i) && i == 0 && ib.good()); + testVerifyBool((ib >> i) && i == 2147483647 && ib.good()); + testVerifyBool(!(ib >> i) && ib.fail()); + + ibInit("-2147483649"); + testVerifyBool(!(ib >> si) && ib.fail()); + ibInit("-2147483648 0 2147483647 2147483648"); + testVerifyBool((ib >> si) && si == -2147483648 && ib.good()); + testVerifyBool((ib >> si) && si == 0 && ib.good()); + testVerifyBool((ib >> si) && si == 2147483647 && ib.good()); + testVerifyBool(!(ib >> si) && ib.fail()); + + ibInit("0 4294967295 4294967296"); + testVerifyBool((ib >> ui) && ui == 0 && ib.good()); + testVerifyBool((ib >> ui) && ui == 4294967295 && ib.good()); + testVerifyBool(!(ib >> ui) && ib.fail()); + } + ibInit("-2147483649"); + testVerifyBool(!(ib >> l) && ib.fail()); + ibInit("-2147483648 0 2147483647 2147483648"); + testVerifyBool((ib >> l) && l == -2147483648 && ib.good()); + testVerifyBool((ib >> l) && l == 0 && ib.good()); + testVerifyBool((ib >> l) && l == 2147483647 && ib.good()); + testVerifyBool(!(ib >> l) && ib.fail()); + + ibInit("-2147483649"); + testVerifyBool(!(ib >> sl) && ib.fail()); + ibInit("-2147483648 0 2147483647 2147483648"); + testVerifyBool((ib >> sl) && sl == -2147483648 && ib.good()); + testVerifyBool((ib >> sl) && sl == 0 && ib.good()); + testVerifyBool((ib >> sl) && sl == 2147483647 && ib.good()); + testVerifyBool(!(ib >> sl) && ib.fail()); + + ibInit("0 4294967295 4294967296"); + testVerifyBool((ib >> ul) && ul == 0 && ib.good()); + testVerifyBool((ib >> ul) && ul == 4294967295 && ib.good()); + testVerifyBool(!(ib >> ul) && ib.fail()); + + // octal hex + ibInit("123 abc 0xdef 0XABC 567"); + testVerifyBool((ib >> oct >> i) && i == 83); + testVerifyBool((ib >> hex >> i) && i == 0xabc); + testVerifyBool((ib >> i) && i == 0xdef); + testVerifyBool((ib >> i) && i == 0xabc); + testVerifyBool((ib >> dec >> i) && i ==567); +} +//------------------------------------------------------------------------------ +void istreamStr() { + char str[20]; + ibInit("abc def\r\n hij"); + testVerifyBool((ib >> str) && ib.good()); + testVerifyStr(str, "abc"); + testVerifyBool((ib >> str) && ib.good()); + testVerifyStr(str, "def"); + testVerifyBool((ib >> str) && ib.eof()); + testVerifyStr(str, "hij"); +} +//------------------------------------------------------------------------------ +void setup() { + testBegin(); + istreamBool(); + istreamChar(); + istreamDouble(); + istreamFloat(); + istreamGet(); + istreamNumber(); + istreamStr(); + testEnd(); +} +//------------------------------------------------------------------------------ +void loop() {} \ No newline at end of file diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/lfnSize/lfnSize.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/lfnSize/lfnSize.ino new file mode 100644 index 0000000..a37e9b2 --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/lfnSize/lfnSize.ino @@ -0,0 +1,36 @@ +// Program to compare size of SdFat with the SD.h library. +#include +// Select the test library by commenting out one of the following two lines. +// #include +#include + +// SD chip select pin. +const uint8_t SD_CS_PIN = SS; + +#ifdef __SD_H__ +File file; +#else // __SD_H__ +SdFat SD; +SdFile file; +#endif // __SD_H__ + +void setup() { + Serial.begin(9600); + while (!Serial) {} // wait for Leonardo + + if (!SD.begin(SD_CS_PIN)) { + Serial.println("begin failed"); + return; + } + #ifdef __SD_H__ + file = SD.open("SFN_file.txt", FILE_WRITE); + #else // __SD_H__ + file.open("LFN_file.txt", O_RDWR | O_CREAT); + #endif // __SD_H__ + + file.println("Hello"); + file.close(); + Serial.println("Done"); +} +//------------------------------------------------------------------------------ +void loop() {} \ No newline at end of file diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/lfnTest/lfnTest.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/lfnTest/lfnTest.ino new file mode 100644 index 0000000..c617929 --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/lfnTest/lfnTest.ino @@ -0,0 +1,234 @@ +#include +#include +#include +const uint8_t SD_CS_PIN = SS; +SdFat sd; +SdFile file; +char name[260]; + +//------------------------------------------------------------------------------ +const char* testName[] = { + "low.low", + "low.Mix", + "low.UP", + "Mix.low", + "Mix.Mix", + "Mix.UP", + "UP.low", + "UP.Mix", + "UP.UP", + ".dot", + ".dot.dot", + "A b c . txt", + " Leading space and no extension", + "Trailing dots and space . . .", + "Long extension.extension", + "Space after dot. txt", + "Dot.dot.test.txt", + "Dot.dot.test.seq.txt", + "LOW.LOW", + "MIX.MIX", + "Invalid character *.test" +}; +//------------------------------------------------------------------------------ +bool checkName(char first, size_t len) { + size_t i; + if (len < 5 || len > sizeof(name)) { + return false; + } + if ( name[0] != first) { + return false; + } + for (i = 1; i < (len - 4); i++) { + if (name[i] != (char)('0' + (i + 1) %10)) { + return false; + } + } + const char* p = ".txt"; + while (*p) { + if (name[i++] != *p++) { + return false; + } + } + return name[i] == 0; +} +//------------------------------------------------------------------------------ +void makeName(char first, size_t len) { + size_t i; + if (len > sizeof(name)) { + len = 255; + } + if (len < 5) { + len = 5; + } + name[0] = first; + for (i = 1; i < (len - 4); i++) { + name[i] = '0' + (i + 1) %10; + } + const char* p = ".txt"; + while (*p) name[i++] = *p++; + name[i] = 0; +} +//------------------------------------------------------------------------------ +// test open, remove, getName, and ls. +void basicTest() { + size_t i; + size_t n = sd.vol()->fatType() == 32 ? 255 : 99; + uint16_t maxIndex = 0; + + makeName('Z', 256); + if (!file.open(name, O_RDWR | O_CREAT)) { + Serial.println(F("255 limit OK")); + } else { + sd.errorHalt(F("255 limit")); + } + for (i = 5; i <= n; i++) { + makeName('A', i); + + if (!file.open(name, O_RDWR | O_CREAT)) { + sd.errorHalt(F("open A")); + } + file.println(name); + Serial.print(i); + Serial.write(' '); + Serial.print(file.dirIndex()); + Serial.write(' '); + Serial.print(file.fileSize()); + Serial.println(F(" open A")); + if (file.fileSize() != (i + 2)) { + sd.errorHalt(F("file size A")); + } + if (file.dirIndex() >= maxIndex) { + maxIndex = file.dirIndex(); + } else { + Serial.print(maxIndex); Serial.print(',');Serial.println(file.dirIndex()); + sd.errorHalt(F("dirIndex")); + } + file.close(); + if (!file.open(sd.vwd(), maxIndex, O_READ)) { + sd.errorHalt(F("open by index")); + } + memset(name, 0, sizeof(name)); + if (!file.getName(name, sizeof(name))) { + sd.errorHalt(F("getName")); + } + if (!checkName('A', i)) { + Serial.println(name); + sd.errorHalt(F("checkName")); + } + file.close(); + } + for (i = n; i >= 5; i -= 2) { + makeName('A', i); + Serial.print(i); + Serial.println(F( " rm A")); + if (!sd.remove(name)) { + sd.errorHalt(F("remove A")); + } + } + for (i = n; i >= 5; i -= 2) { + makeName('B', i); + if (!file.open(name, O_RDWR | O_CREAT)) { + sd.errorHalt(F("open B")); + } + file.println(name); + Serial.print(i); + Serial.write(' '); + Serial.print(file.dirIndex()); + Serial.write(' '); + Serial.print(file.fileSize()); + Serial.println(F(" open B")); + if (file.fileSize() != (i + 2)) { + sd.errorHalt(F("file size B")); + } + if (file.dirIndex() > maxIndex) { + sd.errorHalt(F("maxIndex")); + } + file.close(); + } + Serial.println(F("----- ls ------")); + sd.ls(); + for (i = 5; i <= n; i++) { + char fc = i & 1 ? 'B' : 'A'; + makeName(fc, i); + Serial.print(i); + Serial.print(F(" rm ")); + Serial.println(fc); + if (!sd.remove(name)) { + sd.errorHalt(F("remove A/B")); + } + } + if (file.openNext(sd.vwd())) { + sd.errorHalt(F("remove all")); + } + Serial.println(); + Serial.println(F("basicTest done")); +} +//------------------------------------------------------------------------------ +void nameTest() { + Serial.println(); + uint8_t n = sizeof(testName)/sizeof(char*); + for (uint8_t i = 0; i < n; i++) { + Serial.print(F("Name: ")); + Serial.write('"'); + Serial.print(testName[i]); + Serial.println('"'); + if(!file.open(testName[i], O_CREAT | O_RDWR)) { + Serial.println(F("Open failed")); + } else { + file.println(testName[i]); + if (!file.getName(name, sizeof(name))) { + sd.errorHalt(F("getFilemame")); + } + file.println(name); + Serial.print(F("LFN: ")); + Serial.write('"'); + Serial.print(name); + Serial.println('"'); + Serial.print(F("SFN: ")); + Serial.write('"'); + file.printSFN(&Serial); + Serial.println('"'); + Serial.print(F("Index: ")); + if (file.dirIndex() < 10) { + Serial.write(' '); + } + Serial.println(file.dirIndex()); + file.close(); + } + Serial.println(); + } + Serial.println(F("----- ls ------")); + sd.ls(); + Serial.println(); + Serial.println(F("nameTest done")); +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + while(!Serial); + Serial.print(F("\r\nFreeRam: ")); + Serial.println(FreeRam()); + Serial.println(F("Type any character to start.")); + while (Serial.read() < 0) {} + if (!sd.begin(SD_CS_PIN)) sd.initErrorHalt(); + if (file.openNext(sd.vwd())) { + file.close(); + delay(100); + while (Serial.read() >= 0) {} + Serial.print(F("Type 'W' to wipe the card: ")); + int c; + while ((c = Serial.read()) < 0) {} + if (c != 'W') { + sd.errorHalt(F("Invalid")); + } + Serial.println((char)c); + if (!sd.wipe(&Serial) || !sd.begin(SD_CS_PIN)) { + sd.errorHalt(F("wipe failed")); + } + } + basicTest(); + nameTest(); +} +//------------------------------------------------------------------------------ +void loop() {} \ No newline at end of file diff --git a/libraries/SdFat/extras/SdFatTestSuite/examples/lfnTestCout/lfnTestCout.ino b/libraries/SdFat/extras/SdFatTestSuite/examples/lfnTestCout/lfnTestCout.ino new file mode 100644 index 0000000..038f025 --- /dev/null +++ b/libraries/SdFat/extras/SdFatTestSuite/examples/lfnTestCout/lfnTestCout.ino @@ -0,0 +1,218 @@ +#include +#include +#include +const uint8_t SD_CS_PIN = SS; +SdFat sd; +SdFile file; +char name[260]; + +// Serial output stream +ArduinoOutStream cout(Serial); + +// Serial in buffer. +char cinBuf[10]; + +// Serial input stream +ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); +//------------------------------------------------------------------------------ +const char* testName[] = { + "low.low", + "low.Mix", + "low.UP", + "Mix.low", + "Mix.Mix", + "Mix.UP", + "UP.low", + "UP.Mix", + "UP.UP", + ".dot", + ".dot.dot", + "A b c . txt", + " Leading space and no extension", + "Trailing dots and space . . .", + "Long extension.extension", + "Space after dot. txt", + "Dot.dot.test.txt", + "Dot.dot.test.seq.txt", + "LOW.LOW", + "MIX.MIX", + "Invalid character *.test" +}; +//------------------------------------------------------------------------------ +bool checkName(char first, size_t len) { + size_t i; + if (len < 5 || len > sizeof(name)) { + return false; + } + if ( name[0] != first) { + return false; + } + for (i = 1; i < (len - 4); i++) { + if (name[i] != (char)('0' + (i + 1) %10)) { + return false; + } + } + const char* p = ".txt"; + while (*p) { + if (name[i++] != *p++) { + return false; + } + } + return name[i] == 0; +} +//------------------------------------------------------------------------------ +void makeName(char first, size_t len) { + size_t i; + if (len > sizeof(name)) { + len = 255; + } + if (len < 5) { + len = 5; + } + name[0] = first; + for (i = 1; i < (len - 4); i++) { + name[i] = '0' + (i + 1) %10; + } + const char* p = ".txt"; + while (*p) name[i++] = *p++; + name[i] = 0; +} +//------------------------------------------------------------------------------ +// test open, remove, getName, and ls. +void basicTest() { + size_t i; + size_t n = sd.vol()->fatType() == 32 ? 255 : 99; + uint16_t maxIndex = 0; + + makeName('Z', 256); + if (!file.open(name, O_RDWR | O_CREAT)) { + cout << F("255 limit OK") << endl; + } else { + sd.errorHalt(F("255 limit")); + } + for (i = 5; i <= n; i++) { + makeName('A', i); + + if (!file.open(name, O_RDWR | O_CREAT)) { + sd.errorHalt(F("open A")); + } + file.println(name); + cout << setw(3) << i << setw(5) << file.dirIndex() << F(" open A") << endl; + + if (file.fileSize() != (i + 2)) { + sd.errorHalt(F("file size A")); + } + if (file.dirIndex() >= maxIndex) { + maxIndex = file.dirIndex(); + } else { + sd.errorHalt(F("dirIndex")); + } + file.close(); + if (!file.open(sd.vwd(), maxIndex, O_READ)) { + sd.errorHalt(F("open by index")); + } + memset(name, 0, sizeof(name)); + if (!file.getName(name, sizeof(name))) { + sd.errorHalt(F("getName")); + } + if (!checkName('A', i)) { + cout << name << endl; + sd.errorHalt(F("checkName")); + } + file.close(); + } + for (i = n; i >= 5; i -= 2) { + makeName('A', i); + cout << setw(3) << i << F( " rm A") << endl; + if (!sd.remove(name)) { + sd.errorHalt(F("remove A")); + } + } + for (i = n; i >= 5; i -= 2) { + makeName('B', i); + if (!file.open(name, O_RDWR | O_CREAT)) { + sd.errorHalt(F("open B")); + } + file.println(name); + + cout << setw(3) << i << setw(5) << file.dirIndex() << F(" open B") << endl; + + if (file.fileSize() != (i + 2)) { + sd.errorHalt(F("file size B")); + } + if (file.dirIndex() > maxIndex) { + sd.errorHalt(F("maxIndex")); + } + file.close(); + } + cout << endl << F("----- ls ------") << endl; + sd.ls(); + for (i = 5; i <= n; i++) { + char fc = i & 1 ? 'B' : 'A'; + makeName(fc, i); + cout << setw(3) << i << F(" rm ") << fc << endl; + if (!sd.remove(name)) { + sd.errorHalt(F("remove A/B")); + } + } + if (file.openNext(sd.vwd())) { + sd.errorHalt(F("remove all")); + } + cout << endl << F("basicTest done") << endl; +} +//------------------------------------------------------------------------------ +void nameTest() { + cout << endl; + uint8_t n = sizeof(testName)/sizeof(char*); + for (uint8_t i = 0; i < n; i++) { + cout << F("Name: \"") << testName[i] << '"' << endl; + if(!file.open(testName[i], O_CREAT | O_RDWR)) { + cout < +#include +#include +//------------------------------------------------------------------------------ +void ostreamBool() { + char buf[40]; + obufstream ob(buf, sizeof(buf)); + bool f = false; + bool t = true; + ob << t << ',' << f << ',' << setw(2) << t << ',' << left << setw(2) << f; + testVerifyStr(buf, "1,0, 1,0 "); + + ob.init(buf, sizeof(buf)); + ob << boolalpha << t << ',' << f << ',' << setw(5) << t; + ob << ',' << right << setw(6) << f; + testVerifyStr(buf, "true,false,true , false"); +} +//------------------------------------------------------------------------------ +void ostreamChar() { + char buf[40]; + obufstream ob(buf, sizeof(buf)); + char c = 'c'; + signed char sc = 's'; + unsigned char uc = 'u'; + ob <<'l' << c << sc << uc; + ob.put('p'); + testVerifyStr(buf, "lcsup"); + + ob.init(buf, sizeof(buf)); + ob << 's' << setw(2) << 'r' << 'n' << left << setw(2) << 'l'; + ob << 'm' << right << setw(2) << 'e'; + testVerifyStr(buf, "s rnl m e"); + + ob.init(buf, sizeof(buf)); + ob << setfill('f') << setw(5) << 'r'; + testVerifyStr(buf, "ffffr"); +} +//------------------------------------------------------------------------------ +void ostreamFloat() { + char buf[50]; + obufstream ob(buf, sizeof(buf)); + float f = 9.87654; + double d = -123.4567; + ob << f <<','; + ob << internal << setw(10) << d << ','; + ob << setfill('0') << setw(10) << d; + testVerifyStr(buf, "9.88,- 123.46,-000123.46"); + + ob.init(buf, sizeof(buf)); + ob << setw(10) << left << d << ',' << showpos << -d << ','; + ob << setprecision(0) << d; + testVerifyStr(buf, "-123.46000,+123.46,-123"); + + ob.init(buf, sizeof(buf)); + ob << showpoint << d << noshowpoint << ',' << d << ','; + ob << setprecision(4) << f << ',' << setprecision(2) << noshowpos << f; + testVerifyStr(buf, "-123.,-123,+9.8765,9.88"); +} +//------------------------------------------------------------------------------ +void ostreamNumber() { + char buf[50]; + obufstream ob(buf, sizeof(buf)); + + short s = 1; + short signed ss = 2; + short unsigned su = 3; + int i = 4; + int signed is = 5; + int unsigned iu = 6; + long l = 7; + long signed ls = 8; + long unsigned lu = 9; + + + ob << s << ss << su << i << is << iu << l < + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/ArduinoFiles.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ArduinoFiles.h File Reference
+
+
+ +

PrintFile class. +More...

+
#include "FatLibConfig.h"
+#include "FatFile.h"
+#include <limits.h>
+
+Include dependency graph for ArduinoFiles.h:
+
+
+ + + + + + + + + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + +
+
+ + + + + + + +

+Classes

class  File
 Arduino SD.h style File API. More...
 
class  PrintFile
 FatFile with Print. More...
 
+ + + + + +

+Macros

#define FILE_READ   O_READ
 
#define FILE_WRITE   (O_RDWR | O_CREAT | O_AT_END)
 
+

Detailed Description

+

PrintFile class.

+

Macro Definition Documentation

+ +
+
+ + + + +
#define FILE_READ   O_READ
+
+

Arduino SD.h style flag for open for read.

+ +
+
+ +
+
+ + + + +
#define FILE_WRITE   (O_RDWR | O_CREAT | O_AT_END)
+
+

Arduino SD.h style flag for open at EOF for read/write with create.

+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_arduino_files_8h__dep__incl.png b/libraries/SdFat/extras/html/_arduino_files_8h__dep__incl.png new file mode 100644 index 0000000..6e72f2d Binary files /dev/null and b/libraries/SdFat/extras/html/_arduino_files_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/_arduino_files_8h__incl.png b/libraries/SdFat/extras/html/_arduino_files_8h__incl.png new file mode 100644 index 0000000..2c4c69f Binary files /dev/null and b/libraries/SdFat/extras/html/_arduino_files_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_arduino_stream_8h.html b/libraries/SdFat/extras/html/_arduino_stream_8h.html new file mode 100644 index 0000000..1f3c9f9 --- /dev/null +++ b/libraries/SdFat/extras/html/_arduino_stream_8h.html @@ -0,0 +1,146 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/ArduinoStream.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ArduinoStream.h File Reference
+
+
+ +

ArduinoInStream and ArduinoOutStream classes. +More...

+
#include "FatLibConfig.h"
+#include "bufstream.h"
+
+Include dependency graph for ArduinoStream.h:
+
+
+ + + + + + + + + + + + + + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + +
+
+ + + + + + + +

+Classes

class  ArduinoInStream
 Input stream for Arduino Stream objects. More...
 
class  ArduinoOutStream
 Output stream for Arduino Print objects. More...
 
+

Detailed Description

+
+ + + + diff --git a/libraries/SdFat/extras/html/_arduino_stream_8h__dep__incl.png b/libraries/SdFat/extras/html/_arduino_stream_8h__dep__incl.png new file mode 100644 index 0000000..8764ad8 Binary files /dev/null and b/libraries/SdFat/extras/html/_arduino_stream_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/_arduino_stream_8h__incl.png b/libraries/SdFat/extras/html/_arduino_stream_8h__incl.png new file mode 100644 index 0000000..31aee2d Binary files /dev/null and b/libraries/SdFat/extras/html/_arduino_stream_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_block_driver_8h.html b/libraries/SdFat/extras/html/_block_driver_8h.html new file mode 100644 index 0000000..7000066 --- /dev/null +++ b/libraries/SdFat/extras/html/_block_driver_8h.html @@ -0,0 +1,157 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/BlockDriver.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
BlockDriver.h File Reference
+
+
+ +

Define block driver. +More...

+
#include "FatLib/BaseBlockDriver.h"
+#include "SdCard/SdSpiCard.h"
+
+Include dependency graph for BlockDriver.h:
+
+
+ + + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + + + + + + + + + +
+
+ + + +

+Typedefs

typedef SdSpiCard BlockDriver
 
+

Detailed Description

+

Define block driver.

+

Typedef Documentation

+ +
+
+ + + + +
typedef SdSpiCard BlockDriver
+
+

typedef for BlockDriver

+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_block_driver_8h__dep__incl.png b/libraries/SdFat/extras/html/_block_driver_8h__dep__incl.png new file mode 100644 index 0000000..0b19060 Binary files /dev/null and b/libraries/SdFat/extras/html/_block_driver_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/_block_driver_8h__incl.png b/libraries/SdFat/extras/html/_block_driver_8h__incl.png new file mode 100644 index 0000000..bd82994 Binary files /dev/null and b/libraries/SdFat/extras/html/_block_driver_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_fat_file_8h.html b/libraries/SdFat/extras/html/_fat_file_8h.html new file mode 100644 index 0000000..3e79634 --- /dev/null +++ b/libraries/SdFat/extras/html/_fat_file_8h.html @@ -0,0 +1,337 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/FatFile.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
FatFile.h File Reference
+
+
+ +

FatFile class. +More...

+
#include <string.h>
+#include <stddef.h>
+#include <limits.h>
+#include "FatLibConfig.h"
+#include "FatApiConstants.h"
+#include "FatStructs.h"
+#include "FatVolume.h"
+
+Include dependency graph for FatFile.h:
+
+
+ + + + + + + + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + + + + + + +
+
+ + + + + + + + + + +

+Classes

class  FatFile
 Basic file class. More...
 
struct  FatPos_t
 Internal type for file position - do not use in user apps. More...
 
struct  fname_t
 Internal type for Short File Name - do not use in user apps. More...
 
+ + + + + + + + + + + +

+Macros

#define isDirSeparator(c)   ((c) == '/')
 
#define pgm_read_byte(addr)   (*(const unsigned char*)(addr))
 
#define pgm_read_word(addr)   (*(const uint16_t*)(addr))
 
#define PROGMEM
 
#define PSTR(x)   (x)
 
+ + + + + + + + + + + +

+Variables

const uint8_t FNAME_FLAG_LC_BASE = DIR_NT_LC_BASE
 
const uint8_t FNAME_FLAG_LC_EXT = DIR_NT_LC_EXT
 
const uint8_t FNAME_FLAG_LOST_CHARS = 0X01
 
const uint8_t FNAME_FLAG_MIXED_CASE = 0X02
 
const uint8_t FNAME_FLAG_NEED_LFN
 
+

Detailed Description

+

FatFile class.

+

Macro Definition Documentation

+ +
+
+ + + + + + + + +
#define isDirSeparator( c)   ((c) == '/')
+
+

Expression for path name separator.

+ +
+
+ +
+
+ + + + + + + + +
#define pgm_read_byte( addr)   (*(const unsigned char*)(addr))
+
+

read 8-bits from flash for ARM

+ +
+
+ +
+
+ + + + + + + + +
#define pgm_read_word( addr)   (*(const uint16_t*)(addr))
+
+

read 16-bits from flash for ARM

+ +
+
+ +
+
+ + + + +
#define PROGMEM
+
+

store in flash for ARM

+ +
+
+ +
+
+ + + + + + + + +
#define PSTR( x)   (x)
+
+

store literal string in flash for ARM

+ +
+
+

Variable Documentation

+ +
+
+ + + + +
const uint8_t FNAME_FLAG_LC_BASE = DIR_NT_LC_BASE
+
+

Filename base-name is all lower case

+ +
+
+ +
+
+ + + + +
const uint8_t FNAME_FLAG_LC_EXT = DIR_NT_LC_EXT
+
+

Filename extension is all lower case.

+ +
+
+ +
+
+ + + + +
const uint8_t FNAME_FLAG_LOST_CHARS = 0X01
+
+

Derived from a LFN with loss or conversion of characters.

+ +
+
+ +
+
+ + + + +
const uint8_t FNAME_FLAG_MIXED_CASE = 0X02
+
+

Base-name or extension has mixed case.

+ +
+
+ +
+
+ + + + +
const uint8_t FNAME_FLAG_NEED_LFN
+
+Initial value:
=
+ +
const uint8_t FNAME_FLAG_MIXED_CASE
Definition: FatFile.h:92
+
const uint8_t FNAME_FLAG_LOST_CHARS
Definition: FatFile.h:90
+

LFN entries are required for file name.

+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_fat_file_8h__dep__incl.png b/libraries/SdFat/extras/html/_fat_file_8h__dep__incl.png new file mode 100644 index 0000000..2116a88 Binary files /dev/null and b/libraries/SdFat/extras/html/_fat_file_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/_fat_file_8h__incl.png b/libraries/SdFat/extras/html/_fat_file_8h__incl.png new file mode 100644 index 0000000..6fedec9 Binary files /dev/null and b/libraries/SdFat/extras/html/_fat_file_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_fat_file_system_8h.html b/libraries/SdFat/extras/html/_fat_file_system_8h.html new file mode 100644 index 0000000..e340250 --- /dev/null +++ b/libraries/SdFat/extras/html/_fat_file_system_8h.html @@ -0,0 +1,139 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/FatFileSystem.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
FatFileSystem.h File Reference
+
+
+ +

FatFileSystem class. +More...

+
#include "FatVolume.h"
+#include "FatFile.h"
+#include "ArduinoStream.h"
+#include "ArduinoFiles.h"
+
+Include dependency graph for FatFileSystem.h:
+
+
+ + + + + + + + + + + + + + + + + +
+
+ + + + +

+Classes

class  FatFileSystem
 Integration class for the FatLib library. More...
 
+

Detailed Description

+

FatFileSystem class.

+
+ + + + diff --git a/libraries/SdFat/extras/html/_fat_file_system_8h__incl.png b/libraries/SdFat/extras/html/_fat_file_system_8h__incl.png new file mode 100644 index 0000000..dbcfb61 Binary files /dev/null and b/libraries/SdFat/extras/html/_fat_file_system_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_fat_lib_config_8h.html b/libraries/SdFat/extras/html/_fat_lib_config_8h.html new file mode 100644 index 0000000..a07dfa0 --- /dev/null +++ b/libraries/SdFat/extras/html/_fat_lib_config_8h.html @@ -0,0 +1,274 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/FatLibConfig.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
FatLibConfig.h File Reference
+
+
+ +

configuration definitions +More...

+
#include <stdint.h>
+#include "SdFatConfig.h"
+#include <Arduino.h>
+
+Include dependency graph for FatLibConfig.h:
+
+
+ + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + +

+Macros

#define DESTRUCTOR_CLOSES_FILE   0
 
#define ENABLE_ARDUINO_FEATURES   1
 
#define ENDL_CALLS_FLUSH   0
 
#define FAT12_SUPPORT   0
 
#define MAINTAIN_FREE_CLUSTER_COUNT   0
 
#define USE_LONG_FILE_NAMES   1
 
#define USE_MULTI_BLOCK_IO   1
 
#define USE_SEPARATE_FAT_CACHE   0
 
+

Detailed Description

+

configuration definitions

+

Macro Definition Documentation

+ +
+
+ + + + +
#define DESTRUCTOR_CLOSES_FILE   0
+
+

Set DESTRUCTOR_CLOSES_FILE non-zero to close a file in its destructor.

+

Causes use of lots of heap in ARM.

+ +
+
+ +
+
+ + + + +
#define ENABLE_ARDUINO_FEATURES   1
+
+

Enable Extra features for Arduino.

+ +
+
+ +
+
+ + + + +
#define ENDL_CALLS_FLUSH   0
+
+

Call flush for endl if ENDL_CALLS_FLUSH is non-zero

+

The standard for iostreams is to call flush. This is very costly for SdFat. Each call to flush causes 2048 bytes of I/O to the SD.

+

SdFat has a single 512 byte buffer for I/O so it must write the current data block to the SD, read the directory block from the SD, update the directory entry, write the directory block to the SD and read the data block back into the buffer.

+

The SD flash memory controller is not designed for this many rewrites so performance may be reduced by more than a factor of 100.

+

If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force all data to be written to the SD.

+ +
+
+ +
+
+ + + + +
#define FAT12_SUPPORT   0
+
+

Allow FAT12 volumes if FAT12_SUPPORT is non-zero. FAT12 has not been well tested.

+ +
+
+ +
+
+ + + + +
#define MAINTAIN_FREE_CLUSTER_COUNT   0
+
+

Set MAINTAIN_FREE_CLUSTER_COUNT nonzero to keep the count of free clusters updated. This will increase the speed of the freeClusterCount() call after the first call. Extra flash will be required.

+ +
+
+ +
+
+ + + + +
#define USE_LONG_FILE_NAMES   1
+
+

Set USE_LONG_FILE_NAMES nonzero to use long file names (LFN). Long File Name are limited to a maximum length of 255 characters.

+

This implementation allows 7-bit characters in the range 0X20 to 0X7E. The following characters are not allowed:

+

< (less than)

+

(greater than)

+
+

: (colon) " (double quote) / (forward slash) \ (backslash) | (vertical bar or pipe) ? (question mark)

    +
  • (asterisk)
  • +
+ +
+
+ +
+
+ + + + +
#define USE_MULTI_BLOCK_IO   1
+
+

Set USE_MULTI_BLOCK_IO non-zero to use multi-block SD read/write.

+

Don't use mult-block read/write on small AVR boards.

+ +
+
+ +
+
+ + + + +
#define USE_SEPARATE_FAT_CACHE   0
+
+

Set USE_SEPARATE_FAT_CACHE non-zero to use a second 512 byte cache for FAT table entries. Improves performance for large writes that are not a multiple of 512 bytes.

+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_fat_lib_config_8h__dep__incl.png b/libraries/SdFat/extras/html/_fat_lib_config_8h__dep__incl.png new file mode 100644 index 0000000..a7a8d21 Binary files /dev/null and b/libraries/SdFat/extras/html/_fat_lib_config_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/_fat_lib_config_8h__incl.png b/libraries/SdFat/extras/html/_fat_lib_config_8h__incl.png new file mode 100644 index 0000000..4f0dc51 Binary files /dev/null and b/libraries/SdFat/extras/html/_fat_lib_config_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_fat_structs_8h.html b/libraries/SdFat/extras/html/_fat_structs_8h.html new file mode 100644 index 0000000..a3a887f --- /dev/null +++ b/libraries/SdFat/extras/html/_fat_structs_8h.html @@ -0,0 +1,1282 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/FatStructs.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
FatStructs.h File Reference
+
+
+ +

FAT file structures. +More...

+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Classes

struct  biosParmBlock
 BIOS parameter block. More...
 
struct  directoryEntry
 FAT short directory entry. More...
 
struct  fat32_boot
 Boot sector for a FAT32 volume. More...
 
struct  fat32_fsinfo
 FSINFO sector for a FAT32 volume. More...
 
struct  fat_boot
 Boot sector for a FAT12/FAT16 volume. More...
 
struct  longDirectoryEntry
 FAT long directory entry. More...
 
struct  masterBootRecord
 Master Boot Record. More...
 
struct  partitionTable
 MBR partition table entry. More...
 
+ + + + + + + + + + + + + + + + + +

+Typedefs

typedef struct biosParmBlock bpb_t
 
typedef struct directoryEntry dir_t
 
typedef struct fat32_boot fat32_boot_t
 
typedef struct fat32_fsinfo fat32_fsinfo_t
 
typedef struct fat_boot fat_boot_t
 
typedef struct longDirectoryEntry ldir_t
 
typedef struct masterBootRecord mbr_t
 
typedef struct partitionTable part_t
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

static uint8_t DIR_IS_FILE (const dir_t *dir)
 
static uint8_t DIR_IS_FILE_OR_SUBDIR (const dir_t *dir)
 
static uint8_t DIR_IS_HIDDEN (const dir_t *dir)
 
static uint8_t DIR_IS_LONG_NAME (const dir_t *dir)
 
static uint8_t DIR_IS_SUBDIR (const dir_t *dir)
 
static uint8_t DIR_IS_SYSTEM (const dir_t *dir)
 
static uint16_t FAT_DATE (uint16_t year, uint8_t month, uint8_t day)
 
static uint8_t FAT_DAY (uint16_t fatDate)
 
static uint8_t FAT_HOUR (uint16_t fatTime)
 
static uint8_t FAT_MINUTE (uint16_t fatTime)
 
static uint8_t FAT_MONTH (uint16_t fatDate)
 
static uint8_t FAT_SECOND (uint16_t fatTime)
 
static uint16_t FAT_TIME (uint8_t hour, uint8_t minute, uint8_t second)
 
static uint16_t FAT_YEAR (uint16_t fatDate)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t BOOTSIG0 = 0X55
 
const uint8_t BOOTSIG1 = 0XAA
 
const uint8_t DIR_ATT_ARCHIVE = 0X20
 
const uint8_t DIR_ATT_DEFINED_BITS = 0X3F
 
const uint8_t DIR_ATT_DIRECTORY = 0X10
 
const uint8_t DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY)
 
const uint8_t DIR_ATT_HIDDEN = 0X02
 
const uint8_t DIR_ATT_LONG_NAME = 0X0F
 
const uint8_t DIR_ATT_LONG_NAME_MASK = 0X3F
 
const uint8_t DIR_ATT_READ_ONLY = 0X01
 
const uint8_t DIR_ATT_SYSTEM = 0X04
 
const uint8_t DIR_ATT_VOLUME_ID = 0X08
 
const uint8_t DIR_NAME_0XE5 = 0X05
 
const uint8_t DIR_NAME_DELETED = 0XE5
 
const uint8_t DIR_NAME_FREE = 0X00
 
const uint8_t DIR_NT_LC_BASE = 0X08
 
const uint8_t DIR_NT_LC_EXT = 0X10
 
const uint8_t EXTENDED_BOOT_SIG = 0X29
 
const uint16_t FAT12EOC = 0XFFF
 
const uint16_t FAT12EOC_MIN = 0XFF8
 
const uint16_t FAT16EOC = 0XFFFF
 
const uint16_t FAT16EOC_MIN = 0XFFF8
 
const uint32_t FAT32EOC = 0X0FFFFFFF
 
const uint32_t FAT32EOC_MIN = 0X0FFFFFF8
 
const uint32_t FAT32MASK = 0X0FFFFFFF
 
const uint16_t FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1
 
const uint16_t FAT_DEFAULT_TIME = (1 << 11)
 
const uint32_t FSINFO_LEAD_SIG = 0x41615252
 
const uint32_t FSINFO_STRUCT_SIG = 0x61417272
 
const uint8_t LDIR_NAME1_DIM = 5
 
const uint8_t LDIR_NAME2_DIM = 6
 
const uint8_t LDIR_NAME3_DIM = 2
 
const uint8_t LDIR_ORD_LAST_LONG_ENTRY = 0X40
 
+

Detailed Description

+

FAT file structures.

+

Typedef Documentation

+ +
+
+ + + + +
typedef struct biosParmBlock bpb_t
+
+

Type name for biosParmBlock

+ +
+
+ +
+
+ + + + +
typedef struct directoryEntry dir_t
+
+

Type name for directoryEntry

+ +
+
+ +
+
+ + + + +
typedef struct fat32_boot fat32_boot_t
+
+

Type name for FAT32 Boot Sector

+ +
+
+ +
+
+ + + + +
typedef struct fat32_fsinfo fat32_fsinfo_t
+
+

Type name for FAT32 FSINFO Sector

+ +
+
+ +
+
+ + + + +
typedef struct fat_boot fat_boot_t
+
+

Type name for FAT Boot Sector

+ +
+
+ +
+
+ + + + +
typedef struct longDirectoryEntry ldir_t
+
+

Type name for longDirectoryEntry

+ +
+
+ +
+
+ + + + +
typedef struct masterBootRecord mbr_t
+
+

Type name for masterBootRecord

+ +
+
+ +
+
+ + + + +
typedef struct partitionTable part_t
+
+

Type name for partitionTable

+ +
+
+

Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t DIR_IS_FILE (const dir_tdir)
+
+inlinestatic
+
+

Directory entry is for a file

Parameters
+ + +
[in]dirPointer to a directory entry.
+
+
+
Returns
true if the entry is for a normal file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t DIR_IS_FILE_OR_SUBDIR (const dir_tdir)
+
+inlinestatic
+
+

Directory entry is for a file or subdirectory

Parameters
+ + +
[in]dirPointer to a directory entry.
+
+
+
Returns
true if the entry is for a normal file or subdirectory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t DIR_IS_HIDDEN (const dir_tdir)
+
+inlinestatic
+
+

Directory entry is hidden

Parameters
+ + +
[in]dirPointer to a directory entry.
+
+
+
Returns
true if the entry is hidden else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t DIR_IS_LONG_NAME (const dir_tdir)
+
+inlinestatic
+
+

Directory entry is part of a long name

Parameters
+ + +
[in]dirPointer to a directory entry.
+
+
+
Returns
true if the entry is for part of a long name else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t DIR_IS_SUBDIR (const dir_tdir)
+
+inlinestatic
+
+

Directory entry is for a subdirectory

Parameters
+ + +
[in]dirPointer to a directory entry.
+
+
+
Returns
true if the entry is for a subdirectory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t DIR_IS_SYSTEM (const dir_tdir)
+
+inlinestatic
+
+

Directory entry is system type

Parameters
+ + +
[in]dirPointer to a directory entry.
+
+
+
Returns
true if the entry is system else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static uint16_t FAT_DATE (uint16_t year,
uint8_t month,
uint8_t day 
)
+
+inlinestatic
+
+

date field for FAT directory entry

Parameters
+ + + + +
[in]year[1980,2107]
[in]month[1,12]
[in]day[1,31]
+
+
+
Returns
Packed date for dir_t entry.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t FAT_DAY (uint16_t fatDate)
+
+inlinestatic
+
+

day part of FAT directory date field

Parameters
+ + +
[in]fatDateDate in packed dir format.
+
+
+
Returns
Extracted day [1,31]
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t FAT_HOUR (uint16_t fatTime)
+
+inlinestatic
+
+

hour part of FAT directory time field

Parameters
+ + +
[in]fatTimeTime in packed dir format.
+
+
+
Returns
Extracted hour [0,23]
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t FAT_MINUTE (uint16_t fatTime)
+
+inlinestatic
+
+

minute part of FAT directory time field

Parameters
+ + +
[in]fatTimeTime in packed dir format.
+
+
+
Returns
Extracted minute [0,59]
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t FAT_MONTH (uint16_t fatDate)
+
+inlinestatic
+
+

month part of FAT directory date field

Parameters
+ + +
[in]fatDateDate in packed dir format.
+
+
+
Returns
Extracted month [1,12]
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint8_t FAT_SECOND (uint16_t fatTime)
+
+inlinestatic
+
+

second part of FAT directory time field Note second/2 is stored in packed time.

+
Parameters
+ + +
[in]fatTimeTime in packed dir format.
+
+
+
Returns
Extracted second [0,58]
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static uint16_t FAT_TIME (uint8_t hour,
uint8_t minute,
uint8_t second 
)
+
+inlinestatic
+
+

time field for FAT directory entry

Parameters
+ + + + +
[in]hour[0,23]
[in]minute[0,59]
[in]second[0,59]
+
+
+
Returns
Packed time for dir_t entry.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static uint16_t FAT_YEAR (uint16_t fatDate)
+
+inlinestatic
+
+

year part of FAT directory date field

Parameters
+ + +
[in]fatDateDate in packed dir format.
+
+
+
Returns
Extracted year [1980,2107]
+ +
+
+

Variable Documentation

+ +
+
+ + + + +
const uint8_t BOOTSIG0 = 0X55
+
+

Value for byte 510 of boot block or MBR

+ +
+
+ +
+
+ + + + +
const uint8_t BOOTSIG1 = 0XAA
+
+

Value for byte 511 of boot block or MBR

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_ATT_ARCHIVE = 0X20
+
+

Old DOS archive bit for backup support

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_ATT_DEFINED_BITS = 0X3F
+
+

defined attribute bits

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_ATT_DIRECTORY = 0X10
+
+

Entry is for a directory

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY)
+
+

Mask for file/subdirectory tests

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_ATT_HIDDEN = 0X02
+
+

File should e hidden in directory listings

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_ATT_LONG_NAME = 0X0F
+
+

Test value for long name entry. Test is (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME.

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_ATT_LONG_NAME_MASK = 0X3F
+
+

Test mask for long name entry

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_ATT_READ_ONLY = 0X01
+
+

file is read-only

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_ATT_SYSTEM = 0X04
+
+

Entry is for a system file

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_ATT_VOLUME_ID = 0X08
+
+

Directory entry contains the volume label

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_NAME_0XE5 = 0X05
+
+

escape for name[0] = 0XE5

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_NAME_DELETED = 0XE5
+
+

name[0] value for entry that is free after being "deleted"

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_NAME_FREE = 0X00
+
+

name[0] value for entry that is free and no allocated entries follow

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_NT_LC_BASE = 0X08
+
+

Filename base-name is all lower case

+ +
+
+ +
+
+ + + + +
const uint8_t DIR_NT_LC_EXT = 0X10
+
+

Filename extension is all lower case.

+ +
+
+ +
+
+ + + + +
const uint8_t EXTENDED_BOOT_SIG = 0X29
+
+

Value for bootSignature field int FAT/FAT32 boot sector

+ +
+
+ +
+
+ + + + +
const uint16_t FAT12EOC = 0XFFF
+
+

FAT12 end of chain value used by Microsoft.

+ +
+
+ +
+
+ + + + +
const uint16_t FAT12EOC_MIN = 0XFF8
+
+

Minimum value for FAT12 EOC. Use to test for EOC.

+ +
+
+ +
+
+ + + + +
const uint16_t FAT16EOC = 0XFFFF
+
+

FAT16 end of chain value used by Microsoft.

+ +
+
+ +
+
+ + + + +
const uint16_t FAT16EOC_MIN = 0XFFF8
+
+

Minimum value for FAT16 EOC. Use to test for EOC.

+ +
+
+ +
+
+ + + + +
const uint32_t FAT32EOC = 0X0FFFFFFF
+
+

FAT32 end of chain value used by Microsoft.

+ +
+
+ +
+
+ + + + +
const uint32_t FAT32EOC_MIN = 0X0FFFFFF8
+
+

Minimum value for FAT32 EOC. Use to test for EOC.

+ +
+
+ +
+
+ + + + +
const uint32_t FAT32MASK = 0X0FFFFFFF
+
+

Mask a for FAT32 entry. Entries are 28 bits.

+ +
+
+ +
+
+ + + + +
const uint16_t FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1
+
+

Default date for file timestamps is 1 Jan 2000

+ +
+
+ +
+
+ + + + +
const uint16_t FAT_DEFAULT_TIME = (1 << 11)
+
+

Default time for file timestamp is 1 am

+ +
+
+ +
+
+ + + + +
const uint32_t FSINFO_LEAD_SIG = 0x41615252
+
+

Lead signature for a FSINFO sector

+ +
+
+ +
+
+ + + + +
const uint32_t FSINFO_STRUCT_SIG = 0x61417272
+
+

Struct signature for a FSINFO sector

+ +
+
+ +
+
+ + + + +
const uint8_t LDIR_NAME1_DIM = 5
+
+

Dimension of first name field in long directory entry

+ +
+
+ +
+
+ + + + +
const uint8_t LDIR_NAME2_DIM = 6
+
+

Dimension of first name field in long directory entry

+ +
+
+ +
+
+ + + + +
const uint8_t LDIR_NAME3_DIM = 2
+
+

Dimension of first name field in long directory entry

+ +
+
+ +
+
+ + + + +
const uint8_t LDIR_ORD_LAST_LONG_ENTRY = 0X40
+
+

Ord mast that indicates the entry is the last long dir entry in a set of long dir entries. All valid sets of long dir entries must begin with an entry having this mask.

+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_fat_structs_8h__dep__incl.png b/libraries/SdFat/extras/html/_fat_structs_8h__dep__incl.png new file mode 100644 index 0000000..716eee9 Binary files /dev/null and b/libraries/SdFat/extras/html/_fat_structs_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/_fat_volume_8h.html b/libraries/SdFat/extras/html/_fat_volume_8h.html new file mode 100644 index 0000000..8674685 --- /dev/null +++ b/libraries/SdFat/extras/html/_fat_volume_8h.html @@ -0,0 +1,174 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/FatVolume.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
FatVolume.h File Reference
+
+
+ +

FatVolume class. +More...

+
#include <stddef.h>
+#include "FatLibConfig.h"
+#include "FatStructs.h"
+#include "BlockDriver.h"
+
+Include dependency graph for FatVolume.h:
+
+
+ + + + + + + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + + + + + + + +
+
+ + + + + + + + + + +

+Classes

union  cache_t
 Cache for an raw data block. More...
 
class  FatCache
 Block cache. More...
 
class  FatVolume
 Access FAT16 and FAT32 volumes on raw file devices. More...
 
+ + + +

+Typedefs

typedef Print print_t
 
+

Detailed Description

+

FatVolume class.

+

Typedef Documentation

+ +
+
+ + + + +
typedef Print print_t
+
+

Use Print for Arduino

+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_fat_volume_8h__dep__incl.png b/libraries/SdFat/extras/html/_fat_volume_8h__dep__incl.png new file mode 100644 index 0000000..54a2ab2 Binary files /dev/null and b/libraries/SdFat/extras/html/_fat_volume_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/_fat_volume_8h__incl.png b/libraries/SdFat/extras/html/_fat_volume_8h__incl.png new file mode 100644 index 0000000..57b8c85 Binary files /dev/null and b/libraries/SdFat/extras/html/_fat_volume_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_free_stack_8h.html b/libraries/SdFat/extras/html/_free_stack_8h.html new file mode 100644 index 0000000..24aeca1 --- /dev/null +++ b/libraries/SdFat/extras/html/_free_stack_8h.html @@ -0,0 +1,172 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FreeStack.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
FreeStack.h File Reference
+
+
+ +

FreeStack() function. +More...

+ + + + +

+Functions

static int FreeStack ()
 
+ + + + + +

+Variables

char * __brkval
 
char __bss_end
 
+

Detailed Description

+

FreeStack() function.

+

Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
static int FreeStack ()
+
+static
+
+

Amount of free stack space.

Returns
The number of free bytes.
+ +
+
+

Variable Documentation

+ +
+
+ + + + +
char* __brkval
+
+

boundary between stack and heap.

+ +
+
+ +
+
+ + + + +
char __bss_end
+
+

End of bss section.

+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_minimum_serial_8h.html b/libraries/SdFat/extras/html/_minimum_serial_8h.html new file mode 100644 index 0000000..b4bca2c --- /dev/null +++ b/libraries/SdFat/extras/html/_minimum_serial_8h.html @@ -0,0 +1,122 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/MinimumSerial.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
MinimumSerial.h File Reference
+
+
+ +

Minimal AVR Serial driver. +More...

+
#include "SysCall.h"
+
+Include dependency graph for MinimumSerial.h:
+
+
+ + + +
+
+ + + + +

+Classes

class  MinimumSerial
 mini serial class for the SdFat library. More...
 
+

Detailed Description

+

Minimal AVR Serial driver.

+
+ + + + diff --git a/libraries/SdFat/extras/html/_minimum_serial_8h__incl.png b/libraries/SdFat/extras/html/_minimum_serial_8h__incl.png new file mode 100644 index 0000000..b7fe5cb Binary files /dev/null and b/libraries/SdFat/extras/html/_minimum_serial_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_sd_fat_8h.html b/libraries/SdFat/extras/html/_sd_fat_8h.html new file mode 100644 index 0000000..b441f47 --- /dev/null +++ b/libraries/SdFat/extras/html/_sd_fat_8h.html @@ -0,0 +1,171 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/SdFat.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
SdFat.h File Reference
+
+
+ +

SdFat class. +More...

+
#include "SysCall.h"
+#include "BlockDriver.h"
+#include "FatLib/FatLib.h"
+#include "SdCard/SdioCard.h"
+
+Include dependency graph for SdFat.h:
+
+
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Classes

class  Sd2Card
 Raw access to SD and SDHC card using default SPI library. More...
 
class  SdBaseFile
 Class for backward compatibility. More...
 
class  SdFat
 Main file system class for SdFat library. More...
 
class  SdFatEX
 SdFat class with extended SD I/O. More...
 
class  SdFatSdio
 SdFat class using SDIO. More...
 
class  SdFatSoftSpi< MisoPin, MosiPin, SckPin >
 SdFat class using software SPI. More...
 
class  SdFatSoftSpiEX< MisoPin, MosiPin, SckPin >
 SdFat class using software SPI and extended SD I/O. More...
 
class  SdFile
 Class for backward compatibility. More...
 
class  SdFileSystem< SdDriverClass >
 Virtual base class for SdFat library. More...
 
+ + + +

+Macros

#define SD_FAT_VERSION   20160905
 
+

Detailed Description

+

SdFat class.

+

Macro Definition Documentation

+ +
+
+ + + + +
#define SD_FAT_VERSION   20160905
+
+

SdFat version YYYYMMDD

+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_sd_fat_8h__incl.png b/libraries/SdFat/extras/html/_sd_fat_8h__incl.png new file mode 100644 index 0000000..e5f5614 Binary files /dev/null and b/libraries/SdFat/extras/html/_sd_fat_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_sd_fat_config_8h.html b/libraries/SdFat/extras/html/_sd_fat_config_8h.html new file mode 100644 index 0000000..bc2326d --- /dev/null +++ b/libraries/SdFat/extras/html/_sd_fat_config_8h.html @@ -0,0 +1,381 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/SdFatConfig.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
SdFatConfig.h File Reference
+
+
+ +

configuration definitions +More...

+
#include <stdint.h>
+
+Include dependency graph for SdFatConfig.h:
+
+
+ + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

#define DESTRUCTOR_CLOSES_FILE   0
 
#define ENABLE_EXTENDED_TRANSFER_CLASS   0
 
#define ENABLE_SDIO_CLASS   0
 
#define ENABLE_SOFTWARE_SPI_CLASS   0
 
#define ENDL_CALLS_FLUSH   0
 
#define FAT12_SUPPORT   0
 
#define IMPLEMENT_SPI_PORT_SELECTION   0
 
#define MAINTAIN_FREE_CLUSTER_COUNT   0
 
#define SD_HAS_CUSTOM_SPI   0
 
#define USE_LONG_FILE_NAMES   1
 
#define USE_MULTI_BLOCK_IO   1
 
#define USE_SD_CRC   0
 
#define USE_SEPARATE_FAT_CACHE   0
 
#define USE_STANDARD_SPI_LIBRARY   0
 
#define WDT_YIELD_TIME_MICROS   0
 
+

Detailed Description

+

configuration definitions

+

Macro Definition Documentation

+ +
+
+ + + + +
#define DESTRUCTOR_CLOSES_FILE   0
+
+

Set DESTRUCTOR_CLOSES_FILE nonzero to close a file in its destructor.

+

Causes use of lots of heap in ARM.

+ +
+
+ +
+
+ + + + +
#define ENABLE_EXTENDED_TRANSFER_CLASS   0
+
+

If the symbol ENABLE_EXTENDED_TRANSFER_CLASS is nonzero, the class SdFatEX will be defined. If the symbol ENABLE_SOFTWARE_SPI_CLASS is also nonzero, the class SdFatSoftSpiEX will be defined.

+

These classes used extended multi-block SD I/O for better performance. the SPI bus may not be shared with other devices in this mode.

+ +
+
+ +
+
+ + + + +
#define ENABLE_SDIO_CLASS   0
+
+

Enable SDIO driver if available.

+ +
+
+ +
+
+ + + + +
#define ENABLE_SOFTWARE_SPI_CLASS   0
+
+

If the symbol ENABLE_SOFTWARE_SPI_CLASS is nonzero, the class SdFatSoftSpi will be defined. If ENABLE_EXTENDED_TRANSFER_CLASS is also nonzero, the class SdFatSoftSpiEX will be defined.

+ +
+
+ +
+
+ + + + +
#define ENDL_CALLS_FLUSH   0
+
+

Call flush for endl if ENDL_CALLS_FLUSH is nonzero

+

The standard for iostreams is to call flush. This is very costly for SdFat. Each call to flush causes 2048 bytes of I/O to the SD.

+

SdFat has a single 512 byte buffer for SD I/O so it must write the current data block to the SD, read the directory block from the SD, update the directory entry, write the directory block to the SD and read the data block back into the buffer.

+

The SD flash memory controller is not designed for this many rewrites so performance may be reduced by more than a factor of 100.

+

If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force all data to be written to the SD.

+ +
+
+ +
+
+ + + + +
#define FAT12_SUPPORT   0
+
+

Set FAT12_SUPPORT nonzero to enable use if FAT12 volumes. FAT12 has not been well tested and requires additional flash.

+ +
+
+ +
+
+ + + + +
#define IMPLEMENT_SPI_PORT_SELECTION   0
+
+

Check if API to select HW SPI port is needed.

+ +
+
+ +
+
+ + + + +
#define MAINTAIN_FREE_CLUSTER_COUNT   0
+
+

Set MAINTAIN_FREE_CLUSTER_COUNT nonzero to keep the count of free clusters updated. This will increase the speed of the freeClusterCount() call after the first call. Extra flash will be required.

+ +
+
+ +
+
+ + + + +
#define SD_HAS_CUSTOM_SPI   0
+
+

Determine the default SPI configuration.

+ +
+
+ +
+
+ + + + +
#define USE_LONG_FILE_NAMES   1
+
+

Set USE_LONG_FILE_NAMES nonzero to use long file names (LFN). Long File Name are limited to a maximum length of 255 characters.

+

This implementation allows 7-bit characters in the range 0X20 to 0X7E except the following characters are not allowed:

+

< (less than)

+

(greater than)

+
+

: (colon) " (double quote) / (forward slash) \ (backslash) | (vertical bar or pipe) ? (question mark)

    +
  • (asterisk)
  • +
+ +
+
+ +
+
+ + + + +
#define USE_MULTI_BLOCK_IO   1
+
+

Set USE_MULTI_BLOCK_IO nonzero to use multi-block SD read/write.

+

Don't use mult-block read/write on small AVR boards.

+ +
+
+ +
+
+ + + + +
#define USE_SD_CRC   0
+
+

To enable SD card CRC checking set USE_SD_CRC nonzero.

+

Set USE_SD_CRC to 1 to use a smaller CRC-CCITT function. This function is slower for AVR but may be fast for ARM and other processors.

+

Set USE_SD_CRC to 2 to used a larger table driven CRC-CCITT function. This function is faster for AVR but may be slower for ARM and other processors.

+ +
+
+ +
+
+ + + + +
#define USE_SEPARATE_FAT_CACHE   0
+
+

Set USE_SEPARATE_FAT_CACHE nonzero to use a second 512 byte cache for FAT table entries. This improves performance for large writes that are not a multiple of 512 bytes.

+ +
+
+ +
+
+ + + + +
#define USE_STANDARD_SPI_LIBRARY   0
+
+

If the symbol USE_STANDARD_SPI_LIBRARY is nonzero, the classes SdFat and SdFatEX use the standard Arduino SPI.h library. If USE_STANDARD_SPI_LIBRARY is zero, an optimized custom SPI driver is used if it exists.

+ +
+
+ +
+
+ + + + +
#define WDT_YIELD_TIME_MICROS   0
+
+

Handle Watchdog Timer for WiFi modules.

+

Yield will be called before accessing the SPI bus if it has been more than WDT_YIELD_TIME_MICROS microseconds since the last yield call by SdFat.

+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_sd_fat_config_8h__dep__incl.png b/libraries/SdFat/extras/html/_sd_fat_config_8h__dep__incl.png new file mode 100644 index 0000000..2d40427 Binary files /dev/null and b/libraries/SdFat/extras/html/_sd_fat_config_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/_sd_fat_config_8h__incl.png b/libraries/SdFat/extras/html/_sd_fat_config_8h__incl.png new file mode 100644 index 0000000..39f9b12 Binary files /dev/null and b/libraries/SdFat/extras/html/_sd_fat_config_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_sd_spi_card_8h.html b/libraries/SdFat/extras/html/_sd_spi_card_8h.html new file mode 100644 index 0000000..cdb1ba2 --- /dev/null +++ b/libraries/SdFat/extras/html/_sd_spi_card_8h.html @@ -0,0 +1,150 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/SdCard/SdSpiCard.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
SdSpiCard.h File Reference
+
+
+ +

SdSpiCard class for V2 SD/SDHC cards. +More...

+
#include <stddef.h>
+#include "SysCall.h"
+#include "SdInfo.h"
+#include "../FatLib/BaseBlockDriver.h"
+#include "../SpiDriver/SdSpiDriver.h"
+
+Include dependency graph for SdSpiCard.h:
+
+
+ + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + + + + + + + + + + +
+
+ + + + + + + +

+Classes

class  SdSpiCard
 Raw access to SD and SDHC flash memory cards via SPI protocol. More...
 
class  SdSpiCardEX
 Extended SD I/O block driver. More...
 
+

Detailed Description

+

SdSpiCard class for V2 SD/SDHC cards.

+
+ + + + diff --git a/libraries/SdFat/extras/html/_sd_spi_card_8h__dep__incl.png b/libraries/SdFat/extras/html/_sd_spi_card_8h__dep__incl.png new file mode 100644 index 0000000..b14e65c Binary files /dev/null and b/libraries/SdFat/extras/html/_sd_spi_card_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/_sd_spi_card_8h__incl.png b/libraries/SdFat/extras/html/_sd_spi_card_8h__incl.png new file mode 100644 index 0000000..5ae683e Binary files /dev/null and b/libraries/SdFat/extras/html/_sd_spi_card_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_stdio_stream_8h.html b/libraries/SdFat/extras/html/_stdio_stream_8h.html new file mode 100644 index 0000000..b157a41 --- /dev/null +++ b/libraries/SdFat/extras/html/_stdio_stream_8h.html @@ -0,0 +1,246 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/StdioStream.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
StdioStream.h File Reference
+
+
+ +

StdioStream class. +More...

+
#include <limits.h>
+#include "FatFile.h"
+#include <stdio.h>
+
+Include dependency graph for StdioStream.h:
+
+
+ + + + + + + + + + +
+
+ + + + +

+Classes

class  StdioStream
 StdioStream implements a minimal stdio stream. More...
 
+ + + + + + + + + + + +

+Macros

#define EOF   (-1)
 
#define NULL   0
 
#define SEEK_CUR   1
 
#define SEEK_END   2
 
#define SEEK_SET   0
 
+ + + + + +

+Variables

const uint8_t STREAM_BUF_SIZE = 64
 
const uint8_t UNGETC_BUF_SIZE = 2
 
+

Detailed Description

+

StdioStream class.

+

Macro Definition Documentation

+ +
+
+ + + + +
#define EOF   (-1)
+
+

End-of-file return value.

+ +
+
+ +
+
+ + + + +
#define NULL   0
+
+

Null pointer

+ +
+
+ +
+
+ + + + +
#define SEEK_CUR   1
+
+

Seek relative to current position.

+ +
+
+ +
+
+ + + + +
#define SEEK_END   2
+
+

Seek relative to end-of-file.

+ +
+
+ +
+
+ + + + +
#define SEEK_SET   0
+
+

Seek relative to start-of-file.

+ +
+
+

Variable Documentation

+ +
+
+ + + + +
const uint8_t STREAM_BUF_SIZE = 64
+
+

Total size of stream buffer. The entire buffer is used for output. During input UNGETC_BUF_SIZE of this space is reserved for ungetc.

+ +
+
+ +
+
+ + + + +
const uint8_t UNGETC_BUF_SIZE = 2
+
+

Amount of buffer allocated for ungetc during input.

+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_stdio_stream_8h__incl.png b/libraries/SdFat/extras/html/_stdio_stream_8h__incl.png new file mode 100644 index 0000000..d49df80 Binary files /dev/null and b/libraries/SdFat/extras/html/_stdio_stream_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/_sys_call_8h.html b/libraries/SdFat/extras/html/_sys_call_8h.html new file mode 100644 index 0000000..f5e65c8 --- /dev/null +++ b/libraries/SdFat/extras/html/_sys_call_8h.html @@ -0,0 +1,191 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/SysCall.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
SysCall.h File Reference
+
+
+ +

SysCall class. +More...

+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + + + + + + + + + + + + +
+
+ + + + +

+Classes

class  SysCall
 SysCall - Class to wrap system calls. More...
 
+ + + +

+Macros

#define F(str)   (str)
 
+ + + +

+Functions

uint16_t curTimeMS ()
 
+

Detailed Description

+

SysCall class.

+

Macro Definition Documentation

+ +
+
+ + + + + + + + +
#define F( str)   (str)
+
+

Define macro for strings stored in flash.

+ +
+
+

Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
uint16_t curTimeMS ()
+
+inline
+
+
Returns
the time in milliseconds.
+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/_sys_call_8h__dep__incl.png b/libraries/SdFat/extras/html/_sys_call_8h__dep__incl.png new file mode 100644 index 0000000..f63deda Binary files /dev/null and b/libraries/SdFat/extras/html/_sys_call_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/annotated.html b/libraries/SdFat/extras/html/annotated.html new file mode 100644 index 0000000..151eb0e --- /dev/null +++ b/libraries/SdFat/extras/html/annotated.html @@ -0,0 +1,149 @@ + + + + + + +SdFat: Class List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 CArduinoInStreamInput stream for Arduino Stream objects
 CArduinoOutStreamOutput stream for Arduino Print objects
 CBaseBlockDriverBase block driver
 CbiosParmBlockBIOS parameter block
 Ccache_tCache for an raw data block
 CdirectoryEntryFAT short directory entry
 Cfat32_bootBoot sector for a FAT32 volume
 Cfat32_fsinfoFSINFO sector for a FAT32 volume
 Cfat_bootBoot sector for a FAT12/FAT16 volume
 CFatCacheBlock cache
 CFatFileBasic file class
 CFatFileSystemIntegration class for the FatLib library
 CFatPos_tInternal type for file position - do not use in user apps
 CFatStreamBaseBase class for C++ style streams
 CFatVolumeAccess FAT16 and FAT32 volumes on raw file devices
 CFileArduino SD.h style File API
 Cfname_tInternal type for Short File Name - do not use in user apps
 CfstreamFile input/output stream
 CibufstreamParse a char string
 CifstreamFile input stream
 CiosError and state information for all streams
 Cios_baseBase class for all streams
 CiostreamInput/Output stream
 CistreamInput Stream
 ClongDirectoryEntryFAT long directory entry
 CmasterBootRecordMaster Boot Record
 CMinimumSerialMini serial class for the SdFat library
 CobufstreamFormat a char string
 CofstreamFile output stream
 CostreamOutput Stream
 CpartitionTableMBR partition table entry
 CPrintFileFatFile with Print
 CSd2CardRaw access to SD and SDHC card using default SPI library
 CSdBaseFileClass for backward compatibility
 CSdFatMain file system class for SdFat library
 CSdFatEXSdFat class with extended SD I/O
 CSdFatSdioSdFat class using SDIO
 CSdFatSoftSpiSdFat class using software SPI
 CSdFatSoftSpiEXSdFat class using software SPI and extended SD I/O
 CSdFileClass for backward compatibility
 CSdFileSystemVirtual base class for SdFat library
 CSdioCardRaw SDIO access to SD and SDHC flash memory cards
 CSdSpiCardRaw access to SD and SDHC flash memory cards via SPI protocol
 CSdSpiCardEXExtended SD I/O block driver
 CsetfillType for setfill manipulator
 CsetprecisionType for setprecision manipulator
 CsetwType for setw manipulator
 CStdioStreamStdioStream implements a minimal stdio stream
 CSysCallSysCall - Class to wrap system calls
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/arrowdown.png b/libraries/SdFat/extras/html/arrowdown.png new file mode 100644 index 0000000..0b63f6d Binary files /dev/null and b/libraries/SdFat/extras/html/arrowdown.png differ diff --git a/libraries/SdFat/extras/html/arrowright.png b/libraries/SdFat/extras/html/arrowright.png new file mode 100644 index 0000000..c6ee22f Binary files /dev/null and b/libraries/SdFat/extras/html/arrowright.png differ diff --git a/libraries/SdFat/extras/html/bc_s.png b/libraries/SdFat/extras/html/bc_s.png new file mode 100644 index 0000000..224b29a Binary files /dev/null and b/libraries/SdFat/extras/html/bc_s.png differ diff --git a/libraries/SdFat/extras/html/bdwn.png b/libraries/SdFat/extras/html/bdwn.png new file mode 100644 index 0000000..940a0b9 Binary files /dev/null and b/libraries/SdFat/extras/html/bdwn.png differ diff --git a/libraries/SdFat/extras/html/bufstream_8h.html b/libraries/SdFat/extras/html/bufstream_8h.html new file mode 100644 index 0000000..f0daa27 --- /dev/null +++ b/libraries/SdFat/extras/html/bufstream_8h.html @@ -0,0 +1,146 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/bufstream.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
bufstream.h File Reference
+
+
+ +

ibufstream and obufstream classes +More...

+
#include <string.h>
+#include "iostream.h"
+
+Include dependency graph for bufstream.h:
+
+
+ + + + + + + + + + + + + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + +
+
+ + + + + + + +

+Classes

class  ibufstream
 parse a char string More...
 
class  obufstream
 format a char string More...
 
+

Detailed Description

+

ibufstream and obufstream classes

+
+ + + + diff --git a/libraries/SdFat/extras/html/bufstream_8h__dep__incl.png b/libraries/SdFat/extras/html/bufstream_8h__dep__incl.png new file mode 100644 index 0000000..34df032 Binary files /dev/null and b/libraries/SdFat/extras/html/bufstream_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/bufstream_8h__incl.png b/libraries/SdFat/extras/html/bufstream_8h__incl.png new file mode 100644 index 0000000..fa0c87b Binary files /dev/null and b/libraries/SdFat/extras/html/bufstream_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/class_arduino_in_stream-members.html b/libraries/SdFat/extras/html/class_arduino_in_stream-members.html new file mode 100644 index 0000000..d875aad --- /dev/null +++ b/libraries/SdFat/extras/html/class_arduino_in_stream-members.html @@ -0,0 +1,191 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
ArduinoInStream Member List
+
+
+ +

This is the complete list of members for ArduinoInStream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ArduinoInStream(Stream &hws, char *buf, size_t size)ArduinoInStreaminline
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)iosinline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
fmtflags typedefios_base
gcount() const istreaminline
get()istream
get(char &ch)istream
get(char *str, streamsize n, char delim= '\n')istream
getline(char *str, streamsize n, char delim= '\n')istream
good() const iosinline
goodbitios_basestatic
hexios_basestatic
ibufstream()ibufstreaminline
ibufstream(const char *str)ibufstreaminlineexplicit
ignore(streamsize n=1, int delim=-1)istream
inios_basestatic
init(const char *str)ibufstreaminline
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
istream() (defined in istream)istreaminline
leftios_basestatic
octios_basestatic
off_type typedefios_base
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
operator>>(istream &(*pf)(istream &str))istreaminline
operator>>(ios_base &(*pf)(ios_base &str))istreaminline
operator>>(ios &(*pf)(ios &str))istreaminline
operator>>(char *str)istreaminline
operator>>(char &ch)istreaminline
operator>>(signed char *str)istreaminline
operator>>(signed char &ch)istreaminline
operator>>(unsigned char *str)istreaminline
operator>>(unsigned char &ch)istreaminline
operator>>(bool &arg)istreaminline
operator>>(short &arg)istreaminline
operator>>(unsigned short &arg)istreaminline
operator>>(int &arg)istreaminline
operator>>(unsigned int &arg)istreaminline
operator>>(long &arg)istreaminline
operator>>(unsigned long &arg)istreaminline
operator>>(double &arg)istreaminline
operator>>(float &arg)istreaminline
operator>>(void *&arg)istreaminline
outios_basestatic
peek()istream
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
rdstate() const iosinline
readline()ArduinoInStreaminline
rightios_basestatic
seekdir enum nameios_base
seekg(pos_type pos)istreaminline
seekg(off_type off, seekdir way)istreaminline
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipWhite()istream
skipwsios_basestatic
streamsize typedefios_base
tellg()istreaminline
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/class_arduino_in_stream.html b/libraries/SdFat/extras/html/class_arduino_in_stream.html new file mode 100644 index 0000000..9ece872 --- /dev/null +++ b/libraries/SdFat/extras/html/class_arduino_in_stream.html @@ -0,0 +1,2604 @@ + + + + + + +SdFat: ArduinoInStream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
ArduinoInStream Class Reference
+
+
+ +

Input stream for Arduino Stream objects. + More...

+ +

#include <ArduinoStream.h>

+
+Inheritance diagram for ArduinoInStream:
+
+
Inheritance graph
+ + + + + + +
[legend]
+
+Collaboration diagram for ArduinoInStream:
+
+
Collaboration graph
+ + + + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 ArduinoInStream (Stream &hws, char *buf, size_t size)
 
bool bad () const
 
void clear (iostate state=goodbit)
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
streamsize gcount () const
 
int get ()
 
istreamget (char &ch)
 
istreamget (char *str, streamsize n, char delim= '\n')
 
istreamgetline (char *str, streamsize n, char delim= '\n')
 
bool good () const
 
istreamignore (streamsize n=1, int delim=-1)
 
void init (const char *str)
 
 operator const void * () const
 
bool operator! () const
 
istreamoperator>> (istream &(*pf)(istream &str))
 
istreamoperator>> (ios_base &(*pf)(ios_base &str))
 
istreamoperator>> (ios &(*pf)(ios &str))
 
istreamoperator>> (char *str)
 
istreamoperator>> (char &ch)
 
istreamoperator>> (signed char *str)
 
istreamoperator>> (signed char &ch)
 
istreamoperator>> (unsigned char *str)
 
istreamoperator>> (unsigned char &ch)
 
istreamoperator>> (bool &arg)
 
istreamoperator>> (short &arg)
 
istreamoperator>> (unsigned short &arg)
 
istreamoperator>> (int &arg)
 
istreamoperator>> (unsigned int &arg)
 
istreamoperator>> (long &arg)
 
istreamoperator>> (unsigned long &arg)
 
istreamoperator>> (double &arg)
 
istreamoperator>> (float &arg)
 
istreamoperator>> (void *&arg)
 
int peek ()
 
int precision () const
 
int precision (unsigned int n)
 
iostate rdstate () const
 
void readline ()
 
istreamseekg (pos_type pos)
 
istreamseekg (off_type off, seekdir way)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
void skipWhite ()
 
pos_type tellg ()
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+

Detailed Description

+

Input stream for Arduino Stream objects.

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
ArduinoInStream::ArduinoInStream (Stream & hws,
char * buf,
size_t size 
)
+
+inline
+
+

Constructor

Parameters
+ + + + +
[in]hwshardware stream
[in]bufbuffer for input line
[in]sizesize of input buffer
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::clear (iostate state = goodbit)
+
+inlineinherited
+
+

Clear iostate bits.

+
Parameters
+ + +
[in]stateThe flags you want to set after clearing all flags.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
streamsize istream::gcount () const
+
+inlineinherited
+
+
Returns
The number of characters extracted by the last unformatted input function.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int istream::get ()
+
+inherited
+
+

Extract a character if one is available.

+
Returns
The character or -1 if a failure occurs. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream & istream::get (char & ch)
+
+inherited
+
+

Extract a character if one is available.

+
Parameters
+ + +
[out]chlocation to receive the extracted character.
+
+
+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::get (char * str,
streamsize n,
char delim = '\n' 
)
+
+inherited
+
+

Extract characters.

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, n is less than 1, n-1 characters are extracted, or the next character equals delim (delim is not extracted). If no characters are extracted failbit is set. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::getline (char * str,
streamsize n,
char delim = '\n' 
)
+
+inherited
+
+

Extract characters

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, the next character equals delim (delim is extracted), or n-1 characters are extracted.

+

The failbit is set if no characters are extracted or n-1 characters are extracted. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream & istream::ignore (streamsize n = 1,
int delim = -1 
)
+
+inherited
+
+

Extract characters and discard them.

+
Parameters
+ + + +
[in]nmaximum number of characters to ignore.
[in]delimDelimiter.
+
+
+

Characters are extracted until extraction fails, n characters are extracted, or the next input character equals delim (the delimiter is extracted). If end-of-file occurs the eofbit is set.

+

Failures are indicated by the state of the stream.

+
Returns
*this
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ibufstream::init (const char * str)
+
+inlineinherited
+
+

Initialize an ibufstream

Parameters
+ + +
[in]strpointer to string to be parsed Warning: The string will not be copied so must stay in scope.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (istream &(*)(istream &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios_base &(*)(ios_base &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios &(*)(ios &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (bool & arg)
+
+inlineinherited
+
+

Extract a value of type bool.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (short & arg)
+
+inlineinherited
+
+

Extract a value of type short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned short & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (int & arg)
+
+inlineinherited
+
+

Extract a value of type int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned int & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (long & arg)
+
+inlineinherited
+
+

Extract a value of type long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned long & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (double & arg)
+
+inlineinherited
+
+

Extract a value of type double.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (float & arg)
+
+inlineinherited
+
+

Extract a value of type float.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (void *& arg)
+
+inlineinherited
+
+

Extract a value of type void*.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int istream::peek ()
+
+inherited
+
+

Return the next available character without consuming it.

+
Returns
The character if the stream state is good else -1;
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void ArduinoInStream::readline ()
+
+inline
+
+

read a line.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::seekg (pos_type pos)
+
+inlineinherited
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the read pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream& istream::seekg (off_type off,
seekdir way 
)
+
+inlineinherited
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the read pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void istream::skipWhite ()
+
+inherited
+
+

used to implement ws()

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type istream::tellg ()
+
+inlineinherited
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/class_arduino_in_stream__coll__graph.png b/libraries/SdFat/extras/html/class_arduino_in_stream__coll__graph.png new file mode 100644 index 0000000..0d8855b Binary files /dev/null and b/libraries/SdFat/extras/html/class_arduino_in_stream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_arduino_in_stream__inherit__graph.png b/libraries/SdFat/extras/html/class_arduino_in_stream__inherit__graph.png new file mode 100644 index 0000000..0d8855b Binary files /dev/null and b/libraries/SdFat/extras/html/class_arduino_in_stream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_arduino_out_stream-members.html b/libraries/SdFat/extras/html/class_arduino_out_stream-members.html new file mode 100644 index 0000000..e96250f --- /dev/null +++ b/libraries/SdFat/extras/html/class_arduino_out_stream-members.html @@ -0,0 +1,181 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
ArduinoOutStream Member List
+
+
+ +

This is the complete list of members for ArduinoOutStream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ArduinoOutStream(Print &pr)ArduinoOutStreaminlineexplicit
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)iosinline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
flush()ostreaminline
fmtflags typedefios_base
good() const iosinline
goodbitios_basestatic
hexios_basestatic
inios_basestatic
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
leftios_basestatic
octios_basestatic
off_type typedefios_base
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
operator<<(ostream &(*pf)(ostream &str))ostreaminline
operator<<(ios_base &(*pf)(ios_base &str))ostreaminline
operator<<(bool arg)ostreaminline
operator<<(const char *arg)ostreaminline
operator<<(const signed char *arg)ostreaminline
operator<<(const unsigned char *arg)ostreaminline
operator<<(char arg)ostreaminline
operator<<(signed char arg)ostreaminline
operator<<(unsigned char arg)ostreaminline
operator<<(double arg)ostreaminline
operator<<(float arg)ostreaminline
operator<<(short arg)ostreaminline
operator<<(unsigned short arg)ostreaminline
operator<<(int arg)ostreaminline
operator<<(unsigned int arg)ostreaminline
operator<<(long arg)ostreaminline
operator<<(unsigned long arg)ostreaminline
operator<<(const void *arg)ostreaminline
operator<<(const __FlashStringHelper *arg)ostreaminline
ostream() (defined in ostream)ostreaminline
outios_basestatic
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
put(char ch)ostreaminline
rdstate() const iosinline
rightios_basestatic
seekdir enum nameios_base
seekp(pos_type pos)ostreaminline
seekp(off_type off, seekdir way)ostreaminline
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipwsios_basestatic
streamsize typedefios_base
tellp()ostreaminline
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/class_arduino_out_stream.html b/libraries/SdFat/extras/html/class_arduino_out_stream.html new file mode 100644 index 0000000..badb5a3 --- /dev/null +++ b/libraries/SdFat/extras/html/class_arduino_out_stream.html @@ -0,0 +1,2294 @@ + + + + + + +SdFat: ArduinoOutStream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
ArduinoOutStream Class Reference
+
+
+ +

Output stream for Arduino Print objects. + More...

+ +

#include <ArduinoStream.h>

+
+Inheritance diagram for ArduinoOutStream:
+
+
Inheritance graph
+ + + + + +
[legend]
+
+Collaboration diagram for ArduinoOutStream:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 ArduinoOutStream (Print &pr)
 
bool bad () const
 
void clear (iostate state=goodbit)
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
ostreamflush ()
 
bool good () const
 
 operator const void * () const
 
bool operator! () const
 
ostreamoperator<< (ostream &(*pf)(ostream &str))
 
ostreamoperator<< (ios_base &(*pf)(ios_base &str))
 
ostreamoperator<< (bool arg)
 
ostreamoperator<< (const char *arg)
 
ostreamoperator<< (const signed char *arg)
 
ostreamoperator<< (const unsigned char *arg)
 
ostreamoperator<< (char arg)
 
ostreamoperator<< (signed char arg)
 
ostreamoperator<< (unsigned char arg)
 
ostreamoperator<< (double arg)
 
ostreamoperator<< (float arg)
 
ostreamoperator<< (short arg)
 
ostreamoperator<< (unsigned short arg)
 
ostreamoperator<< (int arg)
 
ostreamoperator<< (unsigned int arg)
 
ostreamoperator<< (long arg)
 
ostreamoperator<< (unsigned long arg)
 
ostreamoperator<< (const void *arg)
 
ostreamoperator<< (const __FlashStringHelper *arg)
 
int precision () const
 
int precision (unsigned int n)
 
ostreamput (char ch)
 
iostate rdstate () const
 
ostreamseekp (pos_type pos)
 
ostreamseekp (off_type off, seekdir way)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
pos_type tellp ()
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+

Detailed Description

+

Output stream for Arduino Print objects.

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
ArduinoOutStream::ArduinoOutStream (Print & pr)
+
+inlineexplicit
+
+

constructor

+
Parameters
+ + +
[in]prPrint object for this ArduinoOutStream.
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::clear (iostate state = goodbit)
+
+inlineinherited
+
+

Clear iostate bits.

+
Parameters
+ + +
[in]stateThe flags you want to set after clearing all flags.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ostream& ostream::flush ()
+
+inlineinherited
+
+

Flushes the buffer associated with this stream. The flush function calls the sync function of the associated file.

Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ostream &(*)(ostream &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ios_base &(*)(ios_base &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (bool arg)
+
+inlineinherited
+
+

Output bool

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const signed char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const unsigned char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (signed char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (double arg)
+
+inlineinherited
+
+

Output double

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (float arg)
+
+inlineinherited
+
+

Output float

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (short arg)
+
+inlineinherited
+
+

Output signed short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned short arg)
+
+inlineinherited
+
+

Output unsigned short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (int arg)
+
+inlineinherited
+
+

Output signed int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned int arg)
+
+inlineinherited
+
+

Output unsigned int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (long arg)
+
+inlineinherited
+
+

Output signed long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned long arg)
+
+inlineinherited
+
+

Output unsigned long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const void * arg)
+
+inlineinherited
+
+

Output pointer

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const __FlashStringHelper * arg)
+
+inlineinherited
+
+

Output a string from flash using the Arduino F() macro.

Parameters
+ + +
[in]argpointing to flash string
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::put (char ch)
+
+inlineinherited
+
+

Puts a character in a stream.

+

The unformatted output function inserts the element ch. It returns *this.

+
Parameters
+ + +
[in]chThe character
+
+
+
Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::seekp (pos_type pos)
+
+inlineinherited
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the write pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ostream& ostream::seekp (off_type off,
seekdir way 
)
+
+inlineinherited
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the write pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type ostream::tellp ()
+
+inlineinherited
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/class_arduino_out_stream__coll__graph.png b/libraries/SdFat/extras/html/class_arduino_out_stream__coll__graph.png new file mode 100644 index 0000000..971f052 Binary files /dev/null and b/libraries/SdFat/extras/html/class_arduino_out_stream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_arduino_out_stream__inherit__graph.png b/libraries/SdFat/extras/html/class_arduino_out_stream__inherit__graph.png new file mode 100644 index 0000000..971f052 Binary files /dev/null and b/libraries/SdFat/extras/html/class_arduino_out_stream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_base_block_driver-members.html b/libraries/SdFat/extras/html/class_base_block_driver-members.html new file mode 100644 index 0000000..4c8c079 --- /dev/null +++ b/libraries/SdFat/extras/html/class_base_block_driver-members.html @@ -0,0 +1,104 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
BaseBlockDriver Member List
+
+
+ +

This is the complete list of members for BaseBlockDriver, including all inherited members.

+ + + + + + +
readBlock(uint32_t block, uint8_t *dst)=0BaseBlockDriverpure virtual
readBlocks(uint32_t block, uint8_t *dst, size_t nb)=0BaseBlockDriverpure virtual
syncBlocks()=0BaseBlockDriverpure virtual
writeBlock(uint32_t block, const uint8_t *src)=0BaseBlockDriverpure virtual
writeBlocks(uint32_t block, const uint8_t *src, size_t nb)=0BaseBlockDriverpure virtual
+ + + + diff --git a/libraries/SdFat/extras/html/class_base_block_driver.html b/libraries/SdFat/extras/html/class_base_block_driver.html new file mode 100644 index 0000000..2e54e05 --- /dev/null +++ b/libraries/SdFat/extras/html/class_base_block_driver.html @@ -0,0 +1,352 @@ + + + + + + +SdFat: BaseBlockDriver Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
BaseBlockDriver Class Referenceabstract
+
+
+ +

Base block driver. + More...

+ +

#include <BaseBlockDriver.h>

+
+Inheritance diagram for BaseBlockDriver:
+
+
Inheritance graph
+ + + +
[legend]
+ + + + + + + + + + + + +

+Public Member Functions

virtual bool readBlock (uint32_t block, uint8_t *dst)=0
 
virtual bool readBlocks (uint32_t block, uint8_t *dst, size_t nb)=0
 
virtual bool syncBlocks ()=0
 
virtual bool writeBlock (uint32_t block, const uint8_t *src)=0
 
virtual bool writeBlocks (uint32_t block, const uint8_t *src, size_t nb)=0
 
+

Detailed Description

+

Base block driver.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
virtual bool BaseBlockDriver::readBlock (uint32_t block,
uint8_t * dst 
)
+
+pure virtual
+
+

Read a 512 byte block from an SD card.

+
Parameters
+ + + +
[in]blockLogical block to be read.
[out]dstPointer to the location that will receive the data.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +

Implemented in SdioCard.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
virtual bool BaseBlockDriver::readBlocks (uint32_t block,
uint8_t * dst,
size_t nb 
)
+
+pure virtual
+
+

Read multiple 512 byte blocks from an SD card.

+
Parameters
+ + + + +
[in]blockLogical block to be read.
[in]nbNumber of blocks to be read.
[out]dstPointer to the location that will receive the data.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +

Implemented in SdioCard.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
virtual bool BaseBlockDriver::syncBlocks ()
+
+pure virtual
+
+

End multi-block transfer and go to idle state.

Returns
The value true is returned for success and the value false is returned for failure.
+ +

Implemented in SdioCard.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
virtual bool BaseBlockDriver::writeBlock (uint32_t block,
const uint8_t * src 
)
+
+pure virtual
+
+

Writes a 512 byte block to an SD card.

+
Parameters
+ + + +
[in]blockLogical block to be written.
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +

Implemented in SdioCard.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
virtual bool BaseBlockDriver::writeBlocks (uint32_t block,
const uint8_t * src,
size_t nb 
)
+
+pure virtual
+
+

Write multiple 512 byte blocks to an SD card.

+
Parameters
+ + + + +
[in]blockLogical block to be written.
[in]nbNumber of blocks to be written.
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +

Implemented in SdioCard.

+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/FatLib/BaseBlockDriver.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_base_block_driver__inherit__graph.png b/libraries/SdFat/extras/html/class_base_block_driver__inherit__graph.png new file mode 100644 index 0000000..1a36e51 Binary files /dev/null and b/libraries/SdFat/extras/html/class_base_block_driver__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_fat_cache-members.html b/libraries/SdFat/extras/html/class_fat_cache-members.html new file mode 100644 index 0000000..e9b5f48 --- /dev/null +++ b/libraries/SdFat/extras/html/class_fat_cache-members.html @@ -0,0 +1,113 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
FatCache Member List
+
+
+ +

This is the complete list of members for FatCache, including all inherited members.

+ + + + + + + + + + + + + + + +
block()FatCacheinline
CACHE_FOR_READFatCachestatic
CACHE_FOR_WRITEFatCachestatic
CACHE_OPTION_NO_READFatCachestatic
CACHE_RESERVE_FOR_WRITEFatCachestatic
CACHE_STATUS_DIRTYFatCachestatic
CACHE_STATUS_MASKFatCachestatic
CACHE_STATUS_MIRROR_FATFatCachestatic
dirty()FatCacheinline
init(FatVolume *vol)FatCacheinline
invalidate()FatCacheinline
lbn()FatCacheinline
read(uint32_t lbn, uint8_t option)FatCache
sync()FatCache
+ + + + diff --git a/libraries/SdFat/extras/html/class_fat_cache.html b/libraries/SdFat/extras/html/class_fat_cache.html new file mode 100644 index 0000000..2ba6879 --- /dev/null +++ b/libraries/SdFat/extras/html/class_fat_cache.html @@ -0,0 +1,471 @@ + + + + + + +SdFat: FatCache Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Block cache. + More...

+ +

#include <FatVolume.h>

+ + + + + + + + + + + + + + + + +

+Public Member Functions

cache_tblock ()
 
void dirty ()
 
void init (FatVolume *vol)
 
void invalidate ()
 
uint32_t lbn ()
 
cache_tread (uint32_t lbn, uint8_t option)
 
bool sync ()
 
+ + + + + + + + + + + + + + + +

+Static Public Attributes

static const uint8_t CACHE_FOR_READ = 0
 
static const uint8_t CACHE_FOR_WRITE = CACHE_STATUS_DIRTY
 
static const uint8_t CACHE_OPTION_NO_READ = 4
 
static const uint8_t CACHE_RESERVE_FOR_WRITE = CACHE_STATUS_DIRTY | CACHE_OPTION_NO_READ
 
static const uint8_t CACHE_STATUS_DIRTY = 1
 
static const uint8_t CACHE_STATUS_MASK = CACHE_STATUS_DIRTY | CACHE_STATUS_MIRROR_FAT
 
static const uint8_t CACHE_STATUS_MIRROR_FAT = 2
 
+

Detailed Description

+

Block cache.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
cache_t* FatCache::block ()
+
+inline
+
+
Returns
Cache block address.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatCache::dirty ()
+
+inline
+
+

Set current block dirty.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatCache::init (FatVolumevol)
+
+inline
+
+

Initialize the cache.

Parameters
+ + +
[in]volFatVolume that owns this FatCache.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatCache::invalidate ()
+
+inline
+
+

Invalidate current cache block.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatCache::lbn ()
+
+inline
+
+
Returns
Logical block number for cached block.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
cache_t * FatCache::read (uint32_t lbn,
uint8_t option 
)
+
+

Read a block into the cache.

Parameters
+ + + +
[in]lbnBlock to read.
[in]optionmode for cached block.
+
+
+
Returns
Address of cached block.
+ +
+
+ +
+
+ + + + + + + +
bool FatCache::sync ()
+
+

Write current block if dirty.

Returns
true for success else false.
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const uint8_t FatCache::CACHE_FOR_READ = 0
+
+static
+
+

Cache block for read.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const uint8_t FatCache::CACHE_FOR_WRITE = CACHE_STATUS_DIRTY
+
+static
+
+

Cache block for write.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const uint8_t FatCache::CACHE_OPTION_NO_READ = 4
+
+static
+
+

Sync existing block but do not read new block.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const uint8_t FatCache::CACHE_RESERVE_FOR_WRITE = CACHE_STATUS_DIRTY | CACHE_OPTION_NO_READ
+
+static
+
+

Reserve cache block for write - do not read from block device.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const uint8_t FatCache::CACHE_STATUS_DIRTY = 1
+
+static
+
+

Cached block is dirty

+ +
+
+ +
+
+ + + + + +
+ + + + +
const uint8_t FatCache::CACHE_STATUS_MASK = CACHE_STATUS_DIRTY | CACHE_STATUS_MIRROR_FAT
+
+static
+
+

Cache block status bits

+ +
+
+ +
+
+ + + + + +
+ + + + +
const uint8_t FatCache::CACHE_STATUS_MIRROR_FAT = 2
+
+static
+
+

Cashed block is FAT entry and must be mirrored in second FAT.

+ +
+
+
The documentation for this class was generated from the following files:
    +
  • Arduino/libraries/SdFat/src/FatLib/FatVolume.h
  • +
  • Arduino/libraries/SdFat/src/FatLib/FatVolume.cpp
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_fat_file-members.html b/libraries/SdFat/extras/html/class_fat_file-members.html new file mode 100644 index 0000000..77345d1 --- /dev/null +++ b/libraries/SdFat/extras/html/class_fat_file-members.html @@ -0,0 +1,188 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
FatFile Member List
+
+
+ +

This is the complete list of members for FatFile, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
available()FatFileinline
clearError()FatFileinline
clearWriteError()FatFileinline
close()FatFile
contiguousRange(uint32_t *bgnBlock, uint32_t *endBlock)FatFile
createContiguous(FatFile *dirFile, const char *path, uint32_t size)FatFile
createContiguous(const char *path, uint32_t size)FatFileinline
curCluster() const FatFileinline
curPosition() const FatFileinline
cwd()FatFileinlinestatic
dateTimeCallback(void(*dateTime)(uint16_t *date, uint16_t *time))FatFileinlinestatic
dateTimeCallbackCancel()FatFileinlinestatic
dirEntry(dir_t *dir)FatFile
dirIndex()FatFileinline
dirName(const dir_t *dir, char *name)FatFilestatic
dirSize()FatFile
dmpFile(print_t *pr, uint32_t pos, size_t n)FatFile
exists(const char *path)FatFileinline
FatFile()FatFileinline
FatFile(const char *path, uint8_t oflag)FatFileinline
fgets(char *str, int16_t num, char *delim=0)FatFile
fileAttr() const FatFileinline
fileSize() const FatFileinline
firstBlock()FatFileinline
firstCluster() const FatFileinline
getError()FatFileinline
getName(char *name, size_t size)FatFile
getpos(FatPos_t *pos)FatFile
getSFN(char *name)FatFile
getWriteError()FatFileinline
isDir() const FatFileinline
isFile() const FatFileinline
isHidden() const FatFileinline
isLFN() const FatFileinline
isOpen() const FatFileinline
isReadOnly() const FatFileinline
isRoot() const FatFileinline
isRoot32() const FatFileinline
isRootFixed() const FatFileinline
isSubDir() const FatFileinline
isSystem() const FatFileinline
legal83Char(uint8_t c)FatFileinlinestatic
ls(uint8_t flags=0)FatFileinline
ls(print_t *pr, uint8_t flags=0, uint8_t indent=0)FatFile
mkdir(FatFile *dir, const char *path, bool pFlag=true)FatFile
open(FatFileSystem *fs, const char *path, uint8_t oflag)FatFile
open(FatFile *dirFile, uint16_t index, uint8_t oflag)FatFile
open(FatFile *dirFile, const char *path, uint8_t oflag)FatFile
open(const char *path, uint8_t oflag=O_READ)FatFileinline
openNext(FatFile *dirFile, uint8_t oflag=O_READ)FatFile
openRoot(FatVolume *vol)FatFile
peek()FatFile
printCreateDateTime(print_t *pr)FatFile
printFatDate(uint16_t fatDate)FatFileinlinestatic
printFatDate(print_t *pr, uint16_t fatDate)FatFilestatic
printFatTime(uint16_t fatTime)FatFileinlinestatic
printFatTime(print_t *pr, uint16_t fatTime)FatFilestatic
printField(float value, char term, uint8_t prec=2)FatFile
printField(int16_t value, char term)FatFile
printField(uint16_t value, char term)FatFile
printField(int32_t value, char term)FatFile
printField(uint32_t value, char term)FatFile
printFileSize(print_t *pr)FatFile
printModifyDateTime(print_t *pr)FatFile
printName()FatFileinline
printName(print_t *pr)FatFile
printSFN(print_t *pr)FatFile
read()FatFileinline
read(void *buf, size_t nbyte)FatFile
readDir(dir_t *dir)FatFile
remove()FatFile
remove(FatFile *dirFile, const char *path)FatFilestatic
rename(FatFile *dirFile, const char *newPath)FatFile
rewind()FatFileinline
rmdir()FatFile
rmRfStar()FatFile
seekCur(int32_t offset)FatFileinline
seekEnd(int32_t offset=0)FatFileinline
seekSet(uint32_t pos)FatFile
setCwd(FatFile *dir)FatFileinlinestatic
setpos(FatPos_t *pos)FatFile
sync()FatFile
timestamp(FatFile *file)FatFile
timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)FatFile
truncate(uint32_t length)FatFile
volume() const FatFileinline
write(const char *str)FatFileinline
write(uint8_t b)FatFileinline
write(const void *buf, size_t nbyte)FatFile
+ + + + diff --git a/libraries/SdFat/extras/html/class_fat_file.html b/libraries/SdFat/extras/html/class_fat_file.html new file mode 100644 index 0000000..e9b283f --- /dev/null +++ b/libraries/SdFat/extras/html/class_fat_file.html @@ -0,0 +1,2989 @@ + + + + + + +SdFat: FatFile Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Basic file class. + More...

+ +

#include <FatFile.h>

+
+Inheritance diagram for FatFile:
+
+
Inheritance graph
+ + + + + + + + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

uint32_t available ()
 
void clearError ()
 
void clearWriteError ()
 
bool close ()
 
bool contiguousRange (uint32_t *bgnBlock, uint32_t *endBlock)
 
bool createContiguous (FatFile *dirFile, const char *path, uint32_t size)
 
bool createContiguous (const char *path, uint32_t size)
 
uint32_t curCluster () const
 
uint32_t curPosition () const
 
bool dirEntry (dir_t *dir)
 
uint16_t dirIndex ()
 
uint32_t dirSize ()
 
void dmpFile (print_t *pr, uint32_t pos, size_t n)
 
bool exists (const char *path)
 
 FatFile ()
 
 FatFile (const char *path, uint8_t oflag)
 
int16_t fgets (char *str, int16_t num, char *delim=0)
 
uint8_t fileAttr () const
 
uint32_t fileSize () const
 
uint32_t firstBlock ()
 
uint32_t firstCluster () const
 
uint8_t getError ()
 
bool getName (char *name, size_t size)
 
void getpos (FatPos_t *pos)
 
bool getSFN (char *name)
 
bool getWriteError ()
 
bool isDir () const
 
bool isFile () const
 
bool isHidden () const
 
bool isLFN () const
 
bool isOpen () const
 
bool isReadOnly () const
 
bool isRoot () const
 
bool isRoot32 () const
 
bool isRootFixed () const
 
bool isSubDir () const
 
bool isSystem () const
 
void ls (uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0, uint8_t indent=0)
 
bool mkdir (FatFile *dir, const char *path, bool pFlag=true)
 
bool open (FatFileSystem *fs, const char *path, uint8_t oflag)
 
bool open (FatFile *dirFile, uint16_t index, uint8_t oflag)
 
bool open (FatFile *dirFile, const char *path, uint8_t oflag)
 
bool open (const char *path, uint8_t oflag=O_READ)
 
bool openNext (FatFile *dirFile, uint8_t oflag=O_READ)
 
bool openRoot (FatVolume *vol)
 
int peek ()
 
bool printCreateDateTime (print_t *pr)
 
int printField (float value, char term, uint8_t prec=2)
 
int printField (int16_t value, char term)
 
int printField (uint16_t value, char term)
 
int printField (int32_t value, char term)
 
int printField (uint32_t value, char term)
 
size_t printFileSize (print_t *pr)
 
bool printModifyDateTime (print_t *pr)
 
size_t printName ()
 
size_t printName (print_t *pr)
 
size_t printSFN (print_t *pr)
 
int read ()
 
int read (void *buf, size_t nbyte)
 
int8_t readDir (dir_t *dir)
 
bool remove ()
 
bool rename (FatFile *dirFile, const char *newPath)
 
void rewind ()
 
bool rmdir ()
 
bool rmRfStar ()
 
bool seekCur (int32_t offset)
 
bool seekEnd (int32_t offset=0)
 
bool seekSet (uint32_t pos)
 
void setpos (FatPos_t *pos)
 
bool sync ()
 
bool timestamp (FatFile *file)
 
bool timestamp (uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
 
bool truncate (uint32_t length)
 
FatVolumevolume () const
 
int write (const char *str)
 
int write (uint8_t b)
 
int write (const void *buf, size_t nbyte)
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static FatFilecwd ()
 
static void dateTimeCallback (void(*dateTime)(uint16_t *date, uint16_t *time))
 
static void dateTimeCallbackCancel ()
 
static uint8_t dirName (const dir_t *dir, char *name)
 
static bool legal83Char (uint8_t c)
 
static void printFatDate (uint16_t fatDate)
 
static void printFatDate (print_t *pr, uint16_t fatDate)
 
static void printFatTime (uint16_t fatTime)
 
static void printFatTime (print_t *pr, uint16_t fatTime)
 
static bool remove (FatFile *dirFile, const char *path)
 
static bool setCwd (FatFile *dir)
 
+

Detailed Description

+

Basic file class.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
FatFile::FatFile ()
+
+inline
+
+

Create an instance.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
FatFile::FatFile (const char * path,
uint8_t oflag 
)
+
+inline
+
+

Create a file object and open it in the current working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagValues for oflag are constructed by a bitwise-inclusive OR of open flags. see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::available ()
+
+inline
+
+
Returns
The number of bytes available from the current position to EOF for normal files. Zero is returned for directory files.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::clearError ()
+
+inline
+
+

Clear all error bits.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::clearWriteError ()
+
+inline
+
+

Set writeError to zero

+ +
+
+ +
+
+ + + + + + + +
bool FatFile::close ()
+
+

Close a file and force cached data and directory information to be written to the storage device.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool FatFile::contiguousRange (uint32_t * bgnBlock,
uint32_t * endBlock 
)
+
+

Check for contiguous file and return its raw block range.

+
Parameters
+ + + +
[out]bgnBlockthe first block address for the file.
[out]endBlockthe last block address for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::createContiguous (FatFiledirFile,
const char * path,
uint32_t size 
)
+
+

Create and open a new contiguous file of a specified size.

+
Parameters
+ + + + +
[in]dirFileThe directory where the file will be created.
[in]pathA path with a validfile name.
[in]sizeThe desired file size.
+
+
+
Returns
The value true is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::createContiguous (const char * path,
uint32_t size 
)
+
+inline
+
+

Create and open a new contiguous file of a specified size.

+
Parameters
+ + + +
[in]pathA path with a validfile name.
[in]sizeThe desired file size.
+
+
+
Returns
The value true is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::curCluster () const
+
+inline
+
+
Returns
The current cluster number for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::curPosition () const
+
+inline
+
+
Returns
The current position for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static FatFile* FatFile::cwd ()
+
+inlinestatic
+
+
Returns
Current working directory
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::dateTimeCallback (void(*)(uint16_t *date, uint16_t *time) dateTime)
+
+inlinestatic
+
+

Set the date/time callback function

+
Parameters
+ + +
[in]dateTimeThe user's call back function. The callback function is of the form:
+
+
+
void dateTime(uint16_t* date, uint16_t* time) {
+
uint16_t year;
+
uint8_t month, day, hour, minute, second;
+
+
// User gets date and time from GPS or real-time clock here
+
+
// return date using FAT_DATE macro to format fields
+
*date = FAT_DATE(year, month, day);
+
+
// return time using FAT_TIME macro to format fields
+
*time = FAT_TIME(hour, minute, second);
+
}
+

Sets the function that is called when a file is created or when a file's directory entry is modified by sync(). All timestamps, access, creation, and modify, are set when a file is created. sync() maintains the last access date and last modify date/time.

+

See the timestamp() function.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static void FatFile::dateTimeCallbackCancel ()
+
+inlinestatic
+
+

Cancel the date/time callback function.

+ +
+
+ +
+
+ + + + + + + + +
bool FatFile::dirEntry (dir_tdir)
+
+

Return a file's directory entry.

+
Parameters
+ + +
[out]dirLocation for return of the file's directory entry.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatFile::dirIndex ()
+
+inline
+
+
Returns
The index of this file in it's directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t FatFile::dirName (const dir_tdir,
char * name 
)
+
+static
+
+

Format the name field of dir into the 13 byte array name in standard 8.3 short name format.

+
Parameters
+ + + +
[in]dirThe directory structure containing the name.
[out]nameA 13 byte char array for the formatted name.
+
+
+
Returns
length of the name.
+ +
+
+ +
+
+ + + + + + + +
uint32_t FatFile::dirSize ()
+
+
Returns
The number of bytes allocated to a directory or zero if an error occurs.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFile::dmpFile (print_tpr,
uint32_t pos,
size_t n 
)
+
+

Dump file in Hex

Parameters
+ + + + +
[in]prPrint stream for list.
[in]posStart position in file.
[in]nnumber of locations to dump.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::exists (const char * path)
+
+inline
+
+

Test for the existence of a file in a directory

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+

The calling instance must be an open directory file.

+

dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory dirFile.

+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int16_t FatFile::fgets (char * str,
int16_t num,
char * delim = 0 
)
+
+

Get a string from a file.

+

fgets() reads bytes from a file into the array pointed to by str, until num - 1 bytes are read, or a delimiter is read and transferred to str, or end-of-file is encountered. The string is then terminated with a null byte.

+

fgets() deletes CR, '\r', from the string. This insures only a '\n' terminates the string for Windows text files which use CRLF for newline.

+
Parameters
+ + + + +
[out]strPointer to the array where the string is stored.
[in]numMaximum number of characters to be read (including the final null byte). Usually the length of the array str is used.
[in]delimOptional set of delimiters. The default is "\n".
+
+
+
Returns
For success fgets() returns the length of the string in str. If no data is read, fgets() returns zero for EOF or -1 if an error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatFile::fileAttr () const
+
+inline
+
+

Type of file. You should use isFile() or isDir() instead of fileType() if possible.

+
Returns
The file or directory type.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::fileSize () const
+
+inline
+
+
Returns
The total number of bytes in a file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::firstBlock ()
+
+inline
+
+
Returns
first block of file or zero for empty file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::firstCluster () const
+
+inline
+
+
Returns
The first cluster number for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatFile::getError ()
+
+inline
+
+
Returns
All error bits.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool FatFile::getName (char * name,
size_t size 
)
+
+

Get a file's name followed by a zero byte.

+
Parameters
+ + + +
[out]nameAn array of characters for the file's name.
[in]sizeThe size of the array in bytes. The array must be at least 13 bytes long. The file's name will be truncated if the file's name is too long.
+
+
+
Returns
The value true, is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
void FatFile::getpos (FatPos_tpos)
+
+

get position for streams

Parameters
+ + +
[out]posstruct to receive position
+
+
+ +
+
+ +
+
+ + + + + + + + +
bool FatFile::getSFN (char * name)
+
+

Get a file's Short File Name followed by a zero byte.

+
Parameters
+ + +
[out]nameAn array of characters for the file's name. The array must be at least 13 bytes long.
+
+
+
Returns
The value true, is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::getWriteError ()
+
+inline
+
+
Returns
value of writeError
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isDir () const
+
+inline
+
+
Returns
True if this is a directory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isFile () const
+
+inline
+
+
Returns
True if this is a normal file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isHidden () const
+
+inline
+
+
Returns
True if this is a hidden file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isLFN () const
+
+inline
+
+
Returns
true if this file has a Long File Name.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isOpen () const
+
+inline
+
+
Returns
True if this is an open file/directory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isReadOnly () const
+
+inline
+
+
Returns
True if file is read-only
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRoot () const
+
+inline
+
+
Returns
True if this is the root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRoot32 () const
+
+inline
+
+
Returns
True if this is the FAT32 root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRootFixed () const
+
+inline
+
+
Returns
True if this is the FAT12 of FAT16 root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isSubDir () const
+
+inline
+
+
Returns
True if this is a subdirectory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isSystem () const
+
+inline
+
+
Returns
True if this is a system file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static bool FatFile::legal83Char (uint8_t c)
+
+inlinestatic
+
+

Check for a legal 8.3 character.

Parameters
+ + +
[in]cCharacter to be checked.
+
+
+
Returns
true for a legal 8.3 character else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::ls (uint8_t flags = 0)
+
+inline
+
+

List directory contents.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFile::ls (print_tpr,
uint8_t flags = 0,
uint8_t indent = 0 
)
+
+

List directory contents.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+
Parameters
+ + +
[in]indentAmount of space before file name. Used for recursive list to indicate subdirectory level.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::mkdir (FatFiledir,
const char * path,
bool pFlag = true 
)
+
+

Make a new directory.

+
Parameters
+ + + + +
[in]dirAn open FatFile instance for the directory that will contain the new directory.
[in]pathA path with a valid 8.3 DOS name for the new directory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFileSystemfs,
const char * path,
uint8_t oflag 
)
+
+

Open a file in the volume working directory of a FatFileSystem.

+
Parameters
+ + + + +
[in]fsFile System where the file is located.
[in]pathwith a valid 8.3 DOS name for a file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFiledirFile,
uint16_t index,
uint8_t oflag 
)
+
+

Open a file by index.

+
Parameters
+ + + + +
[in]dirFileAn open FatFile instance for the directory.
[in]indexThe index of the directory entry for the file to be opened. The value for index is (directory file position)/32.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+

See open() by path for definition of flags.

Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFiledirFile,
const char * path,
uint8_t oflag 
)
+
+

Open a file or directory by name.

+
Parameters
+ + + + +
[in]dirFileAn open FatFile instance for the directory containing the file to be opened.
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagValues for oflag are constructed by a bitwise-inclusive OR of flags from the following list
+
+
+

O_READ - Open for reading.

+

O_RDONLY - Same as O_READ.

+

O_WRITE - Open for writing.

+

O_WRONLY - Same as O_WRITE.

+

O_RDWR - Open for reading and writing.

+

O_APPEND - If set, the file offset shall be set to the end of the file prior to each write.

+

O_AT_END - Set the initial position at the end of the file.

+

O_CREAT - If the file exists, this flag has no effect except as noted under O_EXCL below. Otherwise, the file shall be created

+

O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.

+

O_SYNC - Call sync() after each write. This flag should not be used with write(uint8_t) or any functions do character at a time writes since sync() will be called after each byte.

+

O_TRUNC - If the file exists and is a regular file, and the file is successfully opened and is not read only, its length shall be truncated to 0.

+

WARNING: A given file must not be opened by more than one FatFile object or file corruption may occur.

+
Note
Directory files must be opened read only. Write and truncation is not allowed for directory files.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::open (const char * path,
uint8_t oflag = O_READ 
)
+
+inline
+
+

Open a file in the current working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool FatFile::openNext (FatFiledirFile,
uint8_t oflag = O_READ 
)
+
+

Open the next file or subdirectory in a directory.

+
Parameters
+ + + +
[in]dirFileAn open FatFile instance for the directory containing the file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool FatFile::openRoot (FatVolumevol)
+
+

Open a volume's root directory.

+
Parameters
+ + +
[in]volThe FAT volume containing the root directory to be opened.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + +
int FatFile::peek ()
+
+

Return the next available byte without consuming it.

+
Returns
The byte if no error and not at eof else -1;
+ +
+
+ +
+
+ + + + + + + + +
bool FatFile::printCreateDateTime (print_tpr)
+
+

Print a file's creation date and time

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::printFatDate (uint16_t fatDate)
+
+inlinestatic
+
+

Print a directory date field.

+

Format is yyyy-mm-dd.

+
Parameters
+ + +
[in]fatDateThe date field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFile::printFatDate (print_tpr,
uint16_t fatDate 
)
+
+static
+
+

Print a directory date field.

+

Format is yyyy-mm-dd.

+
Parameters
+ + + +
[in]prPrint stream for output.
[in]fatDateThe date field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::printFatTime (uint16_t fatTime)
+
+inlinestatic
+
+

Print a directory time field.

+

Format is hh:mm:ss.

+
Parameters
+ + +
[in]fatTimeThe time field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFile::printFatTime (print_tpr,
uint16_t fatTime 
)
+
+static
+
+

Print a directory time field.

+

Format is hh:mm:ss.

+
Parameters
+ + + +
[in]prPrint stream for output.
[in]fatTimeThe time field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int FatFile::printField (float value,
char term,
uint8_t prec = 2 
)
+
+

Print a number followed by a field terminator.

Parameters
+ + + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
[in]precNumber of digits after decimal point.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (int16_t value,
char term 
)
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (uint16_t value,
char term 
)
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (int32_t value,
char term 
)
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (uint32_t value,
char term 
)
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + +
size_t FatFile::printFileSize (print_tpr)
+
+

Print a file's size.

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The number of characters printed is returned for success and zero is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool FatFile::printModifyDateTime (print_tpr)
+
+

Print a file's modify date and time

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t FatFile::printName ()
+
+inline
+
+

Print a file's name.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
size_t FatFile::printName (print_tpr)
+
+

Print a file's name

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
size_t FatFile::printSFN (print_tpr)
+
+

Print a file's Short File Name.

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The number of characters printed is returned for success and zero is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int FatFile::read ()
+
+inline
+
+

Read the next byte from a file.

+
Returns
For success read returns the next byte in the file as an int. If an error occurs or end of file is reached -1 is returned.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int FatFile::read (void * buf,
size_t nbyte 
)
+
+

Read data from a file starting at the current position.

+
Parameters
+ + + +
[out]bufPointer to the location that will receive the data.
[in]nbyteMaximum number of bytes to read.
+
+
+
Returns
For success read() returns the number of bytes read. A value less than nbyte, including zero, will be returned if end of file is reached. If an error occurs, read() returns -1. Possible errors include read() called before a file has been opened, corrupt file system or an I/O error occurred.
+ +
+
+ +
+
+ + + + + + + + +
int8_t FatFile::readDir (dir_tdir)
+
+

Read the next directory entry from a directory file.

+
Parameters
+ + +
[out]dirThe dir_t struct that will receive the data.
+
+
+
Returns
For success readDir() returns the number of bytes read. A value of zero will be returned if end of file is reached. If an error occurs, readDir() returns -1. Possible errors include readDir() called before a directory has been opened, this is not a directory file or an I/O error occurred.
+ +
+
+ +
+
+ + + + + + + +
bool FatFile::remove ()
+
+

Remove a file.

+

The directory entry and all data for the file are deleted.

+
Note
This function should not be used to delete the 8.3 version of a file that has a long name. For example if a file has the long name "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::remove (FatFiledirFile,
const char * path 
)
+
+static
+
+

Remove a file.

+

The directory entry and all data for the file are deleted.

+
Parameters
+ + + +
[in]dirFileThe directory that contains the file.
[in]pathPath for the file to be removed.
+
+
+
Note
This function should not be used to delete the 8.3 version of a file that has a long name. For example if a file has the long name "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool FatFile::rename (FatFiledirFile,
const char * newPath 
)
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]dirFileDirectory for the new path.
[in]newPathNew path name for the file/directory.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::rewind ()
+
+inline
+
+

Set the file's current position to zero.

+ +
+
+ +
+
+ + + + + + + +
bool FatFile::rmdir ()
+
+

Remove a directory file.

+

The directory file will be removed only if it is empty and is not the root directory. rmdir() follows DOS and Windows and ignores the read-only attribute for the directory.

+
Note
This function should not be used to delete the 8.3 version of a directory that has a long name. For example if a directory has the long name "New folder" you should not delete the 8.3 name "NEWFOL~1".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + +
bool FatFile::rmRfStar ()
+
+

Recursively delete a directory and all contained files.

+

This is like the Unix/Linux 'rm -rf *' if called with the root directory hence the name.

+

Warning - This will remove all contents of the directory including subdirectories. The directory will then be removed if it is not root. The read-only attribute for files will be ignored.

+
Note
This function should not be used to delete the 8.3 version of a directory that has a long name. See remove() and rmdir().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekCur (int32_t offset)
+
+inline
+
+

Set the files position to current position + pos. See seekSet().

Parameters
+ + +
[in]offsetThe new position in bytes from the current position.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekEnd (int32_t offset = 0)
+
+inline
+
+

Set the files position to end-of-file + offset. See seekSet(). Can't be used for directory files since file size is not defined.

Parameters
+ + +
[in]offsetThe new position in bytes from end-of-file.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool FatFile::seekSet (uint32_t pos)
+
+

Sets a file's position.

+
Parameters
+ + +
[in]posThe new position in bytes from the beginning of the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static bool FatFile::setCwd (FatFiledir)
+
+inlinestatic
+
+

Set the current working directory.

+
Parameters
+ + +
[in]dirNew current working directory.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + + + + +
void FatFile::setpos (FatPos_tpos)
+
+

set position for streams

Parameters
+ + +
[out]posstruct with value for new position
+
+
+ +
+
+ +
+
+ + + + + + + +
bool FatFile::sync ()
+
+

The sync() call causes all modified data and directory fields to be written to the storage device.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool FatFile::timestamp (FatFilefile)
+
+

Copy a file's timestamps

+
Parameters
+ + +
[in]fileFile to copy timestamps from.
+
+
+
Note
Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::timestamp (uint8_t flags,
uint16_t year,
uint8_t month,
uint8_t day,
uint8_t hour,
uint8_t minute,
uint8_t second 
)
+
+

Set a file's timestamps in its directory entry.

+
Parameters
+ + +
[in]flagsValues for flags are constructed by a bitwise-inclusive OR of flags from the following list
+
+
+

T_ACCESS - Set the file's last access date.

+

T_CREATE - Set the file's creation date and time.

+

T_WRITE - Set the file's last write/modification date and time.

+
Parameters
+ + + + + + + +
[in]yearValid range 1980 - 2107 inclusive.
[in]monthValid range 1 - 12 inclusive.
[in]dayValid range 1 - 31 inclusive.
[in]hourValid range 0 - 23 inclusive.
[in]minuteValid range 0 - 59 inclusive.
[in]secondValid range 0 - 59 inclusive
+
+
+
Note
It is possible to set an invalid date since there is no check for the number of days in a month.
+
+Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool FatFile::truncate (uint32_t length)
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + +
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFile::volume () const
+
+inline
+
+
Returns
FatVolume that contains this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int FatFile::write (const char * str)
+
+inline
+
+

Write a string to a file. Used by the Arduino Print class.

Parameters
+ + +
[in]strPointer to the string. Use getWriteError to check for errors.
+
+
+
Returns
count of characters written for success or -1 for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int FatFile::write (uint8_t b)
+
+inline
+
+

Write a single byte.

Parameters
+ + +
[in]bThe byte to be written.
+
+
+
Returns
+1 for success or -1 for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int FatFile::write (const void * buf,
size_t nbyte 
)
+
+

Write data to an open file.

+
Note
Data is moved to the cache but may not be written to the storage device until sync() is called.
+
Parameters
+ + + +
[in]bufPointer to the location of the data to be written.
[in]nbyteNumber of bytes to write.
+
+
+
Returns
For success write() returns the number of bytes written, always nbyte. If an error occurs, write() returns -1. Possible errors include write() is called before a file has been opened, write is called for a read-only file, device is full, a corrupt file system or an I/O error.
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • Arduino/libraries/SdFat/src/FatLib/FatFile.h
  • +
  • Arduino/libraries/SdFat/src/FatLib/FatFile.cpp
  • +
  • Arduino/libraries/SdFat/src/FatLib/FatFileLFN.cpp
  • +
  • Arduino/libraries/SdFat/src/FatLib/FatFilePrint.cpp
  • +
  • Arduino/libraries/SdFat/src/FatLib/FatFileSFN.cpp
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_fat_file__inherit__graph.png b/libraries/SdFat/extras/html/class_fat_file__inherit__graph.png new file mode 100644 index 0000000..6e13b3c Binary files /dev/null and b/libraries/SdFat/extras/html/class_fat_file__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_fat_file_system-members.html b/libraries/SdFat/extras/html/class_fat_file_system-members.html new file mode 100644 index 0000000..dae8a2e --- /dev/null +++ b/libraries/SdFat/extras/html/class_fat_file_system-members.html @@ -0,0 +1,135 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
FatFileSystem Member List
+
+
+ +

This is the complete list of members for FatFileSystem, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin(BlockDriver *blockDev, uint8_t part=0)FatFileSysteminline
blocksPerCluster() const FatVolumeinline
blocksPerFat() const FatVolumeinline
cacheClear()FatVolumeinline
chdir(bool set_cwd=false)FatFileSysteminline
chdir(const char *path, bool set_cwd=false)FatFileSysteminline
chvol()FatFileSysteminline
clusterCount() const FatVolumeinline
clusterSizeShift() const FatVolumeinline
dataStartBlock() const FatVolumeinline
dbgFat(uint32_t n, uint32_t *v)FatVolumeinline
exists(const char *path)FatFileSysteminline
fatCount()FatVolumeinline
fatStartBlock() const FatVolumeinline
fatType() const FatVolumeinline
FatVolume()FatVolumeinline
freeClusterCount()FatVolume
init()FatVolumeinline
init(uint8_t part)FatVolume
ls(uint8_t flags=0)FatFileSysteminline
ls(const char *path, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, const char *path, uint8_t flags)FatFileSysteminline
mkdir(const char *path, bool pFlag=true)FatFileSysteminline
open(const char *path, uint8_t mode=FILE_READ)FatFileSysteminline
open(const String &path, uint8_t mode=FILE_READ)FatFileSysteminline
remove(const char *path)FatFileSysteminline
rename(const char *oldPath, const char *newPath)FatFileSysteminline
rmdir(const char *path)FatFileSysteminline
rootDirEntryCount() const FatVolumeinline
rootDirStart() const FatVolumeinline
truncate(const char *path, uint32_t length)FatFileSysteminline
vol()FatFileSysteminline
volumeBlockCount() const FatVolumeinline
vwd()FatFileSysteminline
wipe(print_t *pr=0)FatFileSysteminline
+ + + + diff --git a/libraries/SdFat/extras/html/class_fat_file_system.html b/libraries/SdFat/extras/html/class_fat_file_system.html new file mode 100644 index 0000000..ac0b556 --- /dev/null +++ b/libraries/SdFat/extras/html/class_fat_file_system.html @@ -0,0 +1,1339 @@ + + + + + + +SdFat: FatFileSystem Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
FatFileSystem Class Reference
+
+
+ +

Integration class for the FatLib library. + More...

+ +

#include <FatFileSystem.h>

+
+Inheritance diagram for FatFileSystem:
+
+
Inheritance graph
+ + + + + + + + + + + + +
[legend]
+
+Collaboration diagram for FatFileSystem:
+
+
Collaboration graph
+ + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin (BlockDriver *blockDev, uint8_t part=0)
 
uint8_t blocksPerCluster () const
 
uint32_t blocksPerFat () const
 
cache_tcacheClear ()
 
bool chdir (bool set_cwd=false)
 
bool chdir (const char *path, bool set_cwd=false)
 
void chvol ()
 
uint32_t clusterCount () const
 
uint8_t clusterSizeShift () const
 
uint32_t dataStartBlock () const
 
int8_t dbgFat (uint32_t n, uint32_t *v)
 
bool exists (const char *path)
 
uint8_t fatCount ()
 
uint32_t fatStartBlock () const
 
uint8_t fatType () const
 
int32_t freeClusterCount ()
 
bool init ()
 
bool init (uint8_t part)
 
void ls (uint8_t flags=0)
 
void ls (const char *path, uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0)
 
void ls (print_t *pr, const char *path, uint8_t flags)
 
bool mkdir (const char *path, bool pFlag=true)
 
File open (const char *path, uint8_t mode=FILE_READ)
 
File open (const String &path, uint8_t mode=FILE_READ)
 
bool remove (const char *path)
 
bool rename (const char *oldPath, const char *newPath)
 
bool rmdir (const char *path)
 
uint16_t rootDirEntryCount () const
 
uint32_t rootDirStart () const
 
bool truncate (const char *path, uint32_t length)
 
FatVolumevol ()
 
uint32_t volumeBlockCount () const
 
FatFilevwd ()
 
bool wipe (print_t *pr=0)
 
+

Detailed Description

+

Integration class for the FatLib library.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::begin (BlockDriverblockDev,
uint8_t part = 0 
)
+
+inline
+
+

Initialize an FatFileSystem object.

Parameters
+ + + +
[in]blockDevDevice block driver.
[in]partpartition to initialize.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::blocksPerCluster () const
+
+inlineinherited
+
+
Returns
The volume's cluster size in blocks.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::blocksPerFat () const
+
+inlineinherited
+
+
Returns
The number of blocks in one FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
cache_t* FatVolume::cacheClear ()
+
+inlineinherited
+
+

Clear the cache and returns a pointer to the cache. Not for normal apps.

Returns
A pointer to the cache buffer or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::chdir (bool set_cwd = false)
+
+inline
+
+

Change a volume's working directory to root

+

Changes the volume's working directory to the SD's root directory. Optionally set the current working directory to the volume's working directory.

+
Parameters
+ + +
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::chdir (const char * path,
bool set_cwd = false 
)
+
+inline
+
+

Change a volume's working directory

+

Changes the volume working directory to the path subdirectory. Optionally set the current working directory to the volume's working directory.

+

Example: If the volume's working directory is "/DIR", chdir("SUB") will change the volume's working directory from "/DIR" to "/DIR/SUB".

+

If path is "/", the volume's working directory will be changed to the root directory

+
Parameters
+ + + +
[in]pathThe name of the subdirectory.
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFileSystem::chvol ()
+
+inline
+
+

Set the current working directory to a volume's working directory.

+

This is useful with multiple SD cards.

+

The current working directory is changed to this volume's working directory.

+

This is like the Windows/DOS <drive letter>: command.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::clusterCount () const
+
+inlineinherited
+
+
Returns
The total number of clusters in the volume.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::clusterSizeShift () const
+
+inlineinherited
+
+
Returns
The shift count required to multiply by blocksPerCluster.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::dataStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of file data.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int8_t FatVolume::dbgFat (uint32_t n,
uint32_t * v 
)
+
+inlineinherited
+
+

Debug access to FAT table

+
Parameters
+ + + +
[in]ncluster number.
[out]vvalue of entry
+
+
+
Returns
true for success or false for failure
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::exists (const char * path)
+
+inline
+
+

Test for the existence of a file.

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatCount ()
+
+inlineinherited
+
+
Returns
The number of File Allocation Tables.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::fatStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the first FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatType () const
+
+inlineinherited
+
+
Returns
The FAT type of the volume. Values are 12, 16 or 32.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int32_t FatVolume::freeClusterCount ()
+
+inherited
+
+

Volume free space in clusters.

+
Returns
Count of free clusters for success or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatVolume::init ()
+
+inlineinherited
+
+

Initialize a FAT volume. Try partition one first then try super floppy format.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatVolume::init (uint8_t part)
+
+inherited
+
+

Initialize a FAT volume.

+
Parameters
+ + +
[in]partThe partition to be used. Legal values for part are 1-4 to use the corresponding partition on a device formatted with a MBR, Master Boot Record, or zero if the device is formatted as a super floppy with the FAT boot sector in block zero.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFileSystem::ls (uint8_t flags = 0)
+
+inline
+
+

List the directory contents of the volume working directory to Serial.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (const char * path,
uint8_t flags = 0 
)
+
+inline
+
+

List the directory contents of a directory to Serial.

+
Parameters
+ + + +
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
uint8_t flags = 0 
)
+
+inline
+
+

List the directory contents of the volume working directory.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
const char * path,
uint8_t flags 
)
+
+inline
+
+

List the directory contents of a directory.

+
Parameters
+ + + + +
[in]prPrint stream for list.
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::mkdir (const char * path,
bool pFlag = true 
)
+
+inline
+
+

Make a subdirectory in the volume working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const char * path,
uint8_t mode = FILE_READ 
)
+
+inline
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const String & path,
uint8_t mode = FILE_READ 
)
+
+inline
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::remove (const char * path)
+
+inline
+
+

Remove a file from the volume working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::rename (const char * oldPath,
const char * newPath 
)
+
+inline
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]oldPathPath name to the file or subdirectory to be renamed.
[in]newPathNew path name of the file or subdirectory.
+
+
+

The newPath object must not exist before the rename call.

+

The file to be renamed must not be open. The directory entry may be moved and file system corruption could occur if the file is accessed by a file object that was opened before the rename() call.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::rmdir (const char * path)
+
+inline
+
+

Remove a subdirectory from the volume's working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
+
+
+

The subdirectory file will be removed only if it is empty.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatVolume::rootDirEntryCount () const
+
+inlineinherited
+
+
Returns
The number of entries in the root directory for FAT16 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::rootDirStart () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the root directory on FAT16 volumes or the first cluster number on FAT32 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::truncate (const char * path,
uint32_t length 
)
+
+inline
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the file.
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFileSystem::vol ()
+
+inline
+
+
Returns
a pointer to the FatVolume object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::volumeBlockCount () const
+
+inlineinherited
+
+
Returns
The number of blocks in the volume
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatFile* FatFileSystem::vwd ()
+
+inline
+
+
Returns
a pointer to the volume working directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::wipe (print_tpr = 0)
+
+inline
+
+

Wipe all data from the volume. You must reinitialize the volume before accessing it again.

Parameters
+ + +
[in]prprint stream for status dots.
+
+
+
Returns
true for success else false.
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/class_fat_file_system__coll__graph.png b/libraries/SdFat/extras/html/class_fat_file_system__coll__graph.png new file mode 100644 index 0000000..dcaf8f8 Binary files /dev/null and b/libraries/SdFat/extras/html/class_fat_file_system__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_fat_file_system__inherit__graph.png b/libraries/SdFat/extras/html/class_fat_file_system__inherit__graph.png new file mode 100644 index 0000000..cbe4c17 Binary files /dev/null and b/libraries/SdFat/extras/html/class_fat_file_system__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_fat_stream_base-members.html b/libraries/SdFat/extras/html/class_fat_stream_base-members.html new file mode 100644 index 0000000..45cc445 --- /dev/null +++ b/libraries/SdFat/extras/html/class_fat_stream_base-members.html @@ -0,0 +1,244 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
FatStreamBase Member List
+
+
+ +

This is the complete list of members for FatStreamBase, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
available()FatFileinlineprivate
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)iosinline
clearError()FatFileinlineprivate
clearWriteError()FatFileinlineprivate
close()FatFileprivate
contiguousRange(uint32_t *bgnBlock, uint32_t *endBlock)FatFileprivate
createContiguous(FatFile *dirFile, const char *path, uint32_t size)FatFileprivate
createContiguous(const char *path, uint32_t size)FatFileinlineprivate
cur enum valueios_base
curCluster() const FatFileinlineprivate
curPosition() const FatFileinlineprivate
cwd()FatFileinlineprivatestatic
dateTimeCallback(void(*dateTime)(uint16_t *date, uint16_t *time))FatFileinlineprivatestatic
dateTimeCallbackCancel()FatFileinlineprivatestatic
decios_basestatic
dirEntry(dir_t *dir)FatFileprivate
dirIndex()FatFileinlineprivate
dirName(const dir_t *dir, char *name)FatFileprivatestatic
dirSize()FatFileprivate
dmpFile(print_t *pr, uint32_t pos, size_t n)FatFileprivate
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
exists(const char *path)FatFileinlineprivate
fail() const iosinline
failbitios_basestatic
FatFile()FatFileinlineprivate
FatFile(const char *path, uint8_t oflag)FatFileinlineprivate
fgets(char *str, int16_t num, char *delim=0)FatFileprivate
fileAttr() const FatFileinlineprivate
fileSize() const FatFileinlineprivate
fill()ios_baseinline
fill(char c)ios_baseinline
firstBlock()FatFileinlineprivate
firstCluster() const FatFileinlineprivate
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
fmtflags typedefios_base
getError()FatFileinlineprivate
getName(char *name, size_t size)FatFileprivate
getpos(FatPos_t *pos)FatFileprivate
getSFN(char *name)FatFileprivate
getWriteError()FatFileinlineprivate
good() const iosinline
goodbitios_basestatic
hexios_basestatic
inios_basestatic
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
isDir() const FatFileinlineprivate
isFile() const FatFileinlineprivate
isHidden() const FatFileinlineprivate
isLFN() const FatFileinlineprivate
isOpen() const FatFileinlineprivate
isReadOnly() const FatFileinlineprivate
isRoot() const FatFileinlineprivate
isRoot32() const FatFileinlineprivate
isRootFixed() const FatFileinlineprivate
isSubDir() const FatFileinlineprivate
isSystem() const FatFileinlineprivate
leftios_basestatic
legal83Char(uint8_t c)FatFileinlineprivatestatic
ls(uint8_t flags=0)FatFileinlineprivate
ls(print_t *pr, uint8_t flags=0, uint8_t indent=0)FatFileprivate
mkdir(FatFile *dir, const char *path, bool pFlag=true)FatFileprivate
octios_basestatic
off_type typedefios_base
open(FatFileSystem *fs, const char *path, uint8_t oflag)FatFileprivate
open(FatFile *dirFile, uint16_t index, uint8_t oflag)FatFileprivate
open(FatFile *dirFile, const char *path, uint8_t oflag)FatFileprivate
open(const char *path, uint8_t oflag=O_READ)FatFileinlineprivate
openmode typedefios_base
openNext(FatFile *dirFile, uint8_t oflag=O_READ)FatFileprivate
openRoot(FatVolume *vol)FatFileprivate
operator const void *() const iosinline
operator!() const iosinline
outios_basestatic
peek()FatFileprivate
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
printCreateDateTime(print_t *pr)FatFileprivate
printFatDate(uint16_t fatDate)FatFileinlineprivatestatic
printFatDate(print_t *pr, uint16_t fatDate)FatFileprivatestatic
printFatTime(uint16_t fatTime)FatFileinlineprivatestatic
printFatTime(print_t *pr, uint16_t fatTime)FatFileprivatestatic
printField(float value, char term, uint8_t prec=2)FatFileprivate
printField(int16_t value, char term)FatFileprivate
printField(uint16_t value, char term)FatFileprivate
printField(int32_t value, char term)FatFileprivate
printField(uint32_t value, char term)FatFileprivate
printFileSize(print_t *pr)FatFileprivate
printModifyDateTime(print_t *pr)FatFileprivate
printName()FatFileinlineprivate
printName(print_t *pr)FatFileprivate
printSFN(print_t *pr)FatFileprivate
rdstate() const iosinline
read()FatFileinlineprivate
read(void *buf, size_t nbyte)FatFileprivate
readDir(dir_t *dir)FatFileprivate
remove()FatFileprivate
remove(FatFile *dirFile, const char *path)FatFileprivatestatic
rename(FatFile *dirFile, const char *newPath)FatFileprivate
rewind()FatFileinlineprivate
rightios_basestatic
rmdir()FatFileprivate
rmRfStar()FatFileprivate
seekCur(int32_t offset)FatFileinlineprivate
seekdir enum nameios_base
seekEnd(int32_t offset=0)FatFileinlineprivate
seekSet(uint32_t pos)FatFileprivate
setCwd(FatFile *dir)FatFileinlineprivatestatic
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setpos(FatPos_t *pos)FatFileprivate
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipwsios_basestatic
streamsize typedefios_base
sync()FatFileprivate
timestamp(FatFile *file)FatFileprivate
timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)FatFileprivate
truncios_basestatic
truncate(uint32_t length)FatFileprivate
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
volume() const FatFileinlineprivate
width()ios_baseinline
width(unsigned n)ios_baseinline
write(const char *str)FatFileinlineprivate
write(uint8_t b)FatFileinlineprivate
write(const void *buf, size_t nbyte)FatFileprivate
+ + + + diff --git a/libraries/SdFat/extras/html/class_fat_stream_base.html b/libraries/SdFat/extras/html/class_fat_stream_base.html new file mode 100644 index 0000000..7fcc666 --- /dev/null +++ b/libraries/SdFat/extras/html/class_fat_stream_base.html @@ -0,0 +1,1653 @@ + + + + + + +SdFat: FatStreamBase Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Base class for C++ style streams. + More...

+ +

#include <fstream.h>

+
+Inheritance diagram for FatStreamBase:
+
+
Inheritance graph
+ + + + + + + + +
[legend]
+
+Collaboration diagram for FatStreamBase:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool bad () const
 
void clear (iostate state=goodbit)
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
bool good () const
 
 operator const void * () const
 
bool operator! () const
 
int precision () const
 
int precision (unsigned int n)
 
iostate rdstate () const
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

uint32_t available ()
 
void clearError ()
 
void clearWriteError ()
 
bool close ()
 
bool contiguousRange (uint32_t *bgnBlock, uint32_t *endBlock)
 
bool createContiguous (FatFile *dirFile, const char *path, uint32_t size)
 
bool createContiguous (const char *path, uint32_t size)
 
uint32_t curCluster () const
 
uint32_t curPosition () const
 
bool dirEntry (dir_t *dir)
 
uint16_t dirIndex ()
 
uint32_t dirSize ()
 
void dmpFile (print_t *pr, uint32_t pos, size_t n)
 
bool exists (const char *path)
 
int16_t fgets (char *str, int16_t num, char *delim=0)
 
uint8_t fileAttr () const
 
uint32_t fileSize () const
 
uint32_t firstBlock ()
 
uint32_t firstCluster () const
 
uint8_t getError ()
 
bool getName (char *name, size_t size)
 
void getpos (FatPos_t *pos)
 
bool getSFN (char *name)
 
bool getWriteError ()
 
bool isDir () const
 
bool isFile () const
 
bool isHidden () const
 
bool isLFN () const
 
bool isOpen () const
 
bool isReadOnly () const
 
bool isRoot () const
 
bool isRoot32 () const
 
bool isRootFixed () const
 
bool isSubDir () const
 
bool isSystem () const
 
void ls (uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0, uint8_t indent=0)
 
bool mkdir (FatFile *dir, const char *path, bool pFlag=true)
 
bool open (FatFileSystem *fs, const char *path, uint8_t oflag)
 
bool open (FatFile *dirFile, uint16_t index, uint8_t oflag)
 
bool open (FatFile *dirFile, const char *path, uint8_t oflag)
 
bool open (const char *path, uint8_t oflag=O_READ)
 
bool openNext (FatFile *dirFile, uint8_t oflag=O_READ)
 
bool openRoot (FatVolume *vol)
 
int peek ()
 
bool printCreateDateTime (print_t *pr)
 
int printField (float value, char term, uint8_t prec=2)
 
int printField (int16_t value, char term)
 
int printField (uint16_t value, char term)
 
int printField (int32_t value, char term)
 
int printField (uint32_t value, char term)
 
size_t printFileSize (print_t *pr)
 
bool printModifyDateTime (print_t *pr)
 
size_t printName ()
 
size_t printName (print_t *pr)
 
size_t printSFN (print_t *pr)
 
int read ()
 
int read (void *buf, size_t nbyte)
 
int8_t readDir (dir_t *dir)
 
bool remove ()
 
bool rename (FatFile *dirFile, const char *newPath)
 
void rewind ()
 
bool rmdir ()
 
bool rmRfStar ()
 
bool seekCur (int32_t offset)
 
bool seekEnd (int32_t offset=0)
 
bool seekSet (uint32_t pos)
 
void setpos (FatPos_t *pos)
 
bool sync ()
 
bool timestamp (FatFile *file)
 
bool timestamp (uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
 
bool truncate (uint32_t length)
 
FatVolumevolume () const
 
int write (const char *str)
 
int write (uint8_t b)
 
int write (const void *buf, size_t nbyte)
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Static Private Member Functions

static FatFilecwd ()
 
static void dateTimeCallback (void(*dateTime)(uint16_t *date, uint16_t *time))
 
static void dateTimeCallbackCancel ()
 
static uint8_t dirName (const dir_t *dir, char *name)
 
static bool legal83Char (uint8_t c)
 
static void printFatDate (uint16_t fatDate)
 
static void printFatDate (print_t *pr, uint16_t fatDate)
 
static void printFatTime (uint16_t fatTime)
 
static void printFatTime (print_t *pr, uint16_t fatTime)
 
static bool remove (FatFile *dirFile, const char *path)
 
static bool setCwd (FatFile *dir)
 
+

Detailed Description

+

Base class for C++ style streams.

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::clear (iostate state = goodbit)
+
+inlineinherited
+
+

Clear iostate bits.

+
Parameters
+ + +
[in]stateThe flags you want to set after clearing all flags.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/FatLib/fstream.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_fat_stream_base__coll__graph.png b/libraries/SdFat/extras/html/class_fat_stream_base__coll__graph.png new file mode 100644 index 0000000..4b13c43 Binary files /dev/null and b/libraries/SdFat/extras/html/class_fat_stream_base__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_fat_stream_base__inherit__graph.png b/libraries/SdFat/extras/html/class_fat_stream_base__inherit__graph.png new file mode 100644 index 0000000..08e0c93 Binary files /dev/null and b/libraries/SdFat/extras/html/class_fat_stream_base__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_fat_volume-members.html b/libraries/SdFat/extras/html/class_fat_volume-members.html new file mode 100644 index 0000000..543d224 --- /dev/null +++ b/libraries/SdFat/extras/html/class_fat_volume-members.html @@ -0,0 +1,120 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
FatVolume Member List
+
+
+ +

This is the complete list of members for FatVolume, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + +
blocksPerCluster() const FatVolumeinline
blocksPerFat() const FatVolumeinline
cacheClear()FatVolumeinline
clusterCount() const FatVolumeinline
clusterSizeShift() const FatVolumeinline
dataStartBlock() const FatVolumeinline
dbgFat(uint32_t n, uint32_t *v)FatVolumeinline
FatCache (defined in FatVolume)FatVolumefriend
fatCount()FatVolumeinline
FatFile (defined in FatVolume)FatVolumefriend
FatFileSystem (defined in FatVolume)FatVolumefriend
fatStartBlock() const FatVolumeinline
fatType() const FatVolumeinline
FatVolume()FatVolumeinline
freeClusterCount()FatVolume
init()FatVolumeinline
init(uint8_t part)FatVolume
rootDirEntryCount() const FatVolumeinline
rootDirStart() const FatVolumeinline
volumeBlockCount() const FatVolumeinline
wipe(print_t *pr=0)FatVolume
+ + + + diff --git a/libraries/SdFat/extras/html/class_fat_volume.html b/libraries/SdFat/extras/html/class_fat_volume.html new file mode 100644 index 0000000..d7a8a99 --- /dev/null +++ b/libraries/SdFat/extras/html/class_fat_volume.html @@ -0,0 +1,626 @@ + + + + + + +SdFat: FatVolume Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
FatVolume Class Reference
+
+
+ +

Access FAT16 and FAT32 volumes on raw file devices. + More...

+ +

#include <FatVolume.h>

+
+Inheritance diagram for FatVolume:
+
+
Inheritance graph
+ + + + + + + + + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

uint8_t blocksPerCluster () const
 
uint32_t blocksPerFat () const
 
cache_tcacheClear ()
 
uint32_t clusterCount () const
 
uint8_t clusterSizeShift () const
 
uint32_t dataStartBlock () const
 
int8_t dbgFat (uint32_t n, uint32_t *v)
 
uint8_t fatCount ()
 
uint32_t fatStartBlock () const
 
uint8_t fatType () const
 
 FatVolume ()
 
int32_t freeClusterCount ()
 
bool init ()
 
bool init (uint8_t part)
 
uint16_t rootDirEntryCount () const
 
uint32_t rootDirStart () const
 
uint32_t volumeBlockCount () const
 
bool wipe (print_t *pr=0)
 
+ + + + + + + +

+Friends

+class FatCache
 
+class FatFile
 
+class FatFileSystem
 
+

Detailed Description

+

Access FAT16 and FAT32 volumes on raw file devices.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
FatVolume::FatVolume ()
+
+inline
+
+

Create an instance of FatVolume

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::blocksPerCluster () const
+
+inline
+
+
Returns
The volume's cluster size in blocks.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::blocksPerFat () const
+
+inline
+
+
Returns
The number of blocks in one FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
cache_t* FatVolume::cacheClear ()
+
+inline
+
+

Clear the cache and returns a pointer to the cache. Not for normal apps.

Returns
A pointer to the cache buffer or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::clusterCount () const
+
+inline
+
+
Returns
The total number of clusters in the volume.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::clusterSizeShift () const
+
+inline
+
+
Returns
The shift count required to multiply by blocksPerCluster.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::dataStartBlock () const
+
+inline
+
+
Returns
The logical block number for the start of file data.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int8_t FatVolume::dbgFat (uint32_t n,
uint32_t * v 
)
+
+inline
+
+

Debug access to FAT table

+
Parameters
+ + + +
[in]ncluster number.
[out]vvalue of entry
+
+
+
Returns
true for success or false for failure
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatCount ()
+
+inline
+
+
Returns
The number of File Allocation Tables.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::fatStartBlock () const
+
+inline
+
+
Returns
The logical block number for the start of the first FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatType () const
+
+inline
+
+
Returns
The FAT type of the volume. Values are 12, 16 or 32.
+ +
+
+ +
+
+ + + + + + + +
int32_t FatVolume::freeClusterCount ()
+
+

Volume free space in clusters.

+
Returns
Count of free clusters for success or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatVolume::init ()
+
+inline
+
+

Initialize a FAT volume. Try partition one first then try super floppy format.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool FatVolume::init (uint8_t part)
+
+

Initialize a FAT volume.

+
Parameters
+ + +
[in]partThe partition to be used. Legal values for part are 1-4 to use the corresponding partition on a device formatted with a MBR, Master Boot Record, or zero if the device is formatted as a super floppy with the FAT boot sector in block zero.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatVolume::rootDirEntryCount () const
+
+inline
+
+
Returns
The number of entries in the root directory for FAT16 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::rootDirStart () const
+
+inline
+
+
Returns
The logical block number for the start of the root directory on FAT16 volumes or the first cluster number on FAT32 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::volumeBlockCount () const
+
+inline
+
+
Returns
The number of blocks in the volume
+ +
+
+ +
+
+ + + + + + + + +
bool FatVolume::wipe (print_tpr = 0)
+
+

Wipe all data from the volume.

Parameters
+ + +
[in]prprint stream for status dots.
+
+
+
Returns
true for success else false.
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • Arduino/libraries/SdFat/src/FatLib/FatVolume.h
  • +
  • Arduino/libraries/SdFat/src/FatLib/FatVolume.cpp
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_fat_volume__inherit__graph.png b/libraries/SdFat/extras/html/class_fat_volume__inherit__graph.png new file mode 100644 index 0000000..7773a79 Binary files /dev/null and b/libraries/SdFat/extras/html/class_fat_volume__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_file-members.html b/libraries/SdFat/extras/html/class_file-members.html new file mode 100644 index 0000000..113bcf6 --- /dev/null +++ b/libraries/SdFat/extras/html/class_file-members.html @@ -0,0 +1,200 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
File Member List
+
+
+ +

This is the complete list of members for File, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
available()Fileinline
clearError()FatFileinline
clearWriteError()FatFileinline
close()FatFile
contiguousRange(uint32_t *bgnBlock, uint32_t *endBlock)FatFile
createContiguous(FatFile *dirFile, const char *path, uint32_t size)FatFile
createContiguous(const char *path, uint32_t size)FatFileinline
curCluster() const FatFileinline
curPosition() const FatFileinline
cwd()FatFileinlinestatic
dateTimeCallback(void(*dateTime)(uint16_t *date, uint16_t *time))FatFileinlinestatic
dateTimeCallbackCancel()FatFileinlinestatic
dirEntry(dir_t *dir)FatFile
dirIndex()FatFileinline
dirName(const dir_t *dir, char *name)FatFilestatic
dirSize()FatFile
dmpFile(print_t *pr, uint32_t pos, size_t n)FatFile
exists(const char *path)FatFileinline
FatFile()FatFileinline
FatFile(const char *path, uint8_t oflag)FatFileinline
fgets(char *str, int16_t num, char *delim=0)FatFile
File() (defined in File)Fileinline
File(const char *path, uint8_t oflag)Fileinline
fileAttr() const FatFileinline
fileSize() const FatFileinline
firstBlock()FatFileinline
firstCluster() const FatFileinline
flush()Fileinline
getError()FatFileinline
getName(char *name, size_t size)FatFile
getpos(FatPos_t *pos)FatFile
getSFN(char *name)FatFile
getWriteError()FatFileinline
isDir() const FatFileinline
isDirectory()Fileinline
isFile() const FatFileinline
isHidden() const FatFileinline
isLFN() const FatFileinline
isOpen() const FatFileinline
isReadOnly() const FatFileinline
isRoot() const FatFileinline
isRoot32() const FatFileinline
isRootFixed() const FatFileinline
isSubDir() const FatFileinline
isSystem() const FatFileinline
legal83Char(uint8_t c)FatFileinlinestatic
ls(uint8_t flags=0)FatFileinline
ls(print_t *pr, uint8_t flags=0, uint8_t indent=0)FatFile
mkdir(FatFile *dir, const char *path, bool pFlag=true)FatFile
name() const Fileinline
open(FatFileSystem *fs, const char *path, uint8_t oflag)FatFile
open(FatFile *dirFile, uint16_t index, uint8_t oflag)FatFile
open(FatFile *dirFile, const char *path, uint8_t oflag)FatFile
open(const char *path, uint8_t oflag=O_READ)FatFileinline
openNext(FatFile *dirFile, uint8_t oflag=O_READ)FatFile
openNextFile(uint8_t mode=O_READ)Fileinline
openRoot(FatVolume *vol)FatFile
operator bool()Fileinline
peek()Fileinline
position()Fileinline
printCreateDateTime(print_t *pr)FatFile
printFatDate(uint16_t fatDate)FatFileinlinestatic
printFatDate(print_t *pr, uint16_t fatDate)FatFilestatic
printFatTime(uint16_t fatTime)FatFileinlinestatic
printFatTime(print_t *pr, uint16_t fatTime)FatFilestatic
printField(float value, char term, uint8_t prec=2)FatFile
printField(int16_t value, char term)FatFile
printField(uint16_t value, char term)FatFile
printField(int32_t value, char term)FatFile
printField(uint32_t value, char term)FatFile
printFileSize(print_t *pr)FatFile
printModifyDateTime(print_t *pr)FatFile
printName()FatFileinline
printName(print_t *pr)FatFile
printSFN(print_t *pr)FatFile
read()Fileinline
FatFile::read(void *buf, size_t nbyte)FatFile
readDir(dir_t *dir)FatFile
remove()FatFile
remove(FatFile *dirFile, const char *path)FatFilestatic
rename(FatFile *dirFile, const char *newPath)FatFile
rewind()FatFileinline
rewindDirectory()Fileinline
rmdir()FatFile
rmRfStar()FatFile
seek(uint32_t pos)Fileinline
seekCur(int32_t offset)FatFileinline
seekEnd(int32_t offset=0)FatFileinline
seekSet(uint32_t pos)FatFile
setCwd(FatFile *dir)FatFileinlinestatic
setpos(FatPos_t *pos)FatFile
size()Fileinline
sync()FatFile
timestamp(FatFile *file)FatFile
timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)FatFile
truncate(uint32_t length)FatFile
volume() const FatFileinline
write(uint8_t b)Fileinline
write(const uint8_t *buf, size_t size)Fileinline
FatFile::write(const char *str)FatFileinline
FatFile::write(const void *buf, size_t nbyte)FatFile
+ + + + diff --git a/libraries/SdFat/extras/html/class_file.html b/libraries/SdFat/extras/html/class_file.html new file mode 100644 index 0000000..5e32727 --- /dev/null +++ b/libraries/SdFat/extras/html/class_file.html @@ -0,0 +1,3585 @@ + + + + + + +SdFat: File Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Arduino SD.h style File API. + More...

+ +

#include <ArduinoFiles.h>

+
+Inheritance diagram for File:
+
+
Inheritance graph
+ + + +
[legend]
+
+Collaboration diagram for File:
+
+
Collaboration graph
+ + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

int available ()
 
void clearError ()
 
void clearWriteError ()
 
bool close ()
 
bool contiguousRange (uint32_t *bgnBlock, uint32_t *endBlock)
 
bool createContiguous (FatFile *dirFile, const char *path, uint32_t size)
 
bool createContiguous (const char *path, uint32_t size)
 
uint32_t curCluster () const
 
uint32_t curPosition () const
 
bool dirEntry (dir_t *dir)
 
uint16_t dirIndex ()
 
uint32_t dirSize ()
 
void dmpFile (print_t *pr, uint32_t pos, size_t n)
 
bool exists (const char *path)
 
int16_t fgets (char *str, int16_t num, char *delim=0)
 
 File (const char *path, uint8_t oflag)
 
uint8_t fileAttr () const
 
uint32_t fileSize () const
 
uint32_t firstBlock ()
 
uint32_t firstCluster () const
 
void flush ()
 
uint8_t getError ()
 
bool getName (char *name, size_t size)
 
void getpos (FatPos_t *pos)
 
bool getSFN (char *name)
 
bool getWriteError ()
 
bool isDir () const
 
bool isDirectory ()
 
bool isFile () const
 
bool isHidden () const
 
bool isLFN () const
 
bool isOpen () const
 
bool isReadOnly () const
 
bool isRoot () const
 
bool isRoot32 () const
 
bool isRootFixed () const
 
bool isSubDir () const
 
bool isSystem () const
 
void ls (uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0, uint8_t indent=0)
 
bool mkdir (FatFile *dir, const char *path, bool pFlag=true)
 
const char * name () const
 
bool open (FatFileSystem *fs, const char *path, uint8_t oflag)
 
bool open (FatFile *dirFile, uint16_t index, uint8_t oflag)
 
bool open (FatFile *dirFile, const char *path, uint8_t oflag)
 
bool open (const char *path, uint8_t oflag=O_READ)
 
bool openNext (FatFile *dirFile, uint8_t oflag=O_READ)
 
File openNextFile (uint8_t mode=O_READ)
 
bool openRoot (FatVolume *vol)
 
 operator bool ()
 
int peek ()
 
uint32_t position ()
 
bool printCreateDateTime (print_t *pr)
 
int printField (float value, char term, uint8_t prec=2)
 
int printField (int16_t value, char term)
 
int printField (uint16_t value, char term)
 
int printField (int32_t value, char term)
 
int printField (uint32_t value, char term)
 
size_t printFileSize (print_t *pr)
 
bool printModifyDateTime (print_t *pr)
 
size_t printName ()
 
size_t printName (print_t *pr)
 
size_t printSFN (print_t *pr)
 
int read ()
 
int read (void *buf, size_t nbyte)
 
int8_t readDir (dir_t *dir)
 
bool remove ()
 
bool rename (FatFile *dirFile, const char *newPath)
 
void rewind ()
 
void rewindDirectory ()
 
bool rmdir ()
 
bool rmRfStar ()
 
bool seek (uint32_t pos)
 
bool seekCur (int32_t offset)
 
bool seekEnd (int32_t offset=0)
 
bool seekSet (uint32_t pos)
 
void setpos (FatPos_t *pos)
 
uint32_t size ()
 
bool sync ()
 
bool timestamp (FatFile *file)
 
bool timestamp (uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
 
bool truncate (uint32_t length)
 
FatVolumevolume () const
 
size_t write (uint8_t b)
 
size_t write (const uint8_t *buf, size_t size)
 
int write (const char *str)
 
int write (const void *buf, size_t nbyte)
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static FatFilecwd ()
 
static void dateTimeCallback (void(*dateTime)(uint16_t *date, uint16_t *time))
 
static void dateTimeCallbackCancel ()
 
static uint8_t dirName (const dir_t *dir, char *name)
 
static bool legal83Char (uint8_t c)
 
static void printFatDate (uint16_t fatDate)
 
static void printFatDate (print_t *pr, uint16_t fatDate)
 
static void printFatTime (uint16_t fatTime)
 
static void printFatTime (print_t *pr, uint16_t fatTime)
 
static bool remove (FatFile *dirFile, const char *path)
 
static bool setCwd (FatFile *dir)
 
+

Detailed Description

+

Arduino SD.h style File API.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File::File (const char * path,
uint8_t oflag 
)
+
+inline
+
+

Create a file object and open it in the current working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagValues for oflag are constructed by a bitwise-inclusive OR of open flags. see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
int File::available ()
+
+inline
+
+
Returns
number of bytes available from the current position to EOF or INT_MAX if more than INT_MAX bytes are available.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::clearError ()
+
+inlineinherited
+
+

Clear all error bits.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::clearWriteError ()
+
+inlineinherited
+
+

Set writeError to zero

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::close ()
+
+inherited
+
+

Close a file and force cached data and directory information to be written to the storage device.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::contiguousRange (uint32_t * bgnBlock,
uint32_t * endBlock 
)
+
+inherited
+
+

Check for contiguous file and return its raw block range.

+
Parameters
+ + + +
[out]bgnBlockthe first block address for the file.
[out]endBlockthe last block address for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::createContiguous (FatFiledirFile,
const char * path,
uint32_t size 
)
+
+inherited
+
+

Create and open a new contiguous file of a specified size.

+
Parameters
+ + + + +
[in]dirFileThe directory where the file will be created.
[in]pathA path with a validfile name.
[in]sizeThe desired file size.
+
+
+
Returns
The value true is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::createContiguous (const char * path,
uint32_t size 
)
+
+inlineinherited
+
+

Create and open a new contiguous file of a specified size.

+
Parameters
+ + + +
[in]pathA path with a validfile name.
[in]sizeThe desired file size.
+
+
+
Returns
The value true is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::curCluster () const
+
+inlineinherited
+
+
Returns
The current cluster number for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::curPosition () const
+
+inlineinherited
+
+
Returns
The current position for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static FatFile* FatFile::cwd ()
+
+inlinestaticinherited
+
+
Returns
Current working directory
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::dateTimeCallback (void(*)(uint16_t *date, uint16_t *time) dateTime)
+
+inlinestaticinherited
+
+

Set the date/time callback function

+
Parameters
+ + +
[in]dateTimeThe user's call back function. The callback function is of the form:
+
+
+
void dateTime(uint16_t* date, uint16_t* time) {
+
uint16_t year;
+
uint8_t month, day, hour, minute, second;
+
+
// User gets date and time from GPS or real-time clock here
+
+
// return date using FAT_DATE macro to format fields
+
*date = FAT_DATE(year, month, day);
+
+
// return time using FAT_TIME macro to format fields
+
*time = FAT_TIME(hour, minute, second);
+
}
+

Sets the function that is called when a file is created or when a file's directory entry is modified by sync(). All timestamps, access, creation, and modify, are set when a file is created. sync() maintains the last access date and last modify date/time.

+

See the timestamp() function.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static void FatFile::dateTimeCallbackCancel ()
+
+inlinestaticinherited
+
+

Cancel the date/time callback function.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::dirEntry (dir_tdir)
+
+inherited
+
+

Return a file's directory entry.

+
Parameters
+ + +
[out]dirLocation for return of the file's directory entry.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatFile::dirIndex ()
+
+inlineinherited
+
+
Returns
The index of this file in it's directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t FatFile::dirName (const dir_tdir,
char * name 
)
+
+staticinherited
+
+

Format the name field of dir into the 13 byte array name in standard 8.3 short name format.

+
Parameters
+ + + +
[in]dirThe directory structure containing the name.
[out]nameA 13 byte char array for the formatted name.
+
+
+
Returns
length of the name.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::dirSize ()
+
+inherited
+
+
Returns
The number of bytes allocated to a directory or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFile::dmpFile (print_tpr,
uint32_t pos,
size_t n 
)
+
+inherited
+
+

Dump file in Hex

Parameters
+ + + + +
[in]prPrint stream for list.
[in]posStart position in file.
[in]nnumber of locations to dump.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::exists (const char * path)
+
+inlineinherited
+
+

Test for the existence of a file in a directory

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+

The calling instance must be an open directory file.

+

dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory dirFile.

+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
int16_t FatFile::fgets (char * str,
int16_t num,
char * delim = 0 
)
+
+inherited
+
+

Get a string from a file.

+

fgets() reads bytes from a file into the array pointed to by str, until num - 1 bytes are read, or a delimiter is read and transferred to str, or end-of-file is encountered. The string is then terminated with a null byte.

+

fgets() deletes CR, '\r', from the string. This insures only a '\n' terminates the string for Windows text files which use CRLF for newline.

+
Parameters
+ + + + +
[out]strPointer to the array where the string is stored.
[in]numMaximum number of characters to be read (including the final null byte). Usually the length of the array str is used.
[in]delimOptional set of delimiters. The default is "\n".
+
+
+
Returns
For success fgets() returns the length of the string in str. If no data is read, fgets() returns zero for EOF or -1 if an error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatFile::fileAttr () const
+
+inlineinherited
+
+

Type of file. You should use isFile() or isDir() instead of fileType() if possible.

+
Returns
The file or directory type.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::fileSize () const
+
+inlineinherited
+
+
Returns
The total number of bytes in a file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::firstBlock ()
+
+inlineinherited
+
+
Returns
first block of file or zero for empty file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::firstCluster () const
+
+inlineinherited
+
+
Returns
The first cluster number for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void File::flush ()
+
+inline
+
+

Ensure that any bytes written to the file are saved to the SD card.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatFile::getError ()
+
+inlineinherited
+
+
Returns
All error bits.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::getName (char * name,
size_t size 
)
+
+inherited
+
+

Get a file's name followed by a zero byte.

+
Parameters
+ + + +
[out]nameAn array of characters for the file's name.
[in]sizeThe size of the array in bytes. The array must be at least 13 bytes long. The file's name will be truncated if the file's name is too long.
+
+
+
Returns
The value true, is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::getpos (FatPos_tpos)
+
+inherited
+
+

get position for streams

Parameters
+ + +
[out]posstruct to receive position
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::getSFN (char * name)
+
+inherited
+
+

Get a file's Short File Name followed by a zero byte.

+
Parameters
+ + +
[out]nameAn array of characters for the file's name. The array must be at least 13 bytes long.
+
+
+
Returns
The value true, is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::getWriteError ()
+
+inlineinherited
+
+
Returns
value of writeError
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isDir () const
+
+inlineinherited
+
+
Returns
True if this is a directory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool File::isDirectory ()
+
+inline
+
+

This function reports if the current file is a directory or not.

Returns
true if the file is a directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isFile () const
+
+inlineinherited
+
+
Returns
True if this is a normal file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isHidden () const
+
+inlineinherited
+
+
Returns
True if this is a hidden file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isLFN () const
+
+inlineinherited
+
+
Returns
true if this file has a Long File Name.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isOpen () const
+
+inlineinherited
+
+
Returns
True if this is an open file/directory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isReadOnly () const
+
+inlineinherited
+
+
Returns
True if file is read-only
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRoot () const
+
+inlineinherited
+
+
Returns
True if this is the root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRoot32 () const
+
+inlineinherited
+
+
Returns
True if this is the FAT32 root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRootFixed () const
+
+inlineinherited
+
+
Returns
True if this is the FAT12 of FAT16 root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isSubDir () const
+
+inlineinherited
+
+
Returns
True if this is a subdirectory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isSystem () const
+
+inlineinherited
+
+
Returns
True if this is a system file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static bool FatFile::legal83Char (uint8_t c)
+
+inlinestaticinherited
+
+

Check for a legal 8.3 character.

Parameters
+ + +
[in]cCharacter to be checked.
+
+
+
Returns
true for a legal 8.3 character else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::ls (uint8_t flags = 0)
+
+inlineinherited
+
+

List directory contents.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFile::ls (print_tpr,
uint8_t flags = 0,
uint8_t indent = 0 
)
+
+inherited
+
+

List directory contents.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+
Parameters
+ + +
[in]indentAmount of space before file name. Used for recursive list to indicate subdirectory level.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::mkdir (FatFiledir,
const char * path,
bool pFlag = true 
)
+
+inherited
+
+

Make a new directory.

+
Parameters
+ + + + +
[in]dirAn open FatFile instance for the directory that will contain the new directory.
[in]pathA path with a valid 8.3 DOS name for the new directory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const char* File::name () const
+
+inline
+
+

No longer implemented due to Long File Names.

+

Use getName(char* name, size_t size).

Returns
a pointer to replacement suggestion.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFileSystemfs,
const char * path,
uint8_t oflag 
)
+
+inherited
+
+

Open a file in the volume working directory of a FatFileSystem.

+
Parameters
+ + + + +
[in]fsFile System where the file is located.
[in]pathwith a valid 8.3 DOS name for a file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFiledirFile,
uint16_t index,
uint8_t oflag 
)
+
+inherited
+
+

Open a file by index.

+
Parameters
+ + + + +
[in]dirFileAn open FatFile instance for the directory.
[in]indexThe index of the directory entry for the file to be opened. The value for index is (directory file position)/32.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+

See open() by path for definition of flags.

Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFiledirFile,
const char * path,
uint8_t oflag 
)
+
+inherited
+
+

Open a file or directory by name.

+
Parameters
+ + + + +
[in]dirFileAn open FatFile instance for the directory containing the file to be opened.
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagValues for oflag are constructed by a bitwise-inclusive OR of flags from the following list
+
+
+

O_READ - Open for reading.

+

O_RDONLY - Same as O_READ.

+

O_WRITE - Open for writing.

+

O_WRONLY - Same as O_WRITE.

+

O_RDWR - Open for reading and writing.

+

O_APPEND - If set, the file offset shall be set to the end of the file prior to each write.

+

O_AT_END - Set the initial position at the end of the file.

+

O_CREAT - If the file exists, this flag has no effect except as noted under O_EXCL below. Otherwise, the file shall be created

+

O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.

+

O_SYNC - Call sync() after each write. This flag should not be used with write(uint8_t) or any functions do character at a time writes since sync() will be called after each byte.

+

O_TRUNC - If the file exists and is a regular file, and the file is successfully opened and is not read only, its length shall be truncated to 0.

+

WARNING: A given file must not be opened by more than one FatFile object or file corruption may occur.

+
Note
Directory files must be opened read only. Write and truncation is not allowed for directory files.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::open (const char * path,
uint8_t oflag = O_READ 
)
+
+inlineinherited
+
+

Open a file in the current working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::openNext (FatFiledirFile,
uint8_t oflag = O_READ 
)
+
+inherited
+
+

Open the next file or subdirectory in a directory.

+
Parameters
+ + + +
[in]dirFileAn open FatFile instance for the directory containing the file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
File File::openNextFile (uint8_t mode = O_READ)
+
+inline
+
+

Opens the next file or folder in a directory.

+
Parameters
+ + +
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::openRoot (FatVolumevol)
+
+inherited
+
+

Open a volume's root directory.

+
Parameters
+ + +
[in]volThe FAT volume containing the root directory to be opened.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
File::operator bool ()
+
+inline
+
+

The parenthesis operator.

+
Returns
true if a file is open.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int File::peek ()
+
+inline
+
+

Return the next available byte without consuming it.

+
Returns
The byte if no error and not at eof else -1;
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t File::position ()
+
+inline
+
+
Returns
the current file position.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::printCreateDateTime (print_tpr)
+
+inherited
+
+

Print a file's creation date and time

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::printFatDate (uint16_t fatDate)
+
+inlinestaticinherited
+
+

Print a directory date field.

+

Format is yyyy-mm-dd.

+
Parameters
+ + +
[in]fatDateThe date field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFile::printFatDate (print_tpr,
uint16_t fatDate 
)
+
+staticinherited
+
+

Print a directory date field.

+

Format is yyyy-mm-dd.

+
Parameters
+ + + +
[in]prPrint stream for output.
[in]fatDateThe date field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::printFatTime (uint16_t fatTime)
+
+inlinestaticinherited
+
+

Print a directory time field.

+

Format is hh:mm:ss.

+
Parameters
+ + +
[in]fatTimeThe time field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFile::printFatTime (print_tpr,
uint16_t fatTime 
)
+
+staticinherited
+
+

Print a directory time field.

+

Format is hh:mm:ss.

+
Parameters
+ + + +
[in]prPrint stream for output.
[in]fatTimeThe time field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
int FatFile::printField (float value,
char term,
uint8_t prec = 2 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
[in]precNumber of digits after decimal point.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (int16_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (uint16_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (int32_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (uint32_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printFileSize (print_tpr)
+
+inherited
+
+

Print a file's size.

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The number of characters printed is returned for success and zero is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::printModifyDateTime (print_tpr)
+
+inherited
+
+

Print a file's modify date and time

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t FatFile::printName ()
+
+inlineinherited
+
+

Print a file's name.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printName (print_tpr)
+
+inherited
+
+

Print a file's name

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printSFN (print_tpr)
+
+inherited
+
+

Print a file's Short File Name.

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The number of characters printed is returned for success and zero is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int File::read ()
+
+inline
+
+

Read the next byte from a file.

+
Returns
For success return the next byte in the file as an int. If an error occurs or end of file is reached return -1.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::read (void * buf,
size_t nbyte 
)
+
+inherited
+
+

Read data from a file starting at the current position.

+
Parameters
+ + + +
[out]bufPointer to the location that will receive the data.
[in]nbyteMaximum number of bytes to read.
+
+
+
Returns
For success read() returns the number of bytes read. A value less than nbyte, including zero, will be returned if end of file is reached. If an error occurs, read() returns -1. Possible errors include read() called before a file has been opened, corrupt file system or an I/O error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int8_t FatFile::readDir (dir_tdir)
+
+inherited
+
+

Read the next directory entry from a directory file.

+
Parameters
+ + +
[out]dirThe dir_t struct that will receive the data.
+
+
+
Returns
For success readDir() returns the number of bytes read. A value of zero will be returned if end of file is reached. If an error occurs, readDir() returns -1. Possible errors include readDir() called before a directory has been opened, this is not a directory file or an I/O error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::remove ()
+
+inherited
+
+

Remove a file.

+

The directory entry and all data for the file are deleted.

+
Note
This function should not be used to delete the 8.3 version of a file that has a long name. For example if a file has the long name "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::remove (FatFiledirFile,
const char * path 
)
+
+staticinherited
+
+

Remove a file.

+

The directory entry and all data for the file are deleted.

+
Parameters
+ + + +
[in]dirFileThe directory that contains the file.
[in]pathPath for the file to be removed.
+
+
+
Note
This function should not be used to delete the 8.3 version of a file that has a long name. For example if a file has the long name "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::rename (FatFiledirFile,
const char * newPath 
)
+
+inherited
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]dirFileDirectory for the new path.
[in]newPathNew path name for the file/directory.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::rewind ()
+
+inlineinherited
+
+

Set the file's current position to zero.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void File::rewindDirectory ()
+
+inline
+
+

Rewind a file if it is a directory

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::rmdir ()
+
+inherited
+
+

Remove a directory file.

+

The directory file will be removed only if it is empty and is not the root directory. rmdir() follows DOS and Windows and ignores the read-only attribute for the directory.

+
Note
This function should not be used to delete the 8.3 version of a directory that has a long name. For example if a directory has the long name "New folder" you should not delete the 8.3 name "NEWFOL~1".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::rmRfStar ()
+
+inherited
+
+

Recursively delete a directory and all contained files.

+

This is like the Unix/Linux 'rm -rf *' if called with the root directory hence the name.

+

Warning - This will remove all contents of the directory including subdirectories. The directory will then be removed if it is not root. The read-only attribute for files will be ignored.

+
Note
This function should not be used to delete the 8.3 version of a directory that has a long name. See remove() and rmdir().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool File::seek (uint32_t pos)
+
+inline
+
+

Seek to a new position in the file, which must be between 0 and the size of the file (inclusive).

+
Parameters
+ + +
[in]posthe new file position.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekCur (int32_t offset)
+
+inlineinherited
+
+

Set the files position to current position + pos. See seekSet().

Parameters
+ + +
[in]offsetThe new position in bytes from the current position.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekEnd (int32_t offset = 0)
+
+inlineinherited
+
+

Set the files position to end-of-file + offset. See seekSet(). Can't be used for directory files since file size is not defined.

Parameters
+ + +
[in]offsetThe new position in bytes from end-of-file.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekSet (uint32_t pos)
+
+inherited
+
+

Sets a file's position.

+
Parameters
+ + +
[in]posThe new position in bytes from the beginning of the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static bool FatFile::setCwd (FatFiledir)
+
+inlinestaticinherited
+
+

Set the current working directory.

+
Parameters
+ + +
[in]dirNew current working directory.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::setpos (FatPos_tpos)
+
+inherited
+
+

set position for streams

Parameters
+ + +
[out]posstruct with value for new position
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t File::size ()
+
+inline
+
+
Returns
the file's size.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::sync ()
+
+inherited
+
+

The sync() call causes all modified data and directory fields to be written to the storage device.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::timestamp (FatFilefile)
+
+inherited
+
+

Copy a file's timestamps

+
Parameters
+ + +
[in]fileFile to copy timestamps from.
+
+
+
Note
Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::timestamp (uint8_t flags,
uint16_t year,
uint8_t month,
uint8_t day,
uint8_t hour,
uint8_t minute,
uint8_t second 
)
+
+inherited
+
+

Set a file's timestamps in its directory entry.

+
Parameters
+ + +
[in]flagsValues for flags are constructed by a bitwise-inclusive OR of flags from the following list
+
+
+

T_ACCESS - Set the file's last access date.

+

T_CREATE - Set the file's creation date and time.

+

T_WRITE - Set the file's last write/modification date and time.

+
Parameters
+ + + + + + + +
[in]yearValid range 1980 - 2107 inclusive.
[in]monthValid range 1 - 12 inclusive.
[in]dayValid range 1 - 31 inclusive.
[in]hourValid range 0 - 23 inclusive.
[in]minuteValid range 0 - 59 inclusive.
[in]secondValid range 0 - 59 inclusive
+
+
+
Note
It is possible to set an invalid date since there is no check for the number of days in a month.
+
+Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::truncate (uint32_t length)
+
+inherited
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + +
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFile::volume () const
+
+inlineinherited
+
+
Returns
FatVolume that contains this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t File::write (uint8_t b)
+
+inline
+
+

Write a byte to a file. Required by the Arduino Print class.

Parameters
+ + +
[in]bthe byte to be written. Use getWriteError to check for errors.
+
+
+
Returns
1 for success and 0 for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
size_t File::write (const uint8_t * buf,
size_t size 
)
+
+inline
+
+

Write data to an open file. Form required by Print.

+
Note
Data is moved to the cache but may not be written to the storage device until sync() is called.
+
Parameters
+ + + +
[in]bufPointer to the location of the data to be written.
[in]sizeNumber of bytes to write.
+
+
+
Returns
For success write() returns the number of bytes written, always nbyte. If an error occurs, write() returns -1. Possible errors include write() is called before a file has been opened, write is called for a read-only file, device is full, a corrupt file system or an I/O error.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int FatFile::write (const char * str)
+
+inlineinherited
+
+

Write a string to a file. Used by the Arduino Print class.

Parameters
+ + +
[in]strPointer to the string. Use getWriteError to check for errors.
+
+
+
Returns
count of characters written for success or -1 for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::write (const void * buf,
size_t nbyte 
)
+
+inherited
+
+

Write data to an open file.

+
Note
Data is moved to the cache but may not be written to the storage device until sync() is called.
+
Parameters
+ + + +
[in]bufPointer to the location of the data to be written.
[in]nbyteNumber of bytes to write.
+
+
+
Returns
For success write() returns the number of bytes written, always nbyte. If an error occurs, write() returns -1. Possible errors include write() is called before a file has been opened, write is called for a read-only file, device is full, a corrupt file system or an I/O error.
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/class_file__coll__graph.png b/libraries/SdFat/extras/html/class_file__coll__graph.png new file mode 100644 index 0000000..b65001b Binary files /dev/null and b/libraries/SdFat/extras/html/class_file__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_file__inherit__graph.png b/libraries/SdFat/extras/html/class_file__inherit__graph.png new file mode 100644 index 0000000..b65001b Binary files /dev/null and b/libraries/SdFat/extras/html/class_file__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_minimum_serial-members.html b/libraries/SdFat/extras/html/class_minimum_serial-members.html new file mode 100644 index 0000000..472096d --- /dev/null +++ b/libraries/SdFat/extras/html/class_minimum_serial-members.html @@ -0,0 +1,105 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
MinimumSerial Member List
+
+
+ +

This is the complete list of members for MinimumSerial, including all inherited members.

+ + + + + + + +
available()MinimumSerial
begin(uint32_t baud)MinimumSerial
flush()MinimumSerial
operator bool()MinimumSerialinline
read()MinimumSerial
write(uint8_t b)MinimumSerial
+ + + + diff --git a/libraries/SdFat/extras/html/class_minimum_serial.html b/libraries/SdFat/extras/html/class_minimum_serial.html new file mode 100644 index 0000000..27b4e05 --- /dev/null +++ b/libraries/SdFat/extras/html/class_minimum_serial.html @@ -0,0 +1,259 @@ + + + + + + +SdFat: MinimumSerial Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
MinimumSerial Class Reference
+
+
+ +

mini serial class for the SdFat library. + More...

+ +

#include <MinimumSerial.h>

+
+Inheritance diagram for MinimumSerial:
+
+
Inheritance graph
+ + +
[legend]
+
+Collaboration diagram for MinimumSerial:
+
+
Collaboration graph
+ + +
[legend]
+ + + + + + + + + + + + + + +

+Public Member Functions

int available ()
 
void begin (uint32_t baud)
 
void flush ()
 
 operator bool ()
 
int read ()
 
size_t write (uint8_t b)
 
+

Detailed Description

+

mini serial class for the SdFat library.

+

Member Function Documentation

+ +
+
+ + + + + + + +
int MinimumSerial::available ()
+
+
Returns
one if data is available.
+ +
+
+ +
+
+ + + + + + + + +
void MinimumSerial::begin (uint32_t baud)
+
+

Set baud rate for serial port zero and enable in non interrupt mode. Do not call this function if you use another serial library.

Parameters
+ + +
[in]baudrate
+
+
+ +
+
+ +
+
+ + + + + + + +
void MinimumSerial::flush ()
+
+

Wait for write done.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
MinimumSerial::operator bool ()
+
+inline
+
+
Returns
true for hardware serial
+ +
+
+ +
+
+ + + + + + + +
int MinimumSerial::read ()
+
+

Unbuffered read

Returns
-1 if no character is available or an available character.
+ +
+
+ +
+
+ + + + + + + + +
size_t MinimumSerial::write (uint8_t b)
+
+

Unbuffered write

+
Parameters
+ + +
[in]bbyte to write.
+
+
+
Returns
1
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • Arduino/libraries/SdFat/src/MinimumSerial.h
  • +
  • Arduino/libraries/SdFat/src/MinimumSerial.cpp
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_minimum_serial__coll__graph.png b/libraries/SdFat/extras/html/class_minimum_serial__coll__graph.png new file mode 100644 index 0000000..b5ad74f Binary files /dev/null and b/libraries/SdFat/extras/html/class_minimum_serial__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_minimum_serial__inherit__graph.png b/libraries/SdFat/extras/html/class_minimum_serial__inherit__graph.png new file mode 100644 index 0000000..b5ad74f Binary files /dev/null and b/libraries/SdFat/extras/html/class_minimum_serial__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_print_file-members.html b/libraries/SdFat/extras/html/class_print_file-members.html new file mode 100644 index 0000000..44473ff --- /dev/null +++ b/libraries/SdFat/extras/html/class_print_file-members.html @@ -0,0 +1,192 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
PrintFile Member List
+
+
+ +

This is the complete list of members for PrintFile, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
available()PrintFileinline
clearError()FatFileinline
clearWriteError()FatFileinline
close()FatFile
contiguousRange(uint32_t *bgnBlock, uint32_t *endBlock)FatFile
createContiguous(FatFile *dirFile, const char *path, uint32_t size)FatFile
createContiguous(const char *path, uint32_t size)FatFileinline
curCluster() const FatFileinline
curPosition() const FatFileinline
cwd()FatFileinlinestatic
dateTimeCallback(void(*dateTime)(uint16_t *date, uint16_t *time))FatFileinlinestatic
dateTimeCallbackCancel()FatFileinlinestatic
dirEntry(dir_t *dir)FatFile
dirIndex()FatFileinline
dirName(const dir_t *dir, char *name)FatFilestatic
dirSize()FatFile
dmpFile(print_t *pr, uint32_t pos, size_t n)FatFile
exists(const char *path)FatFileinline
FatFile()FatFileinline
FatFile(const char *path, uint8_t oflag)FatFileinline
fgets(char *str, int16_t num, char *delim=0)FatFile
fileAttr() const FatFileinline
fileSize() const FatFileinline
firstBlock()FatFileinline
firstCluster() const FatFileinline
flush()PrintFileinline
getError()FatFileinline
getName(char *name, size_t size)FatFile
getpos(FatPos_t *pos)FatFile
getSFN(char *name)FatFile
getWriteError()FatFileinline
isDir() const FatFileinline
isFile() const FatFileinline
isHidden() const FatFileinline
isLFN() const FatFileinline
isOpen() const FatFileinline
isReadOnly() const FatFileinline
isRoot() const FatFileinline
isRoot32() const FatFileinline
isRootFixed() const FatFileinline
isSubDir() const FatFileinline
isSystem() const FatFileinline
legal83Char(uint8_t c)FatFileinlinestatic
ls(uint8_t flags=0)FatFileinline
ls(print_t *pr, uint8_t flags=0, uint8_t indent=0)FatFile
mkdir(FatFile *dir, const char *path, bool pFlag=true)FatFile
open(FatFileSystem *fs, const char *path, uint8_t oflag)FatFile
open(FatFile *dirFile, uint16_t index, uint8_t oflag)FatFile
open(FatFile *dirFile, const char *path, uint8_t oflag)FatFile
open(const char *path, uint8_t oflag=O_READ)FatFileinline
openNext(FatFile *dirFile, uint8_t oflag=O_READ)FatFile
openRoot(FatVolume *vol)FatFile
peek()PrintFileinline
printCreateDateTime(print_t *pr)FatFile
printFatDate(uint16_t fatDate)FatFileinlinestatic
printFatDate(print_t *pr, uint16_t fatDate)FatFilestatic
printFatTime(uint16_t fatTime)FatFileinlinestatic
printFatTime(print_t *pr, uint16_t fatTime)FatFilestatic
printField(float value, char term, uint8_t prec=2)FatFile
printField(int16_t value, char term)FatFile
printField(uint16_t value, char term)FatFile
printField(int32_t value, char term)FatFile
printField(uint32_t value, char term)FatFile
PrintFile() (defined in PrintFile)PrintFileinline
PrintFile(const char *path, uint8_t oflag)PrintFileinline
printFileSize(print_t *pr)FatFile
printModifyDateTime(print_t *pr)FatFile
printName()FatFileinline
printName(print_t *pr)FatFile
printSFN(print_t *pr)FatFile
read()FatFileinline
read(void *buf, size_t nbyte)FatFile
readDir(dir_t *dir)FatFile
remove()FatFile
remove(FatFile *dirFile, const char *path)FatFilestatic
rename(FatFile *dirFile, const char *newPath)FatFile
rewind()FatFileinline
rmdir()FatFile
rmRfStar()FatFile
seekCur(int32_t offset)FatFileinline
seekEnd(int32_t offset=0)FatFileinline
seekSet(uint32_t pos)FatFile
setCwd(FatFile *dir)FatFileinlinestatic
setpos(FatPos_t *pos)FatFile
sync()FatFile
timestamp(FatFile *file)FatFile
timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)FatFile
truncate(uint32_t length)FatFile
volume() const FatFileinline
write(uint8_t b)PrintFileinline
write(const uint8_t *buf, size_t size)PrintFileinline
FatFile::write(const char *str)FatFileinline
FatFile::write(const void *buf, size_t nbyte)FatFile
+ + + + diff --git a/libraries/SdFat/extras/html/class_print_file.html b/libraries/SdFat/extras/html/class_print_file.html new file mode 100644 index 0000000..ec56bef --- /dev/null +++ b/libraries/SdFat/extras/html/class_print_file.html @@ -0,0 +1,3362 @@ + + + + + + +SdFat: PrintFile Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

FatFile with Print. + More...

+ +

#include <ArduinoFiles.h>

+
+Inheritance diagram for PrintFile:
+
+
Inheritance graph
+ + + + +
[legend]
+
+Collaboration diagram for PrintFile:
+
+
Collaboration graph
+ + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

int available ()
 
void clearError ()
 
void clearWriteError ()
 
bool close ()
 
bool contiguousRange (uint32_t *bgnBlock, uint32_t *endBlock)
 
bool createContiguous (FatFile *dirFile, const char *path, uint32_t size)
 
bool createContiguous (const char *path, uint32_t size)
 
uint32_t curCluster () const
 
uint32_t curPosition () const
 
bool dirEntry (dir_t *dir)
 
uint16_t dirIndex ()
 
uint32_t dirSize ()
 
void dmpFile (print_t *pr, uint32_t pos, size_t n)
 
bool exists (const char *path)
 
int16_t fgets (char *str, int16_t num, char *delim=0)
 
uint8_t fileAttr () const
 
uint32_t fileSize () const
 
uint32_t firstBlock ()
 
uint32_t firstCluster () const
 
void flush ()
 
uint8_t getError ()
 
bool getName (char *name, size_t size)
 
void getpos (FatPos_t *pos)
 
bool getSFN (char *name)
 
bool getWriteError ()
 
bool isDir () const
 
bool isFile () const
 
bool isHidden () const
 
bool isLFN () const
 
bool isOpen () const
 
bool isReadOnly () const
 
bool isRoot () const
 
bool isRoot32 () const
 
bool isRootFixed () const
 
bool isSubDir () const
 
bool isSystem () const
 
void ls (uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0, uint8_t indent=0)
 
bool mkdir (FatFile *dir, const char *path, bool pFlag=true)
 
bool open (FatFileSystem *fs, const char *path, uint8_t oflag)
 
bool open (FatFile *dirFile, uint16_t index, uint8_t oflag)
 
bool open (FatFile *dirFile, const char *path, uint8_t oflag)
 
bool open (const char *path, uint8_t oflag=O_READ)
 
bool openNext (FatFile *dirFile, uint8_t oflag=O_READ)
 
bool openRoot (FatVolume *vol)
 
int peek ()
 
bool printCreateDateTime (print_t *pr)
 
int printField (float value, char term, uint8_t prec=2)
 
int printField (int16_t value, char term)
 
int printField (uint16_t value, char term)
 
int printField (int32_t value, char term)
 
int printField (uint32_t value, char term)
 
 PrintFile (const char *path, uint8_t oflag)
 
size_t printFileSize (print_t *pr)
 
bool printModifyDateTime (print_t *pr)
 
size_t printName ()
 
size_t printName (print_t *pr)
 
size_t printSFN (print_t *pr)
 
int read ()
 
int read (void *buf, size_t nbyte)
 
int8_t readDir (dir_t *dir)
 
bool remove ()
 
bool rename (FatFile *dirFile, const char *newPath)
 
void rewind ()
 
bool rmdir ()
 
bool rmRfStar ()
 
bool seekCur (int32_t offset)
 
bool seekEnd (int32_t offset=0)
 
bool seekSet (uint32_t pos)
 
void setpos (FatPos_t *pos)
 
bool sync ()
 
bool timestamp (FatFile *file)
 
bool timestamp (uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
 
bool truncate (uint32_t length)
 
FatVolumevolume () const
 
size_t write (uint8_t b)
 
size_t write (const uint8_t *buf, size_t size)
 
int write (const char *str)
 
int write (const void *buf, size_t nbyte)
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static FatFilecwd ()
 
static void dateTimeCallback (void(*dateTime)(uint16_t *date, uint16_t *time))
 
static void dateTimeCallbackCancel ()
 
static uint8_t dirName (const dir_t *dir, char *name)
 
static bool legal83Char (uint8_t c)
 
static void printFatDate (uint16_t fatDate)
 
static void printFatDate (print_t *pr, uint16_t fatDate)
 
static void printFatTime (uint16_t fatTime)
 
static void printFatTime (print_t *pr, uint16_t fatTime)
 
static bool remove (FatFile *dirFile, const char *path)
 
static bool setCwd (FatFile *dir)
 
+

Detailed Description

+

FatFile with Print.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
PrintFile::PrintFile (const char * path,
uint8_t oflag 
)
+
+inline
+
+

Create a file object and open it in the current working directory.

+
Parameters
+ + + +
[in]pathA path for a file to be opened.
[in]oflagValues for oflag are constructed by a bitwise-inclusive OR of open flags. see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
int PrintFile::available ()
+
+inline
+
+
Returns
number of bytes available from the current position to EOF or INT_MAX if more than INT_MAX bytes are available.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::clearError ()
+
+inlineinherited
+
+

Clear all error bits.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::clearWriteError ()
+
+inlineinherited
+
+

Set writeError to zero

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::close ()
+
+inherited
+
+

Close a file and force cached data and directory information to be written to the storage device.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::contiguousRange (uint32_t * bgnBlock,
uint32_t * endBlock 
)
+
+inherited
+
+

Check for contiguous file and return its raw block range.

+
Parameters
+ + + +
[out]bgnBlockthe first block address for the file.
[out]endBlockthe last block address for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::createContiguous (FatFiledirFile,
const char * path,
uint32_t size 
)
+
+inherited
+
+

Create and open a new contiguous file of a specified size.

+
Parameters
+ + + + +
[in]dirFileThe directory where the file will be created.
[in]pathA path with a validfile name.
[in]sizeThe desired file size.
+
+
+
Returns
The value true is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::createContiguous (const char * path,
uint32_t size 
)
+
+inlineinherited
+
+

Create and open a new contiguous file of a specified size.

+
Parameters
+ + + +
[in]pathA path with a validfile name.
[in]sizeThe desired file size.
+
+
+
Returns
The value true is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::curCluster () const
+
+inlineinherited
+
+
Returns
The current cluster number for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::curPosition () const
+
+inlineinherited
+
+
Returns
The current position for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static FatFile* FatFile::cwd ()
+
+inlinestaticinherited
+
+
Returns
Current working directory
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::dateTimeCallback (void(*)(uint16_t *date, uint16_t *time) dateTime)
+
+inlinestaticinherited
+
+

Set the date/time callback function

+
Parameters
+ + +
[in]dateTimeThe user's call back function. The callback function is of the form:
+
+
+
void dateTime(uint16_t* date, uint16_t* time) {
+
uint16_t year;
+
uint8_t month, day, hour, minute, second;
+
+
// User gets date and time from GPS or real-time clock here
+
+
// return date using FAT_DATE macro to format fields
+
*date = FAT_DATE(year, month, day);
+
+
// return time using FAT_TIME macro to format fields
+
*time = FAT_TIME(hour, minute, second);
+
}
+

Sets the function that is called when a file is created or when a file's directory entry is modified by sync(). All timestamps, access, creation, and modify, are set when a file is created. sync() maintains the last access date and last modify date/time.

+

See the timestamp() function.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static void FatFile::dateTimeCallbackCancel ()
+
+inlinestaticinherited
+
+

Cancel the date/time callback function.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::dirEntry (dir_tdir)
+
+inherited
+
+

Return a file's directory entry.

+
Parameters
+ + +
[out]dirLocation for return of the file's directory entry.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatFile::dirIndex ()
+
+inlineinherited
+
+
Returns
The index of this file in it's directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t FatFile::dirName (const dir_tdir,
char * name 
)
+
+staticinherited
+
+

Format the name field of dir into the 13 byte array name in standard 8.3 short name format.

+
Parameters
+ + + +
[in]dirThe directory structure containing the name.
[out]nameA 13 byte char array for the formatted name.
+
+
+
Returns
length of the name.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::dirSize ()
+
+inherited
+
+
Returns
The number of bytes allocated to a directory or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFile::dmpFile (print_tpr,
uint32_t pos,
size_t n 
)
+
+inherited
+
+

Dump file in Hex

Parameters
+ + + + +
[in]prPrint stream for list.
[in]posStart position in file.
[in]nnumber of locations to dump.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::exists (const char * path)
+
+inlineinherited
+
+

Test for the existence of a file in a directory

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+

The calling instance must be an open directory file.

+

dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory dirFile.

+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
int16_t FatFile::fgets (char * str,
int16_t num,
char * delim = 0 
)
+
+inherited
+
+

Get a string from a file.

+

fgets() reads bytes from a file into the array pointed to by str, until num - 1 bytes are read, or a delimiter is read and transferred to str, or end-of-file is encountered. The string is then terminated with a null byte.

+

fgets() deletes CR, '\r', from the string. This insures only a '\n' terminates the string for Windows text files which use CRLF for newline.

+
Parameters
+ + + + +
[out]strPointer to the array where the string is stored.
[in]numMaximum number of characters to be read (including the final null byte). Usually the length of the array str is used.
[in]delimOptional set of delimiters. The default is "\n".
+
+
+
Returns
For success fgets() returns the length of the string in str. If no data is read, fgets() returns zero for EOF or -1 if an error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatFile::fileAttr () const
+
+inlineinherited
+
+

Type of file. You should use isFile() or isDir() instead of fileType() if possible.

+
Returns
The file or directory type.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::fileSize () const
+
+inlineinherited
+
+
Returns
The total number of bytes in a file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::firstBlock ()
+
+inlineinherited
+
+
Returns
first block of file or zero for empty file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::firstCluster () const
+
+inlineinherited
+
+
Returns
The first cluster number for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void PrintFile::flush ()
+
+inline
+
+

Ensure that any bytes written to the file are saved to the SD card.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatFile::getError ()
+
+inlineinherited
+
+
Returns
All error bits.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::getName (char * name,
size_t size 
)
+
+inherited
+
+

Get a file's name followed by a zero byte.

+
Parameters
+ + + +
[out]nameAn array of characters for the file's name.
[in]sizeThe size of the array in bytes. The array must be at least 13 bytes long. The file's name will be truncated if the file's name is too long.
+
+
+
Returns
The value true, is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::getpos (FatPos_tpos)
+
+inherited
+
+

get position for streams

Parameters
+ + +
[out]posstruct to receive position
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::getSFN (char * name)
+
+inherited
+
+

Get a file's Short File Name followed by a zero byte.

+
Parameters
+ + +
[out]nameAn array of characters for the file's name. The array must be at least 13 bytes long.
+
+
+
Returns
The value true, is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::getWriteError ()
+
+inlineinherited
+
+
Returns
value of writeError
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isDir () const
+
+inlineinherited
+
+
Returns
True if this is a directory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isFile () const
+
+inlineinherited
+
+
Returns
True if this is a normal file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isHidden () const
+
+inlineinherited
+
+
Returns
True if this is a hidden file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isLFN () const
+
+inlineinherited
+
+
Returns
true if this file has a Long File Name.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isOpen () const
+
+inlineinherited
+
+
Returns
True if this is an open file/directory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isReadOnly () const
+
+inlineinherited
+
+
Returns
True if file is read-only
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRoot () const
+
+inlineinherited
+
+
Returns
True if this is the root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRoot32 () const
+
+inlineinherited
+
+
Returns
True if this is the FAT32 root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRootFixed () const
+
+inlineinherited
+
+
Returns
True if this is the FAT12 of FAT16 root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isSubDir () const
+
+inlineinherited
+
+
Returns
True if this is a subdirectory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isSystem () const
+
+inlineinherited
+
+
Returns
True if this is a system file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static bool FatFile::legal83Char (uint8_t c)
+
+inlinestaticinherited
+
+

Check for a legal 8.3 character.

Parameters
+ + +
[in]cCharacter to be checked.
+
+
+
Returns
true for a legal 8.3 character else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::ls (uint8_t flags = 0)
+
+inlineinherited
+
+

List directory contents.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFile::ls (print_tpr,
uint8_t flags = 0,
uint8_t indent = 0 
)
+
+inherited
+
+

List directory contents.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+
Parameters
+ + +
[in]indentAmount of space before file name. Used for recursive list to indicate subdirectory level.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::mkdir (FatFiledir,
const char * path,
bool pFlag = true 
)
+
+inherited
+
+

Make a new directory.

+
Parameters
+ + + + +
[in]dirAn open FatFile instance for the directory that will contain the new directory.
[in]pathA path with a valid 8.3 DOS name for the new directory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFileSystemfs,
const char * path,
uint8_t oflag 
)
+
+inherited
+
+

Open a file in the volume working directory of a FatFileSystem.

+
Parameters
+ + + + +
[in]fsFile System where the file is located.
[in]pathwith a valid 8.3 DOS name for a file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFiledirFile,
uint16_t index,
uint8_t oflag 
)
+
+inherited
+
+

Open a file by index.

+
Parameters
+ + + + +
[in]dirFileAn open FatFile instance for the directory.
[in]indexThe index of the directory entry for the file to be opened. The value for index is (directory file position)/32.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+

See open() by path for definition of flags.

Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFiledirFile,
const char * path,
uint8_t oflag 
)
+
+inherited
+
+

Open a file or directory by name.

+
Parameters
+ + + + +
[in]dirFileAn open FatFile instance for the directory containing the file to be opened.
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagValues for oflag are constructed by a bitwise-inclusive OR of flags from the following list
+
+
+

O_READ - Open for reading.

+

O_RDONLY - Same as O_READ.

+

O_WRITE - Open for writing.

+

O_WRONLY - Same as O_WRITE.

+

O_RDWR - Open for reading and writing.

+

O_APPEND - If set, the file offset shall be set to the end of the file prior to each write.

+

O_AT_END - Set the initial position at the end of the file.

+

O_CREAT - If the file exists, this flag has no effect except as noted under O_EXCL below. Otherwise, the file shall be created

+

O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.

+

O_SYNC - Call sync() after each write. This flag should not be used with write(uint8_t) or any functions do character at a time writes since sync() will be called after each byte.

+

O_TRUNC - If the file exists and is a regular file, and the file is successfully opened and is not read only, its length shall be truncated to 0.

+

WARNING: A given file must not be opened by more than one FatFile object or file corruption may occur.

+
Note
Directory files must be opened read only. Write and truncation is not allowed for directory files.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::open (const char * path,
uint8_t oflag = O_READ 
)
+
+inlineinherited
+
+

Open a file in the current working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::openNext (FatFiledirFile,
uint8_t oflag = O_READ 
)
+
+inherited
+
+

Open the next file or subdirectory in a directory.

+
Parameters
+ + + +
[in]dirFileAn open FatFile instance for the directory containing the file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::openRoot (FatVolumevol)
+
+inherited
+
+

Open a volume's root directory.

+
Parameters
+ + +
[in]volThe FAT volume containing the root directory to be opened.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int PrintFile::peek ()
+
+inline
+
+

Return the next available byte without consuming it.

+
Returns
The byte if no error and not at eof else -1;
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::printCreateDateTime (print_tpr)
+
+inherited
+
+

Print a file's creation date and time

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::printFatDate (uint16_t fatDate)
+
+inlinestaticinherited
+
+

Print a directory date field.

+

Format is yyyy-mm-dd.

+
Parameters
+ + +
[in]fatDateThe date field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFile::printFatDate (print_tpr,
uint16_t fatDate 
)
+
+staticinherited
+
+

Print a directory date field.

+

Format is yyyy-mm-dd.

+
Parameters
+ + + +
[in]prPrint stream for output.
[in]fatDateThe date field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::printFatTime (uint16_t fatTime)
+
+inlinestaticinherited
+
+

Print a directory time field.

+

Format is hh:mm:ss.

+
Parameters
+ + +
[in]fatTimeThe time field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFile::printFatTime (print_tpr,
uint16_t fatTime 
)
+
+staticinherited
+
+

Print a directory time field.

+

Format is hh:mm:ss.

+
Parameters
+ + + +
[in]prPrint stream for output.
[in]fatTimeThe time field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
int FatFile::printField (float value,
char term,
uint8_t prec = 2 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
[in]precNumber of digits after decimal point.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (int16_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (uint16_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (int32_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (uint32_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printFileSize (print_tpr)
+
+inherited
+
+

Print a file's size.

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The number of characters printed is returned for success and zero is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::printModifyDateTime (print_tpr)
+
+inherited
+
+

Print a file's modify date and time

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t FatFile::printName ()
+
+inlineinherited
+
+

Print a file's name.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printName (print_tpr)
+
+inherited
+
+

Print a file's name

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printSFN (print_tpr)
+
+inherited
+
+

Print a file's Short File Name.

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The number of characters printed is returned for success and zero is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int FatFile::read ()
+
+inlineinherited
+
+

Read the next byte from a file.

+
Returns
For success read returns the next byte in the file as an int. If an error occurs or end of file is reached -1 is returned.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::read (void * buf,
size_t nbyte 
)
+
+inherited
+
+

Read data from a file starting at the current position.

+
Parameters
+ + + +
[out]bufPointer to the location that will receive the data.
[in]nbyteMaximum number of bytes to read.
+
+
+
Returns
For success read() returns the number of bytes read. A value less than nbyte, including zero, will be returned if end of file is reached. If an error occurs, read() returns -1. Possible errors include read() called before a file has been opened, corrupt file system or an I/O error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int8_t FatFile::readDir (dir_tdir)
+
+inherited
+
+

Read the next directory entry from a directory file.

+
Parameters
+ + +
[out]dirThe dir_t struct that will receive the data.
+
+
+
Returns
For success readDir() returns the number of bytes read. A value of zero will be returned if end of file is reached. If an error occurs, readDir() returns -1. Possible errors include readDir() called before a directory has been opened, this is not a directory file or an I/O error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::remove ()
+
+inherited
+
+

Remove a file.

+

The directory entry and all data for the file are deleted.

+
Note
This function should not be used to delete the 8.3 version of a file that has a long name. For example if a file has the long name "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::remove (FatFiledirFile,
const char * path 
)
+
+staticinherited
+
+

Remove a file.

+

The directory entry and all data for the file are deleted.

+
Parameters
+ + + +
[in]dirFileThe directory that contains the file.
[in]pathPath for the file to be removed.
+
+
+
Note
This function should not be used to delete the 8.3 version of a file that has a long name. For example if a file has the long name "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::rename (FatFiledirFile,
const char * newPath 
)
+
+inherited
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]dirFileDirectory for the new path.
[in]newPathNew path name for the file/directory.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::rewind ()
+
+inlineinherited
+
+

Set the file's current position to zero.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::rmdir ()
+
+inherited
+
+

Remove a directory file.

+

The directory file will be removed only if it is empty and is not the root directory. rmdir() follows DOS and Windows and ignores the read-only attribute for the directory.

+
Note
This function should not be used to delete the 8.3 version of a directory that has a long name. For example if a directory has the long name "New folder" you should not delete the 8.3 name "NEWFOL~1".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::rmRfStar ()
+
+inherited
+
+

Recursively delete a directory and all contained files.

+

This is like the Unix/Linux 'rm -rf *' if called with the root directory hence the name.

+

Warning - This will remove all contents of the directory including subdirectories. The directory will then be removed if it is not root. The read-only attribute for files will be ignored.

+
Note
This function should not be used to delete the 8.3 version of a directory that has a long name. See remove() and rmdir().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekCur (int32_t offset)
+
+inlineinherited
+
+

Set the files position to current position + pos. See seekSet().

Parameters
+ + +
[in]offsetThe new position in bytes from the current position.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekEnd (int32_t offset = 0)
+
+inlineinherited
+
+

Set the files position to end-of-file + offset. See seekSet(). Can't be used for directory files since file size is not defined.

Parameters
+ + +
[in]offsetThe new position in bytes from end-of-file.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekSet (uint32_t pos)
+
+inherited
+
+

Sets a file's position.

+
Parameters
+ + +
[in]posThe new position in bytes from the beginning of the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static bool FatFile::setCwd (FatFiledir)
+
+inlinestaticinherited
+
+

Set the current working directory.

+
Parameters
+ + +
[in]dirNew current working directory.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::setpos (FatPos_tpos)
+
+inherited
+
+

set position for streams

Parameters
+ + +
[out]posstruct with value for new position
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::sync ()
+
+inherited
+
+

The sync() call causes all modified data and directory fields to be written to the storage device.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::timestamp (FatFilefile)
+
+inherited
+
+

Copy a file's timestamps

+
Parameters
+ + +
[in]fileFile to copy timestamps from.
+
+
+
Note
Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::timestamp (uint8_t flags,
uint16_t year,
uint8_t month,
uint8_t day,
uint8_t hour,
uint8_t minute,
uint8_t second 
)
+
+inherited
+
+

Set a file's timestamps in its directory entry.

+
Parameters
+ + +
[in]flagsValues for flags are constructed by a bitwise-inclusive OR of flags from the following list
+
+
+

T_ACCESS - Set the file's last access date.

+

T_CREATE - Set the file's creation date and time.

+

T_WRITE - Set the file's last write/modification date and time.

+
Parameters
+ + + + + + + +
[in]yearValid range 1980 - 2107 inclusive.
[in]monthValid range 1 - 12 inclusive.
[in]dayValid range 1 - 31 inclusive.
[in]hourValid range 0 - 23 inclusive.
[in]minuteValid range 0 - 59 inclusive.
[in]secondValid range 0 - 59 inclusive
+
+
+
Note
It is possible to set an invalid date since there is no check for the number of days in a month.
+
+Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::truncate (uint32_t length)
+
+inherited
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + +
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFile::volume () const
+
+inlineinherited
+
+
Returns
FatVolume that contains this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t PrintFile::write (uint8_t b)
+
+inline
+
+

Read the next byte from a file.

+
Returns
For success return the next byte in the file as an int. If an error occurs or end of file is reached return -1. Write a byte to a file. Required by the Arduino Print class.
+
Parameters
+ + +
[in]bthe byte to be written. Use getWriteError to check for errors.
+
+
+
Returns
1 for success and 0 for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
size_t PrintFile::write (const uint8_t * buf,
size_t size 
)
+
+inline
+
+

Write data to an open file. Form required by Print.

+
Note
Data is moved to the cache but may not be written to the storage device until sync() is called.
+
Parameters
+ + + +
[in]bufPointer to the location of the data to be written.
[in]sizeNumber of bytes to write.
+
+
+
Returns
For success write() returns the number of bytes written, always nbyte. If an error occurs, write() returns -1. Possible errors include write() is called before a file has been opened, write is called for a read-only file, device is full, a corrupt file system or an I/O error.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int FatFile::write (const char * str)
+
+inlineinherited
+
+

Write a string to a file. Used by the Arduino Print class.

Parameters
+ + +
[in]strPointer to the string. Use getWriteError to check for errors.
+
+
+
Returns
count of characters written for success or -1 for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::write (const void * buf,
size_t nbyte 
)
+
+inherited
+
+

Write data to an open file.

+
Note
Data is moved to the cache but may not be written to the storage device until sync() is called.
+
Parameters
+ + + +
[in]bufPointer to the location of the data to be written.
[in]nbyteNumber of bytes to write.
+
+
+
Returns
For success write() returns the number of bytes written, always nbyte. If an error occurs, write() returns -1. Possible errors include write() is called before a file has been opened, write is called for a read-only file, device is full, a corrupt file system or an I/O error.
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/class_print_file__coll__graph.png b/libraries/SdFat/extras/html/class_print_file__coll__graph.png new file mode 100644 index 0000000..36319e9 Binary files /dev/null and b/libraries/SdFat/extras/html/class_print_file__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_print_file__inherit__graph.png b/libraries/SdFat/extras/html/class_print_file__inherit__graph.png new file mode 100644 index 0000000..3706975 Binary files /dev/null and b/libraries/SdFat/extras/html/class_print_file__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd2_card-members.html b/libraries/SdFat/extras/html/class_sd2_card-members.html new file mode 100644 index 0000000..0ad99b4 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd2_card-members.html @@ -0,0 +1,128 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
Sd2Card Member List
+
+
+ +

This is the complete list of members for Sd2Card, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin(uint8_t csPin=SS, SPISettings settings=SD_SCK_MHZ(50))Sd2Cardinline
SdSpiCard::begin(SdSpiDriver *spi, uint8_t csPin, SPISettings spiSettings)SdSpiCard
cardSize()SdSpiCard
erase(uint32_t firstBlock, uint32_t lastBlock)SdSpiCard
eraseSingleBlockEnable()SdSpiCard
error(uint8_t code)SdSpiCardinline
errorCode() const SdSpiCardinline
errorData() const SdSpiCardinline
isBusy()SdSpiCard
readBlock(uint32_t lba, uint8_t *dst)SdSpiCard
readBlocks(uint32_t lba, uint8_t *dst, size_t nb)SdSpiCard
readCID(cid_t *cid)SdSpiCardinline
readCSD(csd_t *csd)SdSpiCardinline
readData(uint8_t *dst)SdSpiCard
readOCR(uint32_t *ocr)SdSpiCard
readStart(uint32_t blockNumber)SdSpiCard
readStatus(uint8_t *status)SdSpiCard
readStop()SdSpiCard
SdSpiCard()SdSpiCardinline
spiStart()SdSpiCard
spiStop()SdSpiCard
syncBlocks()SdSpiCardinline
type() const SdSpiCardinline
writeBlock(uint32_t lba, const uint8_t *src)SdSpiCard
writeBlocks(uint32_t lba, const uint8_t *src, size_t nb)SdSpiCard
writeData(const uint8_t *src)SdSpiCard
writeStart(uint32_t blockNumber)SdSpiCard
writeStart(uint32_t blockNumber, uint32_t eraseCount)SdSpiCard
writeStop()SdSpiCard
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd2_card.html b/libraries/SdFat/extras/html/class_sd2_card.html new file mode 100644 index 0000000..1ba9a57 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd2_card.html @@ -0,0 +1,1106 @@ + + + + + + +SdFat: Sd2Card Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
Sd2Card Class Reference
+
+
+ +

Raw access to SD and SDHC card using default SPI library. + More...

+ +

#include <SdFat.h>

+
+Inheritance diagram for Sd2Card:
+
+
Inheritance graph
+ + + +
[legend]
+
+Collaboration diagram for Sd2Card:
+
+
Collaboration graph
+ + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin (SdSpiDriver *spi, uint8_t csPin, SPISettings spiSettings)
 
bool begin (uint8_t csPin=SS, SPISettings settings=SD_SCK_MHZ(50))
 
uint32_t cardSize ()
 
bool erase (uint32_t firstBlock, uint32_t lastBlock)
 
bool eraseSingleBlockEnable ()
 
void error (uint8_t code)
 
int errorCode () const
 
int errorData () const
 
bool isBusy ()
 
bool readBlock (uint32_t lba, uint8_t *dst)
 
bool readBlocks (uint32_t lba, uint8_t *dst, size_t nb)
 
bool readCID (cid_t *cid)
 
bool readCSD (csd_t *csd)
 
bool readData (uint8_t *dst)
 
bool readOCR (uint32_t *ocr)
 
bool readStart (uint32_t blockNumber)
 
bool readStatus (uint8_t *status)
 
bool readStop ()
 
void spiStart ()
 
void spiStop ()
 
bool syncBlocks ()
 
int type () const
 
bool writeBlock (uint32_t lba, const uint8_t *src)
 
bool writeBlocks (uint32_t lba, const uint8_t *src, size_t nb)
 
bool writeData (const uint8_t *src)
 
bool writeStart (uint32_t blockNumber)
 
bool writeStart (uint32_t blockNumber, uint32_t eraseCount)
 
bool writeStop ()
 
+

Detailed Description

+

Raw access to SD and SDHC card using default SPI library.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdSpiCard::begin (SdSpiDriver * spi,
uint8_t csPin,
SPISettings spiSettings 
)
+
+inherited
+
+

Initialize the SD card.

Parameters
+ + + + +
[in]spiSPI driver for card.
[in]csPincard chip select pin.
[in]spiSettingsSPI speed, mode, and bit order.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool Sd2Card::begin (uint8_t csPin = SS,
SPISettings settings = SD_SCK_MHZ(50) 
)
+
+inline
+
+

Initialize the SD card.

Parameters
+ + + +
[in]csPinSD chip select pin.
[in]settingsSPI speed, mode, and bit order.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t SdSpiCard::cardSize ()
+
+inherited
+
+

Determine the size of an SD flash memory card.

+
Returns
The number of 512 byte data blocks in the card or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCard::erase (uint32_t firstBlock,
uint32_t lastBlock 
)
+
+inherited
+
+

Erase a range of blocks.

+
Parameters
+ + + +
[in]firstBlockThe address of the first block in the range.
[in]lastBlockThe address of the last block in the range.
+
+
+
Note
This function requests the SD card to do a flash erase for a range of blocks. The data on the card after an erase operation is either 0 or 1, depends on the card vendor. The card must support single block erase.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdSpiCard::eraseSingleBlockEnable ()
+
+inherited
+
+

Determine if card supports single block erase.

+
Returns
true is returned if single block erase is supported. false is returned if single block erase is not supported.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdSpiCard::error (uint8_t code)
+
+inlineinherited
+
+

Set SD error code.

Parameters
+ + +
[in]codevalue for error code.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SdSpiCard::errorCode () const
+
+inlineinherited
+
+
Returns
code for the last error. See SdInfo.h for a list of error codes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SdSpiCard::errorData () const
+
+inlineinherited
+
+
Returns
error data for last error.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdSpiCard::isBusy ()
+
+inherited
+
+

Check for busy. MISO low indicates the card is busy.

+
Returns
true if busy else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCard::readBlock (uint32_t lba,
uint8_t * dst 
)
+
+inherited
+
+

Read a 512 byte block from an SD card.

+
Parameters
+ + + +
[in]lbaLogical block to be read.
[out]dstPointer to the location that will receive the data.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdSpiCard::readBlocks (uint32_t lba,
uint8_t * dst,
size_t nb 
)
+
+inherited
+
+

Read multiple 512 byte blocks from an SD card.

+
Parameters
+ + + + +
[in]lbaLogical block to be read.
[in]nbNumber of blocks to be read.
[out]dstPointer to the location that will receive the data.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readCID (cid_t * cid)
+
+inlineinherited
+
+

Read a card's CID register. The CID contains card identification information such as Manufacturer ID, Product name, Product serial number and Manufacturing date.

+
Parameters
+ + +
[out]cidpointer to area for returned data.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readCSD (csd_t * csd)
+
+inlineinherited
+
+

Read a card's CSD register. The CSD contains Card-Specific Data that provides information regarding access to the card's contents.

+
Parameters
+ + +
[out]csdpointer to area for returned data.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readData (uint8_t * dst)
+
+inherited
+
+

Read one data block in a multiple block read sequence

+
Parameters
+ + +
[out]dstPointer to the location for the data to be read.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readOCR (uint32_t * ocr)
+
+inherited
+
+

Read OCR register.

+
Parameters
+ + +
[out]ocrValue of OCR register.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readStart (uint32_t blockNumber)
+
+inherited
+
+

Start a read multiple blocks sequence.

+
Parameters
+ + +
[in]blockNumberAddress of first block in sequence.
+
+
+
Note
This function is used with readData() and readStop() for optimized multiple block reads. SPI chipSelect must be low for the entire sequence.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readStatus (uint8_t * status)
+
+inherited
+
+

Return the 64 byte card status

Parameters
+ + +
[out]statuslocation for 64 status bytes.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdSpiCard::readStop ()
+
+inherited
+
+

End a read multiple blocks sequence.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdSpiCard::spiStart ()
+
+inherited
+
+

Set CS low and activate the card.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdSpiCard::spiStop ()
+
+inherited
+
+

Set CS high and deactivate the card.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdSpiCard::syncBlocks ()
+
+inlineinherited
+
+
Returns
success if sync successful. Not for user apps.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SdSpiCard::type () const
+
+inlineinherited
+
+

Return the card type: SD V1, SD V2 or SDHC

Returns
0 - SD V1, 1 - SD V2, or 3 - SDHC.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCard::writeBlock (uint32_t lba,
const uint8_t * src 
)
+
+inherited
+
+

Writes a 512 byte block to an SD card.

+
Parameters
+ + + +
[in]lbaLogical block to be written.
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdSpiCard::writeBlocks (uint32_t lba,
const uint8_t * src,
size_t nb 
)
+
+inherited
+
+

Write multiple 512 byte blocks to an SD card.

+
Parameters
+ + + + +
[in]lbaLogical block to be written.
[in]nbNumber of blocks to be written.
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::writeData (const uint8_t * src)
+
+inherited
+
+

Write one data block in a multiple block write sequence.

Parameters
+ + +
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::writeStart (uint32_t blockNumber)
+
+inherited
+
+

Start a write multiple blocks sequence.

+
Parameters
+ + +
[in]blockNumberAddress of first block in sequence.
+
+
+
Note
This function is used with writeData() and writeStop() for optimized multiple block writes.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCard::writeStart (uint32_t blockNumber,
uint32_t eraseCount 
)
+
+inherited
+
+

Start a write multiple blocks sequence with pre-erase.

+
Parameters
+ + + +
[in]blockNumberAddress of first block in sequence.
[in]eraseCountThe number of blocks to be pre-erased.
+
+
+
Note
This function is used with writeData() and writeStop() for optimized multiple block writes.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdSpiCard::writeStop ()
+
+inherited
+
+

End a write multiple blocks sequence.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/SdFat.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd2_card__coll__graph.png b/libraries/SdFat/extras/html/class_sd2_card__coll__graph.png new file mode 100644 index 0000000..023d327 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd2_card__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd2_card__inherit__graph.png b/libraries/SdFat/extras/html/class_sd2_card__inherit__graph.png new file mode 100644 index 0000000..023d327 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd2_card__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_base_file-members.html b/libraries/SdFat/extras/html/class_sd_base_file-members.html new file mode 100644 index 0000000..72f47a4 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_base_file-members.html @@ -0,0 +1,190 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdBaseFile Member List
+
+
+ +

This is the complete list of members for SdBaseFile, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
available()FatFileinline
clearError()FatFileinline
clearWriteError()FatFileinline
close()FatFile
contiguousRange(uint32_t *bgnBlock, uint32_t *endBlock)FatFile
createContiguous(FatFile *dirFile, const char *path, uint32_t size)FatFile
createContiguous(const char *path, uint32_t size)FatFileinline
curCluster() const FatFileinline
curPosition() const FatFileinline
cwd()FatFileinlinestatic
dateTimeCallback(void(*dateTime)(uint16_t *date, uint16_t *time))FatFileinlinestatic
dateTimeCallbackCancel()FatFileinlinestatic
dirEntry(dir_t *dir)FatFile
dirIndex()FatFileinline
dirName(const dir_t *dir, char *name)FatFilestatic
dirSize()FatFile
dmpFile(print_t *pr, uint32_t pos, size_t n)FatFile
exists(const char *path)FatFileinline
FatFile()FatFileinline
FatFile(const char *path, uint8_t oflag)FatFileinline
fgets(char *str, int16_t num, char *delim=0)FatFile
fileAttr() const FatFileinline
fileSize() const FatFileinline
firstBlock()FatFileinline
firstCluster() const FatFileinline
getError()FatFileinline
getName(char *name, size_t size)FatFile
getpos(FatPos_t *pos)FatFile
getSFN(char *name)FatFile
getWriteError()FatFileinline
isDir() const FatFileinline
isFile() const FatFileinline
isHidden() const FatFileinline
isLFN() const FatFileinline
isOpen() const FatFileinline
isReadOnly() const FatFileinline
isRoot() const FatFileinline
isRoot32() const FatFileinline
isRootFixed() const FatFileinline
isSubDir() const FatFileinline
isSystem() const FatFileinline
legal83Char(uint8_t c)FatFileinlinestatic
ls(uint8_t flags=0)FatFileinline
ls(print_t *pr, uint8_t flags=0, uint8_t indent=0)FatFile
mkdir(FatFile *dir, const char *path, bool pFlag=true)FatFile
open(FatFileSystem *fs, const char *path, uint8_t oflag)FatFile
open(FatFile *dirFile, uint16_t index, uint8_t oflag)FatFile
open(FatFile *dirFile, const char *path, uint8_t oflag)FatFile
open(const char *path, uint8_t oflag=O_READ)FatFileinline
openNext(FatFile *dirFile, uint8_t oflag=O_READ)FatFile
openRoot(FatVolume *vol)FatFile
peek()FatFile
printCreateDateTime(print_t *pr)FatFile
printFatDate(uint16_t fatDate)FatFileinlinestatic
printFatDate(print_t *pr, uint16_t fatDate)FatFilestatic
printFatTime(uint16_t fatTime)FatFileinlinestatic
printFatTime(print_t *pr, uint16_t fatTime)FatFilestatic
printField(float value, char term, uint8_t prec=2)FatFile
printField(int16_t value, char term)FatFile
printField(uint16_t value, char term)FatFile
printField(int32_t value, char term)FatFile
printField(uint32_t value, char term)FatFile
printFileSize(print_t *pr)FatFile
printModifyDateTime(print_t *pr)FatFile
printName()FatFileinline
printName(print_t *pr)FatFile
printSFN(print_t *pr)FatFile
read()FatFileinline
read(void *buf, size_t nbyte)FatFile
readDir(dir_t *dir)FatFile
remove()FatFile
remove(FatFile *dirFile, const char *path)FatFilestatic
rename(FatFile *dirFile, const char *newPath)FatFile
rewind()FatFileinline
rmdir()FatFile
rmRfStar()FatFile
SdBaseFile() (defined in SdBaseFile)SdBaseFileinline
SdBaseFile(const char *path, uint8_t oflag)SdBaseFileinline
seekCur(int32_t offset)FatFileinline
seekEnd(int32_t offset=0)FatFileinline
seekSet(uint32_t pos)FatFile
setCwd(FatFile *dir)FatFileinlinestatic
setpos(FatPos_t *pos)FatFile
sync()FatFile
timestamp(FatFile *file)FatFile
timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)FatFile
truncate(uint32_t length)FatFile
volume() const FatFileinline
write(const char *str)FatFileinline
write(uint8_t b)FatFileinline
write(const void *buf, size_t nbyte)FatFile
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_base_file.html b/libraries/SdFat/extras/html/class_sd_base_file.html new file mode 100644 index 0000000..525c284 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_base_file.html @@ -0,0 +1,3287 @@ + + + + + + +SdFat: SdBaseFile Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for backward compatibility. + More...

+ +

#include <SdFat.h>

+
+Inheritance diagram for SdBaseFile:
+
+
Inheritance graph
+ + + +
[legend]
+
+Collaboration diagram for SdBaseFile:
+
+
Collaboration graph
+ + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

uint32_t available ()
 
void clearError ()
 
void clearWriteError ()
 
bool close ()
 
bool contiguousRange (uint32_t *bgnBlock, uint32_t *endBlock)
 
bool createContiguous (FatFile *dirFile, const char *path, uint32_t size)
 
bool createContiguous (const char *path, uint32_t size)
 
uint32_t curCluster () const
 
uint32_t curPosition () const
 
bool dirEntry (dir_t *dir)
 
uint16_t dirIndex ()
 
uint32_t dirSize ()
 
void dmpFile (print_t *pr, uint32_t pos, size_t n)
 
bool exists (const char *path)
 
int16_t fgets (char *str, int16_t num, char *delim=0)
 
uint8_t fileAttr () const
 
uint32_t fileSize () const
 
uint32_t firstBlock ()
 
uint32_t firstCluster () const
 
uint8_t getError ()
 
bool getName (char *name, size_t size)
 
void getpos (FatPos_t *pos)
 
bool getSFN (char *name)
 
bool getWriteError ()
 
bool isDir () const
 
bool isFile () const
 
bool isHidden () const
 
bool isLFN () const
 
bool isOpen () const
 
bool isReadOnly () const
 
bool isRoot () const
 
bool isRoot32 () const
 
bool isRootFixed () const
 
bool isSubDir () const
 
bool isSystem () const
 
void ls (uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0, uint8_t indent=0)
 
bool mkdir (FatFile *dir, const char *path, bool pFlag=true)
 
bool open (FatFileSystem *fs, const char *path, uint8_t oflag)
 
bool open (FatFile *dirFile, uint16_t index, uint8_t oflag)
 
bool open (FatFile *dirFile, const char *path, uint8_t oflag)
 
bool open (const char *path, uint8_t oflag=O_READ)
 
bool openNext (FatFile *dirFile, uint8_t oflag=O_READ)
 
bool openRoot (FatVolume *vol)
 
int peek ()
 
bool printCreateDateTime (print_t *pr)
 
int printField (float value, char term, uint8_t prec=2)
 
int printField (int16_t value, char term)
 
int printField (uint16_t value, char term)
 
int printField (int32_t value, char term)
 
int printField (uint32_t value, char term)
 
size_t printFileSize (print_t *pr)
 
bool printModifyDateTime (print_t *pr)
 
size_t printName ()
 
size_t printName (print_t *pr)
 
size_t printSFN (print_t *pr)
 
int read ()
 
int read (void *buf, size_t nbyte)
 
int8_t readDir (dir_t *dir)
 
bool remove ()
 
bool rename (FatFile *dirFile, const char *newPath)
 
void rewind ()
 
bool rmdir ()
 
bool rmRfStar ()
 
 SdBaseFile (const char *path, uint8_t oflag)
 
bool seekCur (int32_t offset)
 
bool seekEnd (int32_t offset=0)
 
bool seekSet (uint32_t pos)
 
void setpos (FatPos_t *pos)
 
bool sync ()
 
bool timestamp (FatFile *file)
 
bool timestamp (uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
 
bool truncate (uint32_t length)
 
FatVolumevolume () const
 
int write (const char *str)
 
int write (uint8_t b)
 
int write (const void *buf, size_t nbyte)
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static FatFilecwd ()
 
static void dateTimeCallback (void(*dateTime)(uint16_t *date, uint16_t *time))
 
static void dateTimeCallbackCancel ()
 
static uint8_t dirName (const dir_t *dir, char *name)
 
static bool legal83Char (uint8_t c)
 
static void printFatDate (uint16_t fatDate)
 
static void printFatDate (print_t *pr, uint16_t fatDate)
 
static void printFatTime (uint16_t fatTime)
 
static void printFatTime (print_t *pr, uint16_t fatTime)
 
static bool remove (FatFile *dirFile, const char *path)
 
static bool setCwd (FatFile *dir)
 
+

Detailed Description

+

Class for backward compatibility.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
SdBaseFile::SdBaseFile (const char * path,
uint8_t oflag 
)
+
+inline
+
+

Create a file object and open it in the current working directory.

+
Parameters
+ + + +
[in]pathA path for a file to be opened.
[in]oflagValues for oflag are constructed by a bitwise-inclusive OR of open flags. see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::available ()
+
+inlineinherited
+
+
Returns
The number of bytes available from the current position to EOF for normal files. Zero is returned for directory files.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::clearError ()
+
+inlineinherited
+
+

Clear all error bits.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::clearWriteError ()
+
+inlineinherited
+
+

Set writeError to zero

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::close ()
+
+inherited
+
+

Close a file and force cached data and directory information to be written to the storage device.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::contiguousRange (uint32_t * bgnBlock,
uint32_t * endBlock 
)
+
+inherited
+
+

Check for contiguous file and return its raw block range.

+
Parameters
+ + + +
[out]bgnBlockthe first block address for the file.
[out]endBlockthe last block address for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::createContiguous (FatFiledirFile,
const char * path,
uint32_t size 
)
+
+inherited
+
+

Create and open a new contiguous file of a specified size.

+
Parameters
+ + + + +
[in]dirFileThe directory where the file will be created.
[in]pathA path with a validfile name.
[in]sizeThe desired file size.
+
+
+
Returns
The value true is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::createContiguous (const char * path,
uint32_t size 
)
+
+inlineinherited
+
+

Create and open a new contiguous file of a specified size.

+
Parameters
+ + + +
[in]pathA path with a validfile name.
[in]sizeThe desired file size.
+
+
+
Returns
The value true is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::curCluster () const
+
+inlineinherited
+
+
Returns
The current cluster number for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::curPosition () const
+
+inlineinherited
+
+
Returns
The current position for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static FatFile* FatFile::cwd ()
+
+inlinestaticinherited
+
+
Returns
Current working directory
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::dateTimeCallback (void(*)(uint16_t *date, uint16_t *time) dateTime)
+
+inlinestaticinherited
+
+

Set the date/time callback function

+
Parameters
+ + +
[in]dateTimeThe user's call back function. The callback function is of the form:
+
+
+
void dateTime(uint16_t* date, uint16_t* time) {
+
uint16_t year;
+
uint8_t month, day, hour, minute, second;
+
+
// User gets date and time from GPS or real-time clock here
+
+
// return date using FAT_DATE macro to format fields
+
*date = FAT_DATE(year, month, day);
+
+
// return time using FAT_TIME macro to format fields
+
*time = FAT_TIME(hour, minute, second);
+
}
+

Sets the function that is called when a file is created or when a file's directory entry is modified by sync(). All timestamps, access, creation, and modify, are set when a file is created. sync() maintains the last access date and last modify date/time.

+

See the timestamp() function.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static void FatFile::dateTimeCallbackCancel ()
+
+inlinestaticinherited
+
+

Cancel the date/time callback function.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::dirEntry (dir_tdir)
+
+inherited
+
+

Return a file's directory entry.

+
Parameters
+ + +
[out]dirLocation for return of the file's directory entry.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatFile::dirIndex ()
+
+inlineinherited
+
+
Returns
The index of this file in it's directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t FatFile::dirName (const dir_tdir,
char * name 
)
+
+staticinherited
+
+

Format the name field of dir into the 13 byte array name in standard 8.3 short name format.

+
Parameters
+ + + +
[in]dirThe directory structure containing the name.
[out]nameA 13 byte char array for the formatted name.
+
+
+
Returns
length of the name.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::dirSize ()
+
+inherited
+
+
Returns
The number of bytes allocated to a directory or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFile::dmpFile (print_tpr,
uint32_t pos,
size_t n 
)
+
+inherited
+
+

Dump file in Hex

Parameters
+ + + + +
[in]prPrint stream for list.
[in]posStart position in file.
[in]nnumber of locations to dump.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::exists (const char * path)
+
+inlineinherited
+
+

Test for the existence of a file in a directory

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+

The calling instance must be an open directory file.

+

dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory dirFile.

+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
int16_t FatFile::fgets (char * str,
int16_t num,
char * delim = 0 
)
+
+inherited
+
+

Get a string from a file.

+

fgets() reads bytes from a file into the array pointed to by str, until num - 1 bytes are read, or a delimiter is read and transferred to str, or end-of-file is encountered. The string is then terminated with a null byte.

+

fgets() deletes CR, '\r', from the string. This insures only a '\n' terminates the string for Windows text files which use CRLF for newline.

+
Parameters
+ + + + +
[out]strPointer to the array where the string is stored.
[in]numMaximum number of characters to be read (including the final null byte). Usually the length of the array str is used.
[in]delimOptional set of delimiters. The default is "\n".
+
+
+
Returns
For success fgets() returns the length of the string in str. If no data is read, fgets() returns zero for EOF or -1 if an error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatFile::fileAttr () const
+
+inlineinherited
+
+

Type of file. You should use isFile() or isDir() instead of fileType() if possible.

+
Returns
The file or directory type.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::fileSize () const
+
+inlineinherited
+
+
Returns
The total number of bytes in a file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::firstBlock ()
+
+inlineinherited
+
+
Returns
first block of file or zero for empty file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::firstCluster () const
+
+inlineinherited
+
+
Returns
The first cluster number for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatFile::getError ()
+
+inlineinherited
+
+
Returns
All error bits.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::getName (char * name,
size_t size 
)
+
+inherited
+
+

Get a file's name followed by a zero byte.

+
Parameters
+ + + +
[out]nameAn array of characters for the file's name.
[in]sizeThe size of the array in bytes. The array must be at least 13 bytes long. The file's name will be truncated if the file's name is too long.
+
+
+
Returns
The value true, is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::getpos (FatPos_tpos)
+
+inherited
+
+

get position for streams

Parameters
+ + +
[out]posstruct to receive position
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::getSFN (char * name)
+
+inherited
+
+

Get a file's Short File Name followed by a zero byte.

+
Parameters
+ + +
[out]nameAn array of characters for the file's name. The array must be at least 13 bytes long.
+
+
+
Returns
The value true, is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::getWriteError ()
+
+inlineinherited
+
+
Returns
value of writeError
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isDir () const
+
+inlineinherited
+
+
Returns
True if this is a directory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isFile () const
+
+inlineinherited
+
+
Returns
True if this is a normal file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isHidden () const
+
+inlineinherited
+
+
Returns
True if this is a hidden file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isLFN () const
+
+inlineinherited
+
+
Returns
true if this file has a Long File Name.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isOpen () const
+
+inlineinherited
+
+
Returns
True if this is an open file/directory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isReadOnly () const
+
+inlineinherited
+
+
Returns
True if file is read-only
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRoot () const
+
+inlineinherited
+
+
Returns
True if this is the root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRoot32 () const
+
+inlineinherited
+
+
Returns
True if this is the FAT32 root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRootFixed () const
+
+inlineinherited
+
+
Returns
True if this is the FAT12 of FAT16 root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isSubDir () const
+
+inlineinherited
+
+
Returns
True if this is a subdirectory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isSystem () const
+
+inlineinherited
+
+
Returns
True if this is a system file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static bool FatFile::legal83Char (uint8_t c)
+
+inlinestaticinherited
+
+

Check for a legal 8.3 character.

Parameters
+ + +
[in]cCharacter to be checked.
+
+
+
Returns
true for a legal 8.3 character else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::ls (uint8_t flags = 0)
+
+inlineinherited
+
+

List directory contents.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFile::ls (print_tpr,
uint8_t flags = 0,
uint8_t indent = 0 
)
+
+inherited
+
+

List directory contents.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+
Parameters
+ + +
[in]indentAmount of space before file name. Used for recursive list to indicate subdirectory level.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::mkdir (FatFiledir,
const char * path,
bool pFlag = true 
)
+
+inherited
+
+

Make a new directory.

+
Parameters
+ + + + +
[in]dirAn open FatFile instance for the directory that will contain the new directory.
[in]pathA path with a valid 8.3 DOS name for the new directory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFileSystemfs,
const char * path,
uint8_t oflag 
)
+
+inherited
+
+

Open a file in the volume working directory of a FatFileSystem.

+
Parameters
+ + + + +
[in]fsFile System where the file is located.
[in]pathwith a valid 8.3 DOS name for a file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFiledirFile,
uint16_t index,
uint8_t oflag 
)
+
+inherited
+
+

Open a file by index.

+
Parameters
+ + + + +
[in]dirFileAn open FatFile instance for the directory.
[in]indexThe index of the directory entry for the file to be opened. The value for index is (directory file position)/32.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+

See open() by path for definition of flags.

Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFiledirFile,
const char * path,
uint8_t oflag 
)
+
+inherited
+
+

Open a file or directory by name.

+
Parameters
+ + + + +
[in]dirFileAn open FatFile instance for the directory containing the file to be opened.
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagValues for oflag are constructed by a bitwise-inclusive OR of flags from the following list
+
+
+

O_READ - Open for reading.

+

O_RDONLY - Same as O_READ.

+

O_WRITE - Open for writing.

+

O_WRONLY - Same as O_WRITE.

+

O_RDWR - Open for reading and writing.

+

O_APPEND - If set, the file offset shall be set to the end of the file prior to each write.

+

O_AT_END - Set the initial position at the end of the file.

+

O_CREAT - If the file exists, this flag has no effect except as noted under O_EXCL below. Otherwise, the file shall be created

+

O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.

+

O_SYNC - Call sync() after each write. This flag should not be used with write(uint8_t) or any functions do character at a time writes since sync() will be called after each byte.

+

O_TRUNC - If the file exists and is a regular file, and the file is successfully opened and is not read only, its length shall be truncated to 0.

+

WARNING: A given file must not be opened by more than one FatFile object or file corruption may occur.

+
Note
Directory files must be opened read only. Write and truncation is not allowed for directory files.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::open (const char * path,
uint8_t oflag = O_READ 
)
+
+inlineinherited
+
+

Open a file in the current working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::openNext (FatFiledirFile,
uint8_t oflag = O_READ 
)
+
+inherited
+
+

Open the next file or subdirectory in a directory.

+
Parameters
+ + + +
[in]dirFileAn open FatFile instance for the directory containing the file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::openRoot (FatVolumevol)
+
+inherited
+
+

Open a volume's root directory.

+
Parameters
+ + +
[in]volThe FAT volume containing the root directory to be opened.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int FatFile::peek ()
+
+inherited
+
+

Return the next available byte without consuming it.

+
Returns
The byte if no error and not at eof else -1;
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::printCreateDateTime (print_tpr)
+
+inherited
+
+

Print a file's creation date and time

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::printFatDate (uint16_t fatDate)
+
+inlinestaticinherited
+
+

Print a directory date field.

+

Format is yyyy-mm-dd.

+
Parameters
+ + +
[in]fatDateThe date field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFile::printFatDate (print_tpr,
uint16_t fatDate 
)
+
+staticinherited
+
+

Print a directory date field.

+

Format is yyyy-mm-dd.

+
Parameters
+ + + +
[in]prPrint stream for output.
[in]fatDateThe date field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::printFatTime (uint16_t fatTime)
+
+inlinestaticinherited
+
+

Print a directory time field.

+

Format is hh:mm:ss.

+
Parameters
+ + +
[in]fatTimeThe time field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFile::printFatTime (print_tpr,
uint16_t fatTime 
)
+
+staticinherited
+
+

Print a directory time field.

+

Format is hh:mm:ss.

+
Parameters
+ + + +
[in]prPrint stream for output.
[in]fatTimeThe time field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
int FatFile::printField (float value,
char term,
uint8_t prec = 2 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
[in]precNumber of digits after decimal point.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (int16_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (uint16_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (int32_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (uint32_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printFileSize (print_tpr)
+
+inherited
+
+

Print a file's size.

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The number of characters printed is returned for success and zero is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::printModifyDateTime (print_tpr)
+
+inherited
+
+

Print a file's modify date and time

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t FatFile::printName ()
+
+inlineinherited
+
+

Print a file's name.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printName (print_tpr)
+
+inherited
+
+

Print a file's name

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printSFN (print_tpr)
+
+inherited
+
+

Print a file's Short File Name.

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The number of characters printed is returned for success and zero is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int FatFile::read ()
+
+inlineinherited
+
+

Read the next byte from a file.

+
Returns
For success read returns the next byte in the file as an int. If an error occurs or end of file is reached -1 is returned.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::read (void * buf,
size_t nbyte 
)
+
+inherited
+
+

Read data from a file starting at the current position.

+
Parameters
+ + + +
[out]bufPointer to the location that will receive the data.
[in]nbyteMaximum number of bytes to read.
+
+
+
Returns
For success read() returns the number of bytes read. A value less than nbyte, including zero, will be returned if end of file is reached. If an error occurs, read() returns -1. Possible errors include read() called before a file has been opened, corrupt file system or an I/O error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int8_t FatFile::readDir (dir_tdir)
+
+inherited
+
+

Read the next directory entry from a directory file.

+
Parameters
+ + +
[out]dirThe dir_t struct that will receive the data.
+
+
+
Returns
For success readDir() returns the number of bytes read. A value of zero will be returned if end of file is reached. If an error occurs, readDir() returns -1. Possible errors include readDir() called before a directory has been opened, this is not a directory file or an I/O error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::remove ()
+
+inherited
+
+

Remove a file.

+

The directory entry and all data for the file are deleted.

+
Note
This function should not be used to delete the 8.3 version of a file that has a long name. For example if a file has the long name "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::remove (FatFiledirFile,
const char * path 
)
+
+staticinherited
+
+

Remove a file.

+

The directory entry and all data for the file are deleted.

+
Parameters
+ + + +
[in]dirFileThe directory that contains the file.
[in]pathPath for the file to be removed.
+
+
+
Note
This function should not be used to delete the 8.3 version of a file that has a long name. For example if a file has the long name "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::rename (FatFiledirFile,
const char * newPath 
)
+
+inherited
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]dirFileDirectory for the new path.
[in]newPathNew path name for the file/directory.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::rewind ()
+
+inlineinherited
+
+

Set the file's current position to zero.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::rmdir ()
+
+inherited
+
+

Remove a directory file.

+

The directory file will be removed only if it is empty and is not the root directory. rmdir() follows DOS and Windows and ignores the read-only attribute for the directory.

+
Note
This function should not be used to delete the 8.3 version of a directory that has a long name. For example if a directory has the long name "New folder" you should not delete the 8.3 name "NEWFOL~1".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::rmRfStar ()
+
+inherited
+
+

Recursively delete a directory and all contained files.

+

This is like the Unix/Linux 'rm -rf *' if called with the root directory hence the name.

+

Warning - This will remove all contents of the directory including subdirectories. The directory will then be removed if it is not root. The read-only attribute for files will be ignored.

+
Note
This function should not be used to delete the 8.3 version of a directory that has a long name. See remove() and rmdir().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekCur (int32_t offset)
+
+inlineinherited
+
+

Set the files position to current position + pos. See seekSet().

Parameters
+ + +
[in]offsetThe new position in bytes from the current position.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekEnd (int32_t offset = 0)
+
+inlineinherited
+
+

Set the files position to end-of-file + offset. See seekSet(). Can't be used for directory files since file size is not defined.

Parameters
+ + +
[in]offsetThe new position in bytes from end-of-file.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekSet (uint32_t pos)
+
+inherited
+
+

Sets a file's position.

+
Parameters
+ + +
[in]posThe new position in bytes from the beginning of the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static bool FatFile::setCwd (FatFiledir)
+
+inlinestaticinherited
+
+

Set the current working directory.

+
Parameters
+ + +
[in]dirNew current working directory.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::setpos (FatPos_tpos)
+
+inherited
+
+

set position for streams

Parameters
+ + +
[out]posstruct with value for new position
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::sync ()
+
+inherited
+
+

The sync() call causes all modified data and directory fields to be written to the storage device.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::timestamp (FatFilefile)
+
+inherited
+
+

Copy a file's timestamps

+
Parameters
+ + +
[in]fileFile to copy timestamps from.
+
+
+
Note
Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::timestamp (uint8_t flags,
uint16_t year,
uint8_t month,
uint8_t day,
uint8_t hour,
uint8_t minute,
uint8_t second 
)
+
+inherited
+
+

Set a file's timestamps in its directory entry.

+
Parameters
+ + +
[in]flagsValues for flags are constructed by a bitwise-inclusive OR of flags from the following list
+
+
+

T_ACCESS - Set the file's last access date.

+

T_CREATE - Set the file's creation date and time.

+

T_WRITE - Set the file's last write/modification date and time.

+
Parameters
+ + + + + + + +
[in]yearValid range 1980 - 2107 inclusive.
[in]monthValid range 1 - 12 inclusive.
[in]dayValid range 1 - 31 inclusive.
[in]hourValid range 0 - 23 inclusive.
[in]minuteValid range 0 - 59 inclusive.
[in]secondValid range 0 - 59 inclusive
+
+
+
Note
It is possible to set an invalid date since there is no check for the number of days in a month.
+
+Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::truncate (uint32_t length)
+
+inherited
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + +
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFile::volume () const
+
+inlineinherited
+
+
Returns
FatVolume that contains this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int FatFile::write (const char * str)
+
+inlineinherited
+
+

Write a string to a file. Used by the Arduino Print class.

Parameters
+ + +
[in]strPointer to the string. Use getWriteError to check for errors.
+
+
+
Returns
count of characters written for success or -1 for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int FatFile::write (uint8_t b)
+
+inlineinherited
+
+

Write a single byte.

Parameters
+ + +
[in]bThe byte to be written.
+
+
+
Returns
+1 for success or -1 for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::write (const void * buf,
size_t nbyte 
)
+
+inherited
+
+

Write data to an open file.

+
Note
Data is moved to the cache but may not be written to the storage device until sync() is called.
+
Parameters
+ + + +
[in]bufPointer to the location of the data to be written.
[in]nbyteNumber of bytes to write.
+
+
+
Returns
For success write() returns the number of bytes written, always nbyte. If an error occurs, write() returns -1. Possible errors include write() is called before a file has been opened, write is called for a read-only file, device is full, a corrupt file system or an I/O error.
+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/SdFat.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_base_file__coll__graph.png b/libraries/SdFat/extras/html/class_sd_base_file__coll__graph.png new file mode 100644 index 0000000..6337c9e Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_base_file__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_base_file__inherit__graph.png b/libraries/SdFat/extras/html/class_sd_base_file__inherit__graph.png new file mode 100644 index 0000000..6337c9e Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_base_file__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_fat-members.html b/libraries/SdFat/extras/html/class_sd_fat-members.html new file mode 100644 index 0000000..4ea22a4 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_fat-members.html @@ -0,0 +1,168 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdFat Member List
+
+
+ +

This is the complete list of members for SdFat, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin(uint8_t csPin=SS, SPISettings spiSettings=SPI_FULL_SPEED)SdFatinline
SdFileSystem< SdSpiCard >::begin()SdFileSystem< SdSpiCard >inline
FatFileSystem::begin(BlockDriver *blockDev, uint8_t part=0)FatFileSysteminline
blocksPerCluster() const FatVolumeinline
blocksPerFat() const FatVolumeinline
cacheClear()FatVolumeinline
card()SdFileSystem< SdSpiCard >inline
cardBegin(uint8_t csPin=SS, SPISettings settings=SPI_FULL_SPEED)SdFatinline
cardErrorCode()SdFileSystem< SdSpiCard >inline
cardErrorData()SdFileSystem< SdSpiCard >inline
chdir(bool set_cwd=false)FatFileSysteminline
chdir(const char *path, bool set_cwd=false)FatFileSysteminline
chvol()FatFileSysteminline
clusterCount() const FatVolumeinline
clusterSizeShift() const FatVolumeinline
dataStartBlock() const FatVolumeinline
dbgFat(uint32_t n, uint32_t *v)FatVolumeinline
errorHalt()SdFileSystem< SdSpiCard >inline
errorHalt(Print *pr)SdFileSystem< SdSpiCard >inline
errorHalt(char const *msg)SdFileSystem< SdSpiCard >inline
errorHalt(Print *pr, char const *msg)SdFileSystem< SdSpiCard >inline
errorHalt(const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
errorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
errorPrint()SdFileSystem< SdSpiCard >inline
errorPrint(Print *pr)SdFileSystem< SdSpiCard >inline
errorPrint(const char *msg)SdFileSystem< SdSpiCard >inline
errorPrint(Print *pr, char const *msg)SdFileSystem< SdSpiCard >inline
errorPrint(const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
errorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
exists(const char *path)FatFileSysteminline
fatCount()FatVolumeinline
fatStartBlock() const FatVolumeinline
fatType() const FatVolumeinline
FatVolume()FatVolumeinline
freeClusterCount()FatVolume
fsBegin()SdFatinline
init()FatVolumeinline
init(uint8_t part)FatVolume
initErrorHalt()SdFileSystem< SdSpiCard >inline
initErrorHalt(Print *pr)SdFileSystem< SdSpiCard >inline
initErrorHalt(char const *msg)SdFileSystem< SdSpiCard >inline
initErrorHalt(Print *pr, char const *msg)SdFileSystem< SdSpiCard >inline
initErrorHalt(const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
initErrorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
initErrorPrint()SdFileSystem< SdSpiCard >inline
initErrorPrint(Print *pr)SdFileSystem< SdSpiCard >inline
initErrorPrint(char const *msg)SdFileSystem< SdSpiCard >inline
initErrorPrint(Print *pr, char const *msg)SdFileSystem< SdSpiCard >inline
initErrorPrint(const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
initErrorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
ls(uint8_t flags=0)FatFileSysteminline
ls(const char *path, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, const char *path, uint8_t flags)FatFileSysteminline
mkdir(const char *path, bool pFlag=true)FatFileSysteminline
open(const char *path, uint8_t mode=FILE_READ)FatFileSysteminline
open(const String &path, uint8_t mode=FILE_READ)FatFileSysteminline
remove(const char *path)FatFileSysteminline
rename(const char *oldPath, const char *newPath)FatFileSysteminline
rmdir(const char *path)FatFileSysteminline
rootDirEntryCount() const FatVolumeinline
rootDirStart() const FatVolumeinline
SdFat() (defined in SdFat)SdFatinline
SdFat(uint8_t spiPort)SdFatinlineexplicit
truncate(const char *path, uint32_t length)FatFileSysteminline
vol()FatFileSysteminline
volumeBlockCount() const FatVolumeinline
vwd()FatFileSysteminline
wipe(print_t *pr=0)FatFileSysteminline
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_fat.html b/libraries/SdFat/extras/html/class_sd_fat.html new file mode 100644 index 0000000..96214e7 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_fat.html @@ -0,0 +1,2436 @@ + + + + + + +SdFat: SdFat Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
SdFat Class Reference
+
+
+ +

Main file system class for SdFat library. + More...

+ +

#include <SdFat.h>

+
+Inheritance diagram for SdFat:
+
+
Inheritance graph
+ + + + + +
[legend]
+
+Collaboration diagram for SdFat:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin (BlockDriver *blockDev, uint8_t part=0)
 
bool begin ()
 
bool begin (uint8_t csPin=SS, SPISettings spiSettings=SPI_FULL_SPEED)
 
uint8_t blocksPerCluster () const
 
uint32_t blocksPerFat () const
 
cache_tcacheClear ()
 
SdSpiCardcard ()
 
bool cardBegin (uint8_t csPin=SS, SPISettings settings=SPI_FULL_SPEED)
 
uint8_t cardErrorCode ()
 
uint32_t cardErrorData ()
 
bool chdir (bool set_cwd=false)
 
bool chdir (const char *path, bool set_cwd=false)
 
void chvol ()
 
uint32_t clusterCount () const
 
uint8_t clusterSizeShift () const
 
uint32_t dataStartBlock () const
 
int8_t dbgFat (uint32_t n, uint32_t *v)
 
void errorHalt ()
 
void errorHalt (Print *pr)
 
void errorHalt (char const *msg)
 
void errorHalt (Print *pr, char const *msg)
 
void errorHalt (const __FlashStringHelper *msg)
 
void errorHalt (Print *pr, const __FlashStringHelper *msg)
 
void errorPrint ()
 
void errorPrint (Print *pr)
 
void errorPrint (const char *msg)
 
void errorPrint (Print *pr, char const *msg)
 
void errorPrint (const __FlashStringHelper *msg)
 
void errorPrint (Print *pr, const __FlashStringHelper *msg)
 
bool exists (const char *path)
 
uint8_t fatCount ()
 
uint32_t fatStartBlock () const
 
uint8_t fatType () const
 
int32_t freeClusterCount ()
 
bool fsBegin ()
 
bool init ()
 
bool init (uint8_t part)
 
void initErrorHalt ()
 
void initErrorHalt (Print *pr)
 
void initErrorHalt (char const *msg)
 
void initErrorHalt (Print *pr, char const *msg)
 
void initErrorHalt (const __FlashStringHelper *msg)
 
void initErrorHalt (Print *pr, const __FlashStringHelper *msg)
 
void initErrorPrint ()
 
void initErrorPrint (Print *pr)
 
void initErrorPrint (char const *msg)
 
void initErrorPrint (Print *pr, char const *msg)
 
void initErrorPrint (const __FlashStringHelper *msg)
 
void initErrorPrint (Print *pr, const __FlashStringHelper *msg)
 
void ls (uint8_t flags=0)
 
void ls (const char *path, uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0)
 
void ls (print_t *pr, const char *path, uint8_t flags)
 
bool mkdir (const char *path, bool pFlag=true)
 
File open (const char *path, uint8_t mode=FILE_READ)
 
File open (const String &path, uint8_t mode=FILE_READ)
 
bool remove (const char *path)
 
bool rename (const char *oldPath, const char *newPath)
 
bool rmdir (const char *path)
 
uint16_t rootDirEntryCount () const
 
uint32_t rootDirStart () const
 
 SdFat (uint8_t spiPort)
 
bool truncate (const char *path, uint32_t length)
 
FatVolumevol ()
 
uint32_t volumeBlockCount () const
 
FatFilevwd ()
 
bool wipe (print_t *pr=0)
 
+

Detailed Description

+

Main file system class for SdFat library.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
SdFat::SdFat (uint8_t spiPort)
+
+inlineexplicit
+
+

Constructor with SPI port selection.

Parameters
+ + +
[in]spiPortSPI port number.
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::begin (BlockDriverblockDev,
uint8_t part = 0 
)
+
+inlineinherited
+
+

Initialize an FatFileSystem object.

Parameters
+ + + +
[in]blockDevDevice block driver.
[in]partpartition to initialize.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdFileSystem< SdSpiCard >::begin ()
+
+inlineinherited
+
+

Initialize file system.

Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdFat::begin (uint8_t csPin = SS,
SPISettings spiSettings = SPI_FULL_SPEED 
)
+
+inline
+
+

Initialize SD card and file system.

+
Parameters
+ + + +
[in]csPinSD card chip select pin.
[in]spiSettingsSPI speed, mode, and bit order.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::blocksPerCluster () const
+
+inlineinherited
+
+
Returns
The volume's cluster size in blocks.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::blocksPerFat () const
+
+inlineinherited
+
+
Returns
The number of blocks in one FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
cache_t* FatVolume::cacheClear ()
+
+inlineinherited
+
+

Clear the cache and returns a pointer to the cache. Not for normal apps.

Returns
A pointer to the cache buffer or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
SdSpiCard * SdFileSystem< SdSpiCard >::card ()
+
+inlineinherited
+
+
Returns
Pointer to SD card object
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdFat::cardBegin (uint8_t csPin = SS,
SPISettings settings = SPI_FULL_SPEED 
)
+
+inline
+
+

Initialize SD card for diagnostic use only.

+
Parameters
+ + + +
[in]csPinSD card chip select pin.
[in]settingsSPI speed, mode, and bit order.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t SdFileSystem< SdSpiCard >::cardErrorCode ()
+
+inlineinherited
+
+
Returns
The card error code
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t SdFileSystem< SdSpiCard >::cardErrorData ()
+
+inlineinherited
+
+
Returns
the card error data
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::chdir (bool set_cwd = false)
+
+inlineinherited
+
+

Change a volume's working directory to root

+

Changes the volume's working directory to the SD's root directory. Optionally set the current working directory to the volume's working directory.

+
Parameters
+ + +
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::chdir (const char * path,
bool set_cwd = false 
)
+
+inlineinherited
+
+

Change a volume's working directory

+

Changes the volume working directory to the path subdirectory. Optionally set the current working directory to the volume's working directory.

+

Example: If the volume's working directory is "/DIR", chdir("SUB") will change the volume's working directory from "/DIR" to "/DIR/SUB".

+

If path is "/", the volume's working directory will be changed to the root directory

+
Parameters
+ + + +
[in]pathThe name of the subdirectory.
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFileSystem::chvol ()
+
+inlineinherited
+
+

Set the current working directory to a volume's working directory.

+

This is useful with multiple SD cards.

+

The current working directory is changed to this volume's working directory.

+

This is like the Windows/DOS <drive letter>: command.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::clusterCount () const
+
+inlineinherited
+
+
Returns
The total number of clusters in the volume.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::clusterSizeShift () const
+
+inlineinherited
+
+
Returns
The shift count required to multiply by blocksPerCluster.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::dataStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of file data.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int8_t FatVolume::dbgFat (uint32_t n,
uint32_t * v 
)
+
+inlineinherited
+
+

Debug access to FAT table

+
Parameters
+ + + +
[in]ncluster number.
[out]vvalue of entry
+
+
+
Returns
true for success or false for failure
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt ()
+
+inlineinherited
+
+

Print any SD error code to Serial and halt.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt (Print * pr)
+
+inlineinherited
+
+

Print any SD error code and halt.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt (char const * msg)
+
+inlineinherited
+
+

Print msg, any SD error code and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint ()
+
+inlineinherited
+
+

Print any SD error code to Serial

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint (Print * pr)
+
+inlineinherited
+
+

Print any SD error code.

Parameters
+ + +
[in]prPrint device.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint (const char * msg)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::exists (const char * path)
+
+inlineinherited
+
+

Test for the existence of a file.

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatCount ()
+
+inlineinherited
+
+
Returns
The number of File Allocation Tables.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::fatStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the first FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatType () const
+
+inlineinherited
+
+
Returns
The FAT type of the volume. Values are 12, 16 or 32.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int32_t FatVolume::freeClusterCount ()
+
+inherited
+
+

Volume free space in clusters.

+
Returns
Count of free clusters for success or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdFat::fsBegin ()
+
+inline
+
+

Initialize file system for diagnostic use only.

Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatVolume::init ()
+
+inlineinherited
+
+

Initialize a FAT volume. Try partition one first then try super floppy format.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatVolume::init (uint8_t part)
+
+inherited
+
+

Initialize a FAT volume.

+
Parameters
+ + +
[in]partThe partition to be used. Legal values for part are 1-4 to use the corresponding partition on a device formatted with a MBR, Master Boot Record, or zero if the device is formatted as a super floppy with the FAT boot sector in block zero.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt ()
+
+inlineinherited
+
+

Print any SD error code and halt.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt (Print * pr)
+
+inlineinherited
+
+

Print error details and halt after begin fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt (char const * msg)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device for message.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint ()
+
+inlineinherited
+
+

Print error details after begin() fails.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint (Print * pr)
+
+inlineinherited
+
+

Print error details after begin() fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint (char const * msg)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFileSystem::ls (uint8_t flags = 0)
+
+inlineinherited
+
+

List the directory contents of the volume working directory to Serial.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (const char * path,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of a directory to Serial.

+
Parameters
+ + + +
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of the volume working directory.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
const char * path,
uint8_t flags 
)
+
+inlineinherited
+
+

List the directory contents of a directory.

+
Parameters
+ + + + +
[in]prPrint stream for list.
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::mkdir (const char * path,
bool pFlag = true 
)
+
+inlineinherited
+
+

Make a subdirectory in the volume working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const char * path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const String & path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::remove (const char * path)
+
+inlineinherited
+
+

Remove a file from the volume working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::rename (const char * oldPath,
const char * newPath 
)
+
+inlineinherited
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]oldPathPath name to the file or subdirectory to be renamed.
[in]newPathNew path name of the file or subdirectory.
+
+
+

The newPath object must not exist before the rename call.

+

The file to be renamed must not be open. The directory entry may be moved and file system corruption could occur if the file is accessed by a file object that was opened before the rename() call.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::rmdir (const char * path)
+
+inlineinherited
+
+

Remove a subdirectory from the volume's working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
+
+
+

The subdirectory file will be removed only if it is empty.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatVolume::rootDirEntryCount () const
+
+inlineinherited
+
+
Returns
The number of entries in the root directory for FAT16 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::rootDirStart () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the root directory on FAT16 volumes or the first cluster number on FAT32 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::truncate (const char * path,
uint32_t length 
)
+
+inlineinherited
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the file.
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFileSystem::vol ()
+
+inlineinherited
+
+
Returns
a pointer to the FatVolume object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::volumeBlockCount () const
+
+inlineinherited
+
+
Returns
The number of blocks in the volume
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatFile* FatFileSystem::vwd ()
+
+inlineinherited
+
+
Returns
a pointer to the volume working directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::wipe (print_tpr = 0)
+
+inlineinherited
+
+

Wipe all data from the volume. You must reinitialize the volume before accessing it again.

Parameters
+ + +
[in]prprint stream for status dots.
+
+
+
Returns
true for success else false.
+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/SdFat.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_fat__coll__graph.png b/libraries/SdFat/extras/html/class_sd_fat__coll__graph.png new file mode 100644 index 0000000..323a75e Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_fat__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_fat__inherit__graph.png b/libraries/SdFat/extras/html/class_sd_fat__inherit__graph.png new file mode 100644 index 0000000..323a75e Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_fat__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_fat_e_x-members.html b/libraries/SdFat/extras/html/class_sd_fat_e_x-members.html new file mode 100644 index 0000000..b283f66 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_fat_e_x-members.html @@ -0,0 +1,166 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdFatEX Member List
+
+
+ +

This is the complete list of members for SdFatEX, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin(uint8_t csPin=SS, SPISettings spiSettings=SPI_FULL_SPEED)SdFatEXinline
SdFileSystem< SdSpiCardEX >::begin()SdFileSystem< SdSpiCardEX >inline
FatFileSystem::begin(BlockDriver *blockDev, uint8_t part=0)FatFileSysteminline
blocksPerCluster() const FatVolumeinline
blocksPerFat() const FatVolumeinline
cacheClear()FatVolumeinline
card()SdFileSystem< SdSpiCardEX >inline
cardErrorCode()SdFileSystem< SdSpiCardEX >inline
cardErrorData()SdFileSystem< SdSpiCardEX >inline
chdir(bool set_cwd=false)FatFileSysteminline
chdir(const char *path, bool set_cwd=false)FatFileSysteminline
chvol()FatFileSysteminline
clusterCount() const FatVolumeinline
clusterSizeShift() const FatVolumeinline
dataStartBlock() const FatVolumeinline
dbgFat(uint32_t n, uint32_t *v)FatVolumeinline
errorHalt()SdFileSystem< SdSpiCardEX >inline
errorHalt(Print *pr)SdFileSystem< SdSpiCardEX >inline
errorHalt(char const *msg)SdFileSystem< SdSpiCardEX >inline
errorHalt(Print *pr, char const *msg)SdFileSystem< SdSpiCardEX >inline
errorHalt(const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
errorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
errorPrint()SdFileSystem< SdSpiCardEX >inline
errorPrint(Print *pr)SdFileSystem< SdSpiCardEX >inline
errorPrint(const char *msg)SdFileSystem< SdSpiCardEX >inline
errorPrint(Print *pr, char const *msg)SdFileSystem< SdSpiCardEX >inline
errorPrint(const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
errorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
exists(const char *path)FatFileSysteminline
fatCount()FatVolumeinline
fatStartBlock() const FatVolumeinline
fatType() const FatVolumeinline
FatVolume()FatVolumeinline
freeClusterCount()FatVolume
init()FatVolumeinline
init(uint8_t part)FatVolume
initErrorHalt()SdFileSystem< SdSpiCardEX >inline
initErrorHalt(Print *pr)SdFileSystem< SdSpiCardEX >inline
initErrorHalt(char const *msg)SdFileSystem< SdSpiCardEX >inline
initErrorHalt(Print *pr, char const *msg)SdFileSystem< SdSpiCardEX >inline
initErrorHalt(const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
initErrorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
initErrorPrint()SdFileSystem< SdSpiCardEX >inline
initErrorPrint(Print *pr)SdFileSystem< SdSpiCardEX >inline
initErrorPrint(char const *msg)SdFileSystem< SdSpiCardEX >inline
initErrorPrint(Print *pr, char const *msg)SdFileSystem< SdSpiCardEX >inline
initErrorPrint(const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
initErrorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
ls(uint8_t flags=0)FatFileSysteminline
ls(const char *path, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, const char *path, uint8_t flags)FatFileSysteminline
mkdir(const char *path, bool pFlag=true)FatFileSysteminline
open(const char *path, uint8_t mode=FILE_READ)FatFileSysteminline
open(const String &path, uint8_t mode=FILE_READ)FatFileSysteminline
remove(const char *path)FatFileSysteminline
rename(const char *oldPath, const char *newPath)FatFileSysteminline
rmdir(const char *path)FatFileSysteminline
rootDirEntryCount() const FatVolumeinline
rootDirStart() const FatVolumeinline
SdFatEX() (defined in SdFatEX)SdFatEXinline
SdFatEX(uint8_t spiPort)SdFatEXinlineexplicit
truncate(const char *path, uint32_t length)FatFileSysteminline
vol()FatFileSysteminline
volumeBlockCount() const FatVolumeinline
vwd()FatFileSysteminline
wipe(print_t *pr=0)FatFileSysteminline
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_fat_e_x.html b/libraries/SdFat/extras/html/class_sd_fat_e_x.html new file mode 100644 index 0000000..33f77ab --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_fat_e_x.html @@ -0,0 +1,2365 @@ + + + + + + +SdFat: SdFatEX Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
SdFatEX Class Reference
+
+
+ +

SdFat class with extended SD I/O. + More...

+ +

#include <SdFat.h>

+
+Inheritance diagram for SdFatEX:
+
+
Inheritance graph
+ + + + + +
[legend]
+
+Collaboration diagram for SdFatEX:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin (BlockDriver *blockDev, uint8_t part=0)
 
bool begin ()
 
bool begin (uint8_t csPin=SS, SPISettings spiSettings=SPI_FULL_SPEED)
 
uint8_t blocksPerCluster () const
 
uint32_t blocksPerFat () const
 
cache_tcacheClear ()
 
SdSpiCardEXcard ()
 
uint8_t cardErrorCode ()
 
uint32_t cardErrorData ()
 
bool chdir (bool set_cwd=false)
 
bool chdir (const char *path, bool set_cwd=false)
 
void chvol ()
 
uint32_t clusterCount () const
 
uint8_t clusterSizeShift () const
 
uint32_t dataStartBlock () const
 
int8_t dbgFat (uint32_t n, uint32_t *v)
 
void errorHalt ()
 
void errorHalt (Print *pr)
 
void errorHalt (char const *msg)
 
void errorHalt (Print *pr, char const *msg)
 
void errorHalt (const __FlashStringHelper *msg)
 
void errorHalt (Print *pr, const __FlashStringHelper *msg)
 
void errorPrint ()
 
void errorPrint (Print *pr)
 
void errorPrint (const char *msg)
 
void errorPrint (Print *pr, char const *msg)
 
void errorPrint (const __FlashStringHelper *msg)
 
void errorPrint (Print *pr, const __FlashStringHelper *msg)
 
bool exists (const char *path)
 
uint8_t fatCount ()
 
uint32_t fatStartBlock () const
 
uint8_t fatType () const
 
int32_t freeClusterCount ()
 
bool init ()
 
bool init (uint8_t part)
 
void initErrorHalt ()
 
void initErrorHalt (Print *pr)
 
void initErrorHalt (char const *msg)
 
void initErrorHalt (Print *pr, char const *msg)
 
void initErrorHalt (const __FlashStringHelper *msg)
 
void initErrorHalt (Print *pr, const __FlashStringHelper *msg)
 
void initErrorPrint ()
 
void initErrorPrint (Print *pr)
 
void initErrorPrint (char const *msg)
 
void initErrorPrint (Print *pr, char const *msg)
 
void initErrorPrint (const __FlashStringHelper *msg)
 
void initErrorPrint (Print *pr, const __FlashStringHelper *msg)
 
void ls (uint8_t flags=0)
 
void ls (const char *path, uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0)
 
void ls (print_t *pr, const char *path, uint8_t flags)
 
bool mkdir (const char *path, bool pFlag=true)
 
File open (const char *path, uint8_t mode=FILE_READ)
 
File open (const String &path, uint8_t mode=FILE_READ)
 
bool remove (const char *path)
 
bool rename (const char *oldPath, const char *newPath)
 
bool rmdir (const char *path)
 
uint16_t rootDirEntryCount () const
 
uint32_t rootDirStart () const
 
 SdFatEX (uint8_t spiPort)
 
bool truncate (const char *path, uint32_t length)
 
FatVolumevol ()
 
uint32_t volumeBlockCount () const
 
FatFilevwd ()
 
bool wipe (print_t *pr=0)
 
+

Detailed Description

+

SdFat class with extended SD I/O.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
SdFatEX::SdFatEX (uint8_t spiPort)
+
+inlineexplicit
+
+

Constructor with SPI port selection.

Parameters
+ + +
[in]spiPortSPI port number.
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::begin (BlockDriverblockDev,
uint8_t part = 0 
)
+
+inlineinherited
+
+

Initialize an FatFileSystem object.

Parameters
+ + + +
[in]blockDevDevice block driver.
[in]partpartition to initialize.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdFileSystem< SdSpiCardEX >::begin ()
+
+inlineinherited
+
+

Initialize file system.

Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdFatEX::begin (uint8_t csPin = SS,
SPISettings spiSettings = SPI_FULL_SPEED 
)
+
+inline
+
+

Initialize SD card and file system.

+
Parameters
+ + + +
[in]csPinSD card chip select pin.
[in]spiSettingsSPI speed, mode, and bit order.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::blocksPerCluster () const
+
+inlineinherited
+
+
Returns
The volume's cluster size in blocks.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::blocksPerFat () const
+
+inlineinherited
+
+
Returns
The number of blocks in one FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
cache_t* FatVolume::cacheClear ()
+
+inlineinherited
+
+

Clear the cache and returns a pointer to the cache. Not for normal apps.

Returns
A pointer to the cache buffer or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
SdSpiCardEX * SdFileSystem< SdSpiCardEX >::card ()
+
+inlineinherited
+
+
Returns
Pointer to SD card object
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t SdFileSystem< SdSpiCardEX >::cardErrorCode ()
+
+inlineinherited
+
+
Returns
The card error code
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t SdFileSystem< SdSpiCardEX >::cardErrorData ()
+
+inlineinherited
+
+
Returns
the card error data
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::chdir (bool set_cwd = false)
+
+inlineinherited
+
+

Change a volume's working directory to root

+

Changes the volume's working directory to the SD's root directory. Optionally set the current working directory to the volume's working directory.

+
Parameters
+ + +
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::chdir (const char * path,
bool set_cwd = false 
)
+
+inlineinherited
+
+

Change a volume's working directory

+

Changes the volume working directory to the path subdirectory. Optionally set the current working directory to the volume's working directory.

+

Example: If the volume's working directory is "/DIR", chdir("SUB") will change the volume's working directory from "/DIR" to "/DIR/SUB".

+

If path is "/", the volume's working directory will be changed to the root directory

+
Parameters
+ + + +
[in]pathThe name of the subdirectory.
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFileSystem::chvol ()
+
+inlineinherited
+
+

Set the current working directory to a volume's working directory.

+

This is useful with multiple SD cards.

+

The current working directory is changed to this volume's working directory.

+

This is like the Windows/DOS <drive letter>: command.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::clusterCount () const
+
+inlineinherited
+
+
Returns
The total number of clusters in the volume.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::clusterSizeShift () const
+
+inlineinherited
+
+
Returns
The shift count required to multiply by blocksPerCluster.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::dataStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of file data.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int8_t FatVolume::dbgFat (uint32_t n,
uint32_t * v 
)
+
+inlineinherited
+
+

Debug access to FAT table

+
Parameters
+ + + +
[in]ncluster number.
[out]vvalue of entry
+
+
+
Returns
true for success or false for failure
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt ()
+
+inlineinherited
+
+

Print any SD error code to Serial and halt.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt (Print * pr)
+
+inlineinherited
+
+

Print any SD error code and halt.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt (char const * msg)
+
+inlineinherited
+
+

Print msg, any SD error code and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint ()
+
+inlineinherited
+
+

Print any SD error code to Serial

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint (Print * pr)
+
+inlineinherited
+
+

Print any SD error code.

Parameters
+ + +
[in]prPrint device.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint (const char * msg)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::exists (const char * path)
+
+inlineinherited
+
+

Test for the existence of a file.

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatCount ()
+
+inlineinherited
+
+
Returns
The number of File Allocation Tables.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::fatStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the first FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatType () const
+
+inlineinherited
+
+
Returns
The FAT type of the volume. Values are 12, 16 or 32.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int32_t FatVolume::freeClusterCount ()
+
+inherited
+
+

Volume free space in clusters.

+
Returns
Count of free clusters for success or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatVolume::init ()
+
+inlineinherited
+
+

Initialize a FAT volume. Try partition one first then try super floppy format.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatVolume::init (uint8_t part)
+
+inherited
+
+

Initialize a FAT volume.

+
Parameters
+ + +
[in]partThe partition to be used. Legal values for part are 1-4 to use the corresponding partition on a device formatted with a MBR, Master Boot Record, or zero if the device is formatted as a super floppy with the FAT boot sector in block zero.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt ()
+
+inlineinherited
+
+

Print any SD error code and halt.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt (Print * pr)
+
+inlineinherited
+
+

Print error details and halt after begin fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt (char const * msg)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device for message.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint ()
+
+inlineinherited
+
+

Print error details after begin() fails.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint (Print * pr)
+
+inlineinherited
+
+

Print error details after begin() fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint (char const * msg)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFileSystem::ls (uint8_t flags = 0)
+
+inlineinherited
+
+

List the directory contents of the volume working directory to Serial.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (const char * path,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of a directory to Serial.

+
Parameters
+ + + +
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of the volume working directory.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
const char * path,
uint8_t flags 
)
+
+inlineinherited
+
+

List the directory contents of a directory.

+
Parameters
+ + + + +
[in]prPrint stream for list.
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::mkdir (const char * path,
bool pFlag = true 
)
+
+inlineinherited
+
+

Make a subdirectory in the volume working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const char * path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const String & path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::remove (const char * path)
+
+inlineinherited
+
+

Remove a file from the volume working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::rename (const char * oldPath,
const char * newPath 
)
+
+inlineinherited
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]oldPathPath name to the file or subdirectory to be renamed.
[in]newPathNew path name of the file or subdirectory.
+
+
+

The newPath object must not exist before the rename call.

+

The file to be renamed must not be open. The directory entry may be moved and file system corruption could occur if the file is accessed by a file object that was opened before the rename() call.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::rmdir (const char * path)
+
+inlineinherited
+
+

Remove a subdirectory from the volume's working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
+
+
+

The subdirectory file will be removed only if it is empty.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatVolume::rootDirEntryCount () const
+
+inlineinherited
+
+
Returns
The number of entries in the root directory for FAT16 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::rootDirStart () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the root directory on FAT16 volumes or the first cluster number on FAT32 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::truncate (const char * path,
uint32_t length 
)
+
+inlineinherited
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the file.
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFileSystem::vol ()
+
+inlineinherited
+
+
Returns
a pointer to the FatVolume object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::volumeBlockCount () const
+
+inlineinherited
+
+
Returns
The number of blocks in the volume
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatFile* FatFileSystem::vwd ()
+
+inlineinherited
+
+
Returns
a pointer to the volume working directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::wipe (print_tpr = 0)
+
+inlineinherited
+
+

Wipe all data from the volume. You must reinitialize the volume before accessing it again.

Parameters
+ + +
[in]prprint stream for status dots.
+
+
+
Returns
true for success else false.
+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/SdFat.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_fat_e_x__coll__graph.png b/libraries/SdFat/extras/html/class_sd_fat_e_x__coll__graph.png new file mode 100644 index 0000000..4a85bc6 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_fat_e_x__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_fat_e_x__inherit__graph.png b/libraries/SdFat/extras/html/class_sd_fat_e_x__inherit__graph.png new file mode 100644 index 0000000..4a85bc6 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_fat_e_x__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_fat_sdio-members.html b/libraries/SdFat/extras/html/class_sd_fat_sdio-members.html new file mode 100644 index 0000000..902f6a8 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_fat_sdio-members.html @@ -0,0 +1,165 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdFatSdio Member List
+
+
+ +

This is the complete list of members for SdFatSdio, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin()SdFatSdioinline
FatFileSystem::begin(BlockDriver *blockDev, uint8_t part=0)FatFileSysteminline
blocksPerCluster() const FatVolumeinline
blocksPerFat() const FatVolumeinline
cacheClear()FatVolumeinline
card()SdFileSystem< SdioCard >inline
cardBegin()SdFatSdioinline
cardErrorCode()SdFileSystem< SdioCard >inline
cardErrorData()SdFileSystem< SdioCard >inline
chdir(bool set_cwd=false)FatFileSysteminline
chdir(const char *path, bool set_cwd=false)FatFileSysteminline
chvol()FatFileSysteminline
clusterCount() const FatVolumeinline
clusterSizeShift() const FatVolumeinline
dataStartBlock() const FatVolumeinline
dbgFat(uint32_t n, uint32_t *v)FatVolumeinline
errorHalt()SdFileSystem< SdioCard >inline
errorHalt(Print *pr)SdFileSystem< SdioCard >inline
errorHalt(char const *msg)SdFileSystem< SdioCard >inline
errorHalt(Print *pr, char const *msg)SdFileSystem< SdioCard >inline
errorHalt(const __FlashStringHelper *msg)SdFileSystem< SdioCard >inline
errorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdioCard >inline
errorPrint()SdFileSystem< SdioCard >inline
errorPrint(Print *pr)SdFileSystem< SdioCard >inline
errorPrint(const char *msg)SdFileSystem< SdioCard >inline
errorPrint(Print *pr, char const *msg)SdFileSystem< SdioCard >inline
errorPrint(const __FlashStringHelper *msg)SdFileSystem< SdioCard >inline
errorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdioCard >inline
exists(const char *path)FatFileSysteminline
fatCount()FatVolumeinline
fatStartBlock() const FatVolumeinline
fatType() const FatVolumeinline
FatVolume()FatVolumeinline
freeClusterCount()FatVolume
fsBegin()SdFatSdioinline
init()FatVolumeinline
init(uint8_t part)FatVolume
initErrorHalt()SdFileSystem< SdioCard >inline
initErrorHalt(Print *pr)SdFileSystem< SdioCard >inline
initErrorHalt(char const *msg)SdFileSystem< SdioCard >inline
initErrorHalt(Print *pr, char const *msg)SdFileSystem< SdioCard >inline
initErrorHalt(const __FlashStringHelper *msg)SdFileSystem< SdioCard >inline
initErrorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdioCard >inline
initErrorPrint()SdFileSystem< SdioCard >inline
initErrorPrint(Print *pr)SdFileSystem< SdioCard >inline
initErrorPrint(char const *msg)SdFileSystem< SdioCard >inline
initErrorPrint(Print *pr, char const *msg)SdFileSystem< SdioCard >inline
initErrorPrint(const __FlashStringHelper *msg)SdFileSystem< SdioCard >inline
initErrorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdioCard >inline
ls(uint8_t flags=0)FatFileSysteminline
ls(const char *path, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, const char *path, uint8_t flags)FatFileSysteminline
mkdir(const char *path, bool pFlag=true)FatFileSysteminline
open(const char *path, uint8_t mode=FILE_READ)FatFileSysteminline
open(const String &path, uint8_t mode=FILE_READ)FatFileSysteminline
remove(const char *path)FatFileSysteminline
rename(const char *oldPath, const char *newPath)FatFileSysteminline
rmdir(const char *path)FatFileSysteminline
rootDirEntryCount() const FatVolumeinline
rootDirStart() const FatVolumeinline
truncate(const char *path, uint32_t length)FatFileSysteminline
vol()FatFileSysteminline
volumeBlockCount() const FatVolumeinline
vwd()FatFileSysteminline
wipe(print_t *pr=0)FatFileSysteminline
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_fat_sdio.html b/libraries/SdFat/extras/html/class_sd_fat_sdio.html new file mode 100644 index 0000000..b876bb1 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_fat_sdio.html @@ -0,0 +1,2340 @@ + + + + + + +SdFat: SdFatSdio Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
SdFatSdio Class Reference
+
+
+ +

SdFat class using SDIO. + More...

+ +

#include <SdFat.h>

+
+Inheritance diagram for SdFatSdio:
+
+
Inheritance graph
+ + + + + +
[legend]
+
+Collaboration diagram for SdFatSdio:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin (BlockDriver *blockDev, uint8_t part=0)
 
bool begin ()
 
uint8_t blocksPerCluster () const
 
uint32_t blocksPerFat () const
 
cache_tcacheClear ()
 
SdioCardcard ()
 
bool cardBegin ()
 
uint8_t cardErrorCode ()
 
uint32_t cardErrorData ()
 
bool chdir (bool set_cwd=false)
 
bool chdir (const char *path, bool set_cwd=false)
 
void chvol ()
 
uint32_t clusterCount () const
 
uint8_t clusterSizeShift () const
 
uint32_t dataStartBlock () const
 
int8_t dbgFat (uint32_t n, uint32_t *v)
 
void errorHalt ()
 
void errorHalt (Print *pr)
 
void errorHalt (char const *msg)
 
void errorHalt (Print *pr, char const *msg)
 
void errorHalt (const __FlashStringHelper *msg)
 
void errorHalt (Print *pr, const __FlashStringHelper *msg)
 
void errorPrint ()
 
void errorPrint (Print *pr)
 
void errorPrint (const char *msg)
 
void errorPrint (Print *pr, char const *msg)
 
void errorPrint (const __FlashStringHelper *msg)
 
void errorPrint (Print *pr, const __FlashStringHelper *msg)
 
bool exists (const char *path)
 
uint8_t fatCount ()
 
uint32_t fatStartBlock () const
 
uint8_t fatType () const
 
int32_t freeClusterCount ()
 
bool fsBegin ()
 
bool init ()
 
bool init (uint8_t part)
 
void initErrorHalt ()
 
void initErrorHalt (Print *pr)
 
void initErrorHalt (char const *msg)
 
void initErrorHalt (Print *pr, char const *msg)
 
void initErrorHalt (const __FlashStringHelper *msg)
 
void initErrorHalt (Print *pr, const __FlashStringHelper *msg)
 
void initErrorPrint ()
 
void initErrorPrint (Print *pr)
 
void initErrorPrint (char const *msg)
 
void initErrorPrint (Print *pr, char const *msg)
 
void initErrorPrint (const __FlashStringHelper *msg)
 
void initErrorPrint (Print *pr, const __FlashStringHelper *msg)
 
void ls (uint8_t flags=0)
 
void ls (const char *path, uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0)
 
void ls (print_t *pr, const char *path, uint8_t flags)
 
bool mkdir (const char *path, bool pFlag=true)
 
File open (const char *path, uint8_t mode=FILE_READ)
 
File open (const String &path, uint8_t mode=FILE_READ)
 
bool remove (const char *path)
 
bool rename (const char *oldPath, const char *newPath)
 
bool rmdir (const char *path)
 
uint16_t rootDirEntryCount () const
 
uint32_t rootDirStart () const
 
bool truncate (const char *path, uint32_t length)
 
FatVolumevol ()
 
uint32_t volumeBlockCount () const
 
FatFilevwd ()
 
bool wipe (print_t *pr=0)
 
+

Detailed Description

+

SdFat class using SDIO.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::begin (BlockDriverblockDev,
uint8_t part = 0 
)
+
+inlineinherited
+
+

Initialize an FatFileSystem object.

Parameters
+ + + +
[in]blockDevDevice block driver.
[in]partpartition to initialize.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdFatSdio::begin ()
+
+inline
+
+

Initialize SD card and file system.

Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::blocksPerCluster () const
+
+inlineinherited
+
+
Returns
The volume's cluster size in blocks.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::blocksPerFat () const
+
+inlineinherited
+
+
Returns
The number of blocks in one FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
cache_t* FatVolume::cacheClear ()
+
+inlineinherited
+
+

Clear the cache and returns a pointer to the cache. Not for normal apps.

Returns
A pointer to the cache buffer or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
SdioCard * SdFileSystem< SdioCard >::card ()
+
+inlineinherited
+
+
Returns
Pointer to SD card object
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdFatSdio::cardBegin ()
+
+inline
+
+

Initialize SD card for diagnostic use only.

+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t SdFileSystem< SdioCard >::cardErrorCode ()
+
+inlineinherited
+
+
Returns
The card error code
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t SdFileSystem< SdioCard >::cardErrorData ()
+
+inlineinherited
+
+
Returns
the card error data
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::chdir (bool set_cwd = false)
+
+inlineinherited
+
+

Change a volume's working directory to root

+

Changes the volume's working directory to the SD's root directory. Optionally set the current working directory to the volume's working directory.

+
Parameters
+ + +
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::chdir (const char * path,
bool set_cwd = false 
)
+
+inlineinherited
+
+

Change a volume's working directory

+

Changes the volume working directory to the path subdirectory. Optionally set the current working directory to the volume's working directory.

+

Example: If the volume's working directory is "/DIR", chdir("SUB") will change the volume's working directory from "/DIR" to "/DIR/SUB".

+

If path is "/", the volume's working directory will be changed to the root directory

+
Parameters
+ + + +
[in]pathThe name of the subdirectory.
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFileSystem::chvol ()
+
+inlineinherited
+
+

Set the current working directory to a volume's working directory.

+

This is useful with multiple SD cards.

+

The current working directory is changed to this volume's working directory.

+

This is like the Windows/DOS <drive letter>: command.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::clusterCount () const
+
+inlineinherited
+
+
Returns
The total number of clusters in the volume.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::clusterSizeShift () const
+
+inlineinherited
+
+
Returns
The shift count required to multiply by blocksPerCluster.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::dataStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of file data.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int8_t FatVolume::dbgFat (uint32_t n,
uint32_t * v 
)
+
+inlineinherited
+
+

Debug access to FAT table

+
Parameters
+ + + +
[in]ncluster number.
[out]vvalue of entry
+
+
+
Returns
true for success or false for failure
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdioCard >::errorHalt ()
+
+inlineinherited
+
+

Print any SD error code to Serial and halt.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::errorHalt (Print * pr)
+
+inlineinherited
+
+

Print any SD error code and halt.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::errorHalt (char const * msg)
+
+inlineinherited
+
+

Print msg, any SD error code and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdioCard >::errorHalt (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::errorHalt (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdioCard >::errorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdioCard >::errorPrint ()
+
+inlineinherited
+
+

Print any SD error code to Serial

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::errorPrint (Print * pr)
+
+inlineinherited
+
+

Print any SD error code.

Parameters
+ + +
[in]prPrint device.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::errorPrint (const char * msg)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdioCard >::errorPrint (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::errorPrint (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdioCard >::errorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::exists (const char * path)
+
+inlineinherited
+
+

Test for the existence of a file.

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatCount ()
+
+inlineinherited
+
+
Returns
The number of File Allocation Tables.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::fatStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the first FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatType () const
+
+inlineinherited
+
+
Returns
The FAT type of the volume. Values are 12, 16 or 32.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int32_t FatVolume::freeClusterCount ()
+
+inherited
+
+

Volume free space in clusters.

+
Returns
Count of free clusters for success or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdFatSdio::fsBegin ()
+
+inline
+
+

Initialize file system for diagnostic use only.

Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatVolume::init ()
+
+inlineinherited
+
+

Initialize a FAT volume. Try partition one first then try super floppy format.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatVolume::init (uint8_t part)
+
+inherited
+
+

Initialize a FAT volume.

+
Parameters
+ + +
[in]partThe partition to be used. Legal values for part are 1-4 to use the corresponding partition on a device formatted with a MBR, Master Boot Record, or zero if the device is formatted as a super floppy with the FAT boot sector in block zero.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdioCard >::initErrorHalt ()
+
+inlineinherited
+
+

Print any SD error code and halt.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::initErrorHalt (Print * pr)
+
+inlineinherited
+
+

Print error details and halt after begin fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::initErrorHalt (char const * msg)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdioCard >::initErrorHalt (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::initErrorHalt (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdioCard >::initErrorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device for message.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdioCard >::initErrorPrint ()
+
+inlineinherited
+
+

Print error details after begin() fails.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::initErrorPrint (Print * pr)
+
+inlineinherited
+
+

Print error details after begin() fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::initErrorPrint (char const * msg)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdioCard >::initErrorPrint (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdioCard >::initErrorPrint (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdioCard >::initErrorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFileSystem::ls (uint8_t flags = 0)
+
+inlineinherited
+
+

List the directory contents of the volume working directory to Serial.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (const char * path,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of a directory to Serial.

+
Parameters
+ + + +
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of the volume working directory.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
const char * path,
uint8_t flags 
)
+
+inlineinherited
+
+

List the directory contents of a directory.

+
Parameters
+ + + + +
[in]prPrint stream for list.
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::mkdir (const char * path,
bool pFlag = true 
)
+
+inlineinherited
+
+

Make a subdirectory in the volume working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const char * path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const String & path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::remove (const char * path)
+
+inlineinherited
+
+

Remove a file from the volume working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::rename (const char * oldPath,
const char * newPath 
)
+
+inlineinherited
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]oldPathPath name to the file or subdirectory to be renamed.
[in]newPathNew path name of the file or subdirectory.
+
+
+

The newPath object must not exist before the rename call.

+

The file to be renamed must not be open. The directory entry may be moved and file system corruption could occur if the file is accessed by a file object that was opened before the rename() call.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::rmdir (const char * path)
+
+inlineinherited
+
+

Remove a subdirectory from the volume's working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
+
+
+

The subdirectory file will be removed only if it is empty.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatVolume::rootDirEntryCount () const
+
+inlineinherited
+
+
Returns
The number of entries in the root directory for FAT16 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::rootDirStart () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the root directory on FAT16 volumes or the first cluster number on FAT32 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::truncate (const char * path,
uint32_t length 
)
+
+inlineinherited
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the file.
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFileSystem::vol ()
+
+inlineinherited
+
+
Returns
a pointer to the FatVolume object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::volumeBlockCount () const
+
+inlineinherited
+
+
Returns
The number of blocks in the volume
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatFile* FatFileSystem::vwd ()
+
+inlineinherited
+
+
Returns
a pointer to the volume working directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::wipe (print_tpr = 0)
+
+inlineinherited
+
+

Wipe all data from the volume. You must reinitialize the volume before accessing it again.

Parameters
+ + +
[in]prprint stream for status dots.
+
+
+
Returns
true for success else false.
+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/SdFat.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_fat_sdio__coll__graph.png b/libraries/SdFat/extras/html/class_sd_fat_sdio__coll__graph.png new file mode 100644 index 0000000..b8803e8 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_fat_sdio__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_fat_sdio__inherit__graph.png b/libraries/SdFat/extras/html/class_sd_fat_sdio__inherit__graph.png new file mode 100644 index 0000000..b8803e8 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_fat_sdio__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_fat_soft_spi-members.html b/libraries/SdFat/extras/html/class_sd_fat_soft_spi-members.html new file mode 100644 index 0000000..a5fa07f --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_fat_soft_spi-members.html @@ -0,0 +1,164 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdFatSoftSpi< MisoPin, MosiPin, SckPin > Member List
+
+
+ +

This is the complete list of members for SdFatSoftSpi< MisoPin, MosiPin, SckPin >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin(uint8_t csPin=SS, SPISettings spiSettings=SPI_FULL_SPEED)SdFatSoftSpi< MisoPin, MosiPin, SckPin >inline
SdFileSystem< SdSpiCard >::begin()SdFileSystem< SdSpiCard >inline
FatFileSystem::begin(BlockDriver *blockDev, uint8_t part=0)FatFileSysteminline
blocksPerCluster() const FatVolumeinline
blocksPerFat() const FatVolumeinline
cacheClear()FatVolumeinline
card()SdFileSystem< SdSpiCard >inline
cardErrorCode()SdFileSystem< SdSpiCard >inline
cardErrorData()SdFileSystem< SdSpiCard >inline
chdir(bool set_cwd=false)FatFileSysteminline
chdir(const char *path, bool set_cwd=false)FatFileSysteminline
chvol()FatFileSysteminline
clusterCount() const FatVolumeinline
clusterSizeShift() const FatVolumeinline
dataStartBlock() const FatVolumeinline
dbgFat(uint32_t n, uint32_t *v)FatVolumeinline
errorHalt()SdFileSystem< SdSpiCard >inline
errorHalt(Print *pr)SdFileSystem< SdSpiCard >inline
errorHalt(char const *msg)SdFileSystem< SdSpiCard >inline
errorHalt(Print *pr, char const *msg)SdFileSystem< SdSpiCard >inline
errorHalt(const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
errorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
errorPrint()SdFileSystem< SdSpiCard >inline
errorPrint(Print *pr)SdFileSystem< SdSpiCard >inline
errorPrint(const char *msg)SdFileSystem< SdSpiCard >inline
errorPrint(Print *pr, char const *msg)SdFileSystem< SdSpiCard >inline
errorPrint(const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
errorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
exists(const char *path)FatFileSysteminline
fatCount()FatVolumeinline
fatStartBlock() const FatVolumeinline
fatType() const FatVolumeinline
FatVolume()FatVolumeinline
freeClusterCount()FatVolume
init()FatVolumeinline
init(uint8_t part)FatVolume
initErrorHalt()SdFileSystem< SdSpiCard >inline
initErrorHalt(Print *pr)SdFileSystem< SdSpiCard >inline
initErrorHalt(char const *msg)SdFileSystem< SdSpiCard >inline
initErrorHalt(Print *pr, char const *msg)SdFileSystem< SdSpiCard >inline
initErrorHalt(const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
initErrorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
initErrorPrint()SdFileSystem< SdSpiCard >inline
initErrorPrint(Print *pr)SdFileSystem< SdSpiCard >inline
initErrorPrint(char const *msg)SdFileSystem< SdSpiCard >inline
initErrorPrint(Print *pr, char const *msg)SdFileSystem< SdSpiCard >inline
initErrorPrint(const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
initErrorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCard >inline
ls(uint8_t flags=0)FatFileSysteminline
ls(const char *path, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, const char *path, uint8_t flags)FatFileSysteminline
mkdir(const char *path, bool pFlag=true)FatFileSysteminline
open(const char *path, uint8_t mode=FILE_READ)FatFileSysteminline
open(const String &path, uint8_t mode=FILE_READ)FatFileSysteminline
remove(const char *path)FatFileSysteminline
rename(const char *oldPath, const char *newPath)FatFileSysteminline
rmdir(const char *path)FatFileSysteminline
rootDirEntryCount() const FatVolumeinline
rootDirStart() const FatVolumeinline
truncate(const char *path, uint32_t length)FatFileSysteminline
vol()FatFileSysteminline
volumeBlockCount() const FatVolumeinline
vwd()FatFileSysteminline
wipe(print_t *pr=0)FatFileSysteminline
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_fat_soft_spi.html b/libraries/SdFat/extras/html/class_sd_fat_soft_spi.html new file mode 100644 index 0000000..ae13854 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_fat_soft_spi.html @@ -0,0 +1,2337 @@ + + + + + + +SdFat: SdFatSoftSpi< MisoPin, MosiPin, SckPin > Class Template Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
SdFatSoftSpi< MisoPin, MosiPin, SckPin > Class Template Reference
+
+
+ +

SdFat class using software SPI. + More...

+ +

#include <SdFat.h>

+
+Inheritance diagram for SdFatSoftSpi< MisoPin, MosiPin, SckPin >:
+
+
Inheritance graph
+ + + + + +
[legend]
+
+Collaboration diagram for SdFatSoftSpi< MisoPin, MosiPin, SckPin >:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin (BlockDriver *blockDev, uint8_t part=0)
 
bool begin ()
 
bool begin (uint8_t csPin=SS, SPISettings spiSettings=SPI_FULL_SPEED)
 
uint8_t blocksPerCluster () const
 
uint32_t blocksPerFat () const
 
cache_tcacheClear ()
 
SdSpiCardcard ()
 
uint8_t cardErrorCode ()
 
uint32_t cardErrorData ()
 
bool chdir (bool set_cwd=false)
 
bool chdir (const char *path, bool set_cwd=false)
 
void chvol ()
 
uint32_t clusterCount () const
 
uint8_t clusterSizeShift () const
 
uint32_t dataStartBlock () const
 
int8_t dbgFat (uint32_t n, uint32_t *v)
 
void errorHalt ()
 
void errorHalt (Print *pr)
 
void errorHalt (char const *msg)
 
void errorHalt (Print *pr, char const *msg)
 
void errorHalt (const __FlashStringHelper *msg)
 
void errorHalt (Print *pr, const __FlashStringHelper *msg)
 
void errorPrint ()
 
void errorPrint (Print *pr)
 
void errorPrint (const char *msg)
 
void errorPrint (Print *pr, char const *msg)
 
void errorPrint (const __FlashStringHelper *msg)
 
void errorPrint (Print *pr, const __FlashStringHelper *msg)
 
bool exists (const char *path)
 
uint8_t fatCount ()
 
uint32_t fatStartBlock () const
 
uint8_t fatType () const
 
int32_t freeClusterCount ()
 
bool init ()
 
bool init (uint8_t part)
 
void initErrorHalt ()
 
void initErrorHalt (Print *pr)
 
void initErrorHalt (char const *msg)
 
void initErrorHalt (Print *pr, char const *msg)
 
void initErrorHalt (const __FlashStringHelper *msg)
 
void initErrorHalt (Print *pr, const __FlashStringHelper *msg)
 
void initErrorPrint ()
 
void initErrorPrint (Print *pr)
 
void initErrorPrint (char const *msg)
 
void initErrorPrint (Print *pr, char const *msg)
 
void initErrorPrint (const __FlashStringHelper *msg)
 
void initErrorPrint (Print *pr, const __FlashStringHelper *msg)
 
void ls (uint8_t flags=0)
 
void ls (const char *path, uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0)
 
void ls (print_t *pr, const char *path, uint8_t flags)
 
bool mkdir (const char *path, bool pFlag=true)
 
File open (const char *path, uint8_t mode=FILE_READ)
 
File open (const String &path, uint8_t mode=FILE_READ)
 
bool remove (const char *path)
 
bool rename (const char *oldPath, const char *newPath)
 
bool rmdir (const char *path)
 
uint16_t rootDirEntryCount () const
 
uint32_t rootDirStart () const
 
bool truncate (const char *path, uint32_t length)
 
FatVolumevol ()
 
uint32_t volumeBlockCount () const
 
FatFilevwd ()
 
bool wipe (print_t *pr=0)
 
+

Detailed Description

+

template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
+class SdFatSoftSpi< MisoPin, MosiPin, SckPin >

+ +

SdFat class using software SPI.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::begin (BlockDriverblockDev,
uint8_t part = 0 
)
+
+inlineinherited
+
+

Initialize an FatFileSystem object.

Parameters
+ + + +
[in]blockDevDevice block driver.
[in]partpartition to initialize.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdFileSystem< SdSpiCard >::begin ()
+
+inlineinherited
+
+

Initialize file system.

Returns
true for success else false.
+ +
+
+ +
+
+
+template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdFatSoftSpi< MisoPin, MosiPin, SckPin >::begin (uint8_t csPin = SS,
SPISettings spiSettings = SPI_FULL_SPEED 
)
+
+inline
+
+

Initialize SD card and file system.

+
Parameters
+ + + +
[in]csPinSD card chip select pin.
[in]spiSettingsignored for software SPI..
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::blocksPerCluster () const
+
+inlineinherited
+
+
Returns
The volume's cluster size in blocks.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::blocksPerFat () const
+
+inlineinherited
+
+
Returns
The number of blocks in one FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
cache_t* FatVolume::cacheClear ()
+
+inlineinherited
+
+

Clear the cache and returns a pointer to the cache. Not for normal apps.

Returns
A pointer to the cache buffer or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
SdSpiCard * SdFileSystem< SdSpiCard >::card ()
+
+inlineinherited
+
+
Returns
Pointer to SD card object
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t SdFileSystem< SdSpiCard >::cardErrorCode ()
+
+inlineinherited
+
+
Returns
The card error code
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t SdFileSystem< SdSpiCard >::cardErrorData ()
+
+inlineinherited
+
+
Returns
the card error data
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::chdir (bool set_cwd = false)
+
+inlineinherited
+
+

Change a volume's working directory to root

+

Changes the volume's working directory to the SD's root directory. Optionally set the current working directory to the volume's working directory.

+
Parameters
+ + +
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::chdir (const char * path,
bool set_cwd = false 
)
+
+inlineinherited
+
+

Change a volume's working directory

+

Changes the volume working directory to the path subdirectory. Optionally set the current working directory to the volume's working directory.

+

Example: If the volume's working directory is "/DIR", chdir("SUB") will change the volume's working directory from "/DIR" to "/DIR/SUB".

+

If path is "/", the volume's working directory will be changed to the root directory

+
Parameters
+ + + +
[in]pathThe name of the subdirectory.
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFileSystem::chvol ()
+
+inlineinherited
+
+

Set the current working directory to a volume's working directory.

+

This is useful with multiple SD cards.

+

The current working directory is changed to this volume's working directory.

+

This is like the Windows/DOS <drive letter>: command.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::clusterCount () const
+
+inlineinherited
+
+
Returns
The total number of clusters in the volume.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::clusterSizeShift () const
+
+inlineinherited
+
+
Returns
The shift count required to multiply by blocksPerCluster.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::dataStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of file data.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int8_t FatVolume::dbgFat (uint32_t n,
uint32_t * v 
)
+
+inlineinherited
+
+

Debug access to FAT table

+
Parameters
+ + + +
[in]ncluster number.
[out]vvalue of entry
+
+
+
Returns
true for success or false for failure
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt ()
+
+inlineinherited
+
+

Print any SD error code to Serial and halt.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt (Print * pr)
+
+inlineinherited
+
+

Print any SD error code and halt.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt (char const * msg)
+
+inlineinherited
+
+

Print msg, any SD error code and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::errorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint ()
+
+inlineinherited
+
+

Print any SD error code to Serial

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint (Print * pr)
+
+inlineinherited
+
+

Print any SD error code.

Parameters
+ + +
[in]prPrint device.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint (const char * msg)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::errorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::exists (const char * path)
+
+inlineinherited
+
+

Test for the existence of a file.

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatCount ()
+
+inlineinherited
+
+
Returns
The number of File Allocation Tables.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::fatStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the first FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatType () const
+
+inlineinherited
+
+
Returns
The FAT type of the volume. Values are 12, 16 or 32.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int32_t FatVolume::freeClusterCount ()
+
+inherited
+
+

Volume free space in clusters.

+
Returns
Count of free clusters for success or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatVolume::init ()
+
+inlineinherited
+
+

Initialize a FAT volume. Try partition one first then try super floppy format.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatVolume::init (uint8_t part)
+
+inherited
+
+

Initialize a FAT volume.

+
Parameters
+ + +
[in]partThe partition to be used. Legal values for part are 1-4 to use the corresponding partition on a device formatted with a MBR, Master Boot Record, or zero if the device is formatted as a super floppy with the FAT boot sector in block zero.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt ()
+
+inlineinherited
+
+

Print any SD error code and halt.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt (Print * pr)
+
+inlineinherited
+
+

Print error details and halt after begin fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt (char const * msg)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device for message.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint ()
+
+inlineinherited
+
+

Print error details after begin() fails.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint (Print * pr)
+
+inlineinherited
+
+

Print error details after begin() fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint (char const * msg)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCard >::initErrorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFileSystem::ls (uint8_t flags = 0)
+
+inlineinherited
+
+

List the directory contents of the volume working directory to Serial.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (const char * path,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of a directory to Serial.

+
Parameters
+ + + +
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of the volume working directory.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
const char * path,
uint8_t flags 
)
+
+inlineinherited
+
+

List the directory contents of a directory.

+
Parameters
+ + + + +
[in]prPrint stream for list.
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::mkdir (const char * path,
bool pFlag = true 
)
+
+inlineinherited
+
+

Make a subdirectory in the volume working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const char * path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const String & path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::remove (const char * path)
+
+inlineinherited
+
+

Remove a file from the volume working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::rename (const char * oldPath,
const char * newPath 
)
+
+inlineinherited
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]oldPathPath name to the file or subdirectory to be renamed.
[in]newPathNew path name of the file or subdirectory.
+
+
+

The newPath object must not exist before the rename call.

+

The file to be renamed must not be open. The directory entry may be moved and file system corruption could occur if the file is accessed by a file object that was opened before the rename() call.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::rmdir (const char * path)
+
+inlineinherited
+
+

Remove a subdirectory from the volume's working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
+
+
+

The subdirectory file will be removed only if it is empty.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatVolume::rootDirEntryCount () const
+
+inlineinherited
+
+
Returns
The number of entries in the root directory for FAT16 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::rootDirStart () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the root directory on FAT16 volumes or the first cluster number on FAT32 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::truncate (const char * path,
uint32_t length 
)
+
+inlineinherited
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the file.
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFileSystem::vol ()
+
+inlineinherited
+
+
Returns
a pointer to the FatVolume object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::volumeBlockCount () const
+
+inlineinherited
+
+
Returns
The number of blocks in the volume
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatFile* FatFileSystem::vwd ()
+
+inlineinherited
+
+
Returns
a pointer to the volume working directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::wipe (print_tpr = 0)
+
+inlineinherited
+
+

Wipe all data from the volume. You must reinitialize the volume before accessing it again.

Parameters
+ + +
[in]prprint stream for status dots.
+
+
+
Returns
true for success else false.
+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/SdFat.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_fat_soft_spi__coll__graph.png b/libraries/SdFat/extras/html/class_sd_fat_soft_spi__coll__graph.png new file mode 100644 index 0000000..e868a3c Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_fat_soft_spi__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_fat_soft_spi__inherit__graph.png b/libraries/SdFat/extras/html/class_sd_fat_soft_spi__inherit__graph.png new file mode 100644 index 0000000..e868a3c Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_fat_soft_spi__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x-members.html b/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x-members.html new file mode 100644 index 0000000..48d8df9 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x-members.html @@ -0,0 +1,164 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdFatSoftSpiEX< MisoPin, MosiPin, SckPin > Member List
+
+
+ +

This is the complete list of members for SdFatSoftSpiEX< MisoPin, MosiPin, SckPin >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin(uint8_t csPin=SS, SPISettings spiSettings=SPI_FULL_SPEED)SdFatSoftSpiEX< MisoPin, MosiPin, SckPin >inline
SdFileSystem< SdSpiCardEX >::begin()SdFileSystem< SdSpiCardEX >inline
FatFileSystem::begin(BlockDriver *blockDev, uint8_t part=0)FatFileSysteminline
blocksPerCluster() const FatVolumeinline
blocksPerFat() const FatVolumeinline
cacheClear()FatVolumeinline
card()SdFileSystem< SdSpiCardEX >inline
cardErrorCode()SdFileSystem< SdSpiCardEX >inline
cardErrorData()SdFileSystem< SdSpiCardEX >inline
chdir(bool set_cwd=false)FatFileSysteminline
chdir(const char *path, bool set_cwd=false)FatFileSysteminline
chvol()FatFileSysteminline
clusterCount() const FatVolumeinline
clusterSizeShift() const FatVolumeinline
dataStartBlock() const FatVolumeinline
dbgFat(uint32_t n, uint32_t *v)FatVolumeinline
errorHalt()SdFileSystem< SdSpiCardEX >inline
errorHalt(Print *pr)SdFileSystem< SdSpiCardEX >inline
errorHalt(char const *msg)SdFileSystem< SdSpiCardEX >inline
errorHalt(Print *pr, char const *msg)SdFileSystem< SdSpiCardEX >inline
errorHalt(const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
errorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
errorPrint()SdFileSystem< SdSpiCardEX >inline
errorPrint(Print *pr)SdFileSystem< SdSpiCardEX >inline
errorPrint(const char *msg)SdFileSystem< SdSpiCardEX >inline
errorPrint(Print *pr, char const *msg)SdFileSystem< SdSpiCardEX >inline
errorPrint(const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
errorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
exists(const char *path)FatFileSysteminline
fatCount()FatVolumeinline
fatStartBlock() const FatVolumeinline
fatType() const FatVolumeinline
FatVolume()FatVolumeinline
freeClusterCount()FatVolume
init()FatVolumeinline
init(uint8_t part)FatVolume
initErrorHalt()SdFileSystem< SdSpiCardEX >inline
initErrorHalt(Print *pr)SdFileSystem< SdSpiCardEX >inline
initErrorHalt(char const *msg)SdFileSystem< SdSpiCardEX >inline
initErrorHalt(Print *pr, char const *msg)SdFileSystem< SdSpiCardEX >inline
initErrorHalt(const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
initErrorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
initErrorPrint()SdFileSystem< SdSpiCardEX >inline
initErrorPrint(Print *pr)SdFileSystem< SdSpiCardEX >inline
initErrorPrint(char const *msg)SdFileSystem< SdSpiCardEX >inline
initErrorPrint(Print *pr, char const *msg)SdFileSystem< SdSpiCardEX >inline
initErrorPrint(const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
initErrorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdSpiCardEX >inline
ls(uint8_t flags=0)FatFileSysteminline
ls(const char *path, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, const char *path, uint8_t flags)FatFileSysteminline
mkdir(const char *path, bool pFlag=true)FatFileSysteminline
open(const char *path, uint8_t mode=FILE_READ)FatFileSysteminline
open(const String &path, uint8_t mode=FILE_READ)FatFileSysteminline
remove(const char *path)FatFileSysteminline
rename(const char *oldPath, const char *newPath)FatFileSysteminline
rmdir(const char *path)FatFileSysteminline
rootDirEntryCount() const FatVolumeinline
rootDirStart() const FatVolumeinline
truncate(const char *path, uint32_t length)FatFileSysteminline
vol()FatFileSysteminline
volumeBlockCount() const FatVolumeinline
vwd()FatFileSysteminline
wipe(print_t *pr=0)FatFileSysteminline
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x.html b/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x.html new file mode 100644 index 0000000..c0058d3 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x.html @@ -0,0 +1,2337 @@ + + + + + + +SdFat: SdFatSoftSpiEX< MisoPin, MosiPin, SckPin > Class Template Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
SdFatSoftSpiEX< MisoPin, MosiPin, SckPin > Class Template Reference
+
+
+ +

SdFat class using software SPI and extended SD I/O. + More...

+ +

#include <SdFat.h>

+
+Inheritance diagram for SdFatSoftSpiEX< MisoPin, MosiPin, SckPin >:
+
+
Inheritance graph
+ + + + + +
[legend]
+
+Collaboration diagram for SdFatSoftSpiEX< MisoPin, MosiPin, SckPin >:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin (BlockDriver *blockDev, uint8_t part=0)
 
bool begin ()
 
bool begin (uint8_t csPin=SS, SPISettings spiSettings=SPI_FULL_SPEED)
 
uint8_t blocksPerCluster () const
 
uint32_t blocksPerFat () const
 
cache_tcacheClear ()
 
SdSpiCardEXcard ()
 
uint8_t cardErrorCode ()
 
uint32_t cardErrorData ()
 
bool chdir (bool set_cwd=false)
 
bool chdir (const char *path, bool set_cwd=false)
 
void chvol ()
 
uint32_t clusterCount () const
 
uint8_t clusterSizeShift () const
 
uint32_t dataStartBlock () const
 
int8_t dbgFat (uint32_t n, uint32_t *v)
 
void errorHalt ()
 
void errorHalt (Print *pr)
 
void errorHalt (char const *msg)
 
void errorHalt (Print *pr, char const *msg)
 
void errorHalt (const __FlashStringHelper *msg)
 
void errorHalt (Print *pr, const __FlashStringHelper *msg)
 
void errorPrint ()
 
void errorPrint (Print *pr)
 
void errorPrint (const char *msg)
 
void errorPrint (Print *pr, char const *msg)
 
void errorPrint (const __FlashStringHelper *msg)
 
void errorPrint (Print *pr, const __FlashStringHelper *msg)
 
bool exists (const char *path)
 
uint8_t fatCount ()
 
uint32_t fatStartBlock () const
 
uint8_t fatType () const
 
int32_t freeClusterCount ()
 
bool init ()
 
bool init (uint8_t part)
 
void initErrorHalt ()
 
void initErrorHalt (Print *pr)
 
void initErrorHalt (char const *msg)
 
void initErrorHalt (Print *pr, char const *msg)
 
void initErrorHalt (const __FlashStringHelper *msg)
 
void initErrorHalt (Print *pr, const __FlashStringHelper *msg)
 
void initErrorPrint ()
 
void initErrorPrint (Print *pr)
 
void initErrorPrint (char const *msg)
 
void initErrorPrint (Print *pr, char const *msg)
 
void initErrorPrint (const __FlashStringHelper *msg)
 
void initErrorPrint (Print *pr, const __FlashStringHelper *msg)
 
void ls (uint8_t flags=0)
 
void ls (const char *path, uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0)
 
void ls (print_t *pr, const char *path, uint8_t flags)
 
bool mkdir (const char *path, bool pFlag=true)
 
File open (const char *path, uint8_t mode=FILE_READ)
 
File open (const String &path, uint8_t mode=FILE_READ)
 
bool remove (const char *path)
 
bool rename (const char *oldPath, const char *newPath)
 
bool rmdir (const char *path)
 
uint16_t rootDirEntryCount () const
 
uint32_t rootDirStart () const
 
bool truncate (const char *path, uint32_t length)
 
FatVolumevol ()
 
uint32_t volumeBlockCount () const
 
FatFilevwd ()
 
bool wipe (print_t *pr=0)
 
+

Detailed Description

+

template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
+class SdFatSoftSpiEX< MisoPin, MosiPin, SckPin >

+ +

SdFat class using software SPI and extended SD I/O.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::begin (BlockDriverblockDev,
uint8_t part = 0 
)
+
+inlineinherited
+
+

Initialize an FatFileSystem object.

Parameters
+ + + +
[in]blockDevDevice block driver.
[in]partpartition to initialize.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdFileSystem< SdSpiCardEX >::begin ()
+
+inlineinherited
+
+

Initialize file system.

Returns
true for success else false.
+ +
+
+ +
+
+
+template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdFatSoftSpiEX< MisoPin, MosiPin, SckPin >::begin (uint8_t csPin = SS,
SPISettings spiSettings = SPI_FULL_SPEED 
)
+
+inline
+
+

Initialize SD card and file system.

+
Parameters
+ + + +
[in]csPinSD card chip select pin.
[in]spiSettingsignored for software SPI.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::blocksPerCluster () const
+
+inlineinherited
+
+
Returns
The volume's cluster size in blocks.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::blocksPerFat () const
+
+inlineinherited
+
+
Returns
The number of blocks in one FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
cache_t* FatVolume::cacheClear ()
+
+inlineinherited
+
+

Clear the cache and returns a pointer to the cache. Not for normal apps.

Returns
A pointer to the cache buffer or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
SdSpiCardEX * SdFileSystem< SdSpiCardEX >::card ()
+
+inlineinherited
+
+
Returns
Pointer to SD card object
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t SdFileSystem< SdSpiCardEX >::cardErrorCode ()
+
+inlineinherited
+
+
Returns
The card error code
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t SdFileSystem< SdSpiCardEX >::cardErrorData ()
+
+inlineinherited
+
+
Returns
the card error data
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::chdir (bool set_cwd = false)
+
+inlineinherited
+
+

Change a volume's working directory to root

+

Changes the volume's working directory to the SD's root directory. Optionally set the current working directory to the volume's working directory.

+
Parameters
+ + +
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::chdir (const char * path,
bool set_cwd = false 
)
+
+inlineinherited
+
+

Change a volume's working directory

+

Changes the volume working directory to the path subdirectory. Optionally set the current working directory to the volume's working directory.

+

Example: If the volume's working directory is "/DIR", chdir("SUB") will change the volume's working directory from "/DIR" to "/DIR/SUB".

+

If path is "/", the volume's working directory will be changed to the root directory

+
Parameters
+ + + +
[in]pathThe name of the subdirectory.
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFileSystem::chvol ()
+
+inlineinherited
+
+

Set the current working directory to a volume's working directory.

+

This is useful with multiple SD cards.

+

The current working directory is changed to this volume's working directory.

+

This is like the Windows/DOS <drive letter>: command.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::clusterCount () const
+
+inlineinherited
+
+
Returns
The total number of clusters in the volume.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::clusterSizeShift () const
+
+inlineinherited
+
+
Returns
The shift count required to multiply by blocksPerCluster.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::dataStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of file data.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int8_t FatVolume::dbgFat (uint32_t n,
uint32_t * v 
)
+
+inlineinherited
+
+

Debug access to FAT table

+
Parameters
+ + + +
[in]ncluster number.
[out]vvalue of entry
+
+
+
Returns
true for success or false for failure
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt ()
+
+inlineinherited
+
+

Print any SD error code to Serial and halt.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt (Print * pr)
+
+inlineinherited
+
+

Print any SD error code and halt.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt (char const * msg)
+
+inlineinherited
+
+

Print msg, any SD error code and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint ()
+
+inlineinherited
+
+

Print any SD error code to Serial

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint (Print * pr)
+
+inlineinherited
+
+

Print any SD error code.

Parameters
+ + +
[in]prPrint device.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint (const char * msg)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::errorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::exists (const char * path)
+
+inlineinherited
+
+

Test for the existence of a file.

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatCount ()
+
+inlineinherited
+
+
Returns
The number of File Allocation Tables.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::fatStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the first FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatType () const
+
+inlineinherited
+
+
Returns
The FAT type of the volume. Values are 12, 16 or 32.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int32_t FatVolume::freeClusterCount ()
+
+inherited
+
+

Volume free space in clusters.

+
Returns
Count of free clusters for success or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatVolume::init ()
+
+inlineinherited
+
+

Initialize a FAT volume. Try partition one first then try super floppy format.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatVolume::init (uint8_t part)
+
+inherited
+
+

Initialize a FAT volume.

+
Parameters
+ + +
[in]partThe partition to be used. Legal values for part are 1-4 to use the corresponding partition on a device formatted with a MBR, Master Boot Record, or zero if the device is formatted as a super floppy with the FAT boot sector in block zero.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt ()
+
+inlineinherited
+
+

Print any SD error code and halt.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt (Print * pr)
+
+inlineinherited
+
+

Print error details and halt after begin fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt (char const * msg)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device for message.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint ()
+
+inlineinherited
+
+

Print error details after begin() fails.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint (Print * pr)
+
+inlineinherited
+
+

Print error details after begin() fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint (char const * msg)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint (Print * pr,
char const * msg 
)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint (const __FlashStringHelper * msg)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdSpiCardEX >::initErrorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inlineinherited
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFileSystem::ls (uint8_t flags = 0)
+
+inlineinherited
+
+

List the directory contents of the volume working directory to Serial.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (const char * path,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of a directory to Serial.

+
Parameters
+ + + +
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of the volume working directory.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
const char * path,
uint8_t flags 
)
+
+inlineinherited
+
+

List the directory contents of a directory.

+
Parameters
+ + + + +
[in]prPrint stream for list.
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::mkdir (const char * path,
bool pFlag = true 
)
+
+inlineinherited
+
+

Make a subdirectory in the volume working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const char * path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const String & path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::remove (const char * path)
+
+inlineinherited
+
+

Remove a file from the volume working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::rename (const char * oldPath,
const char * newPath 
)
+
+inlineinherited
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]oldPathPath name to the file or subdirectory to be renamed.
[in]newPathNew path name of the file or subdirectory.
+
+
+

The newPath object must not exist before the rename call.

+

The file to be renamed must not be open. The directory entry may be moved and file system corruption could occur if the file is accessed by a file object that was opened before the rename() call.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::rmdir (const char * path)
+
+inlineinherited
+
+

Remove a subdirectory from the volume's working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
+
+
+

The subdirectory file will be removed only if it is empty.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatVolume::rootDirEntryCount () const
+
+inlineinherited
+
+
Returns
The number of entries in the root directory for FAT16 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::rootDirStart () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the root directory on FAT16 volumes or the first cluster number on FAT32 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::truncate (const char * path,
uint32_t length 
)
+
+inlineinherited
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the file.
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFileSystem::vol ()
+
+inlineinherited
+
+
Returns
a pointer to the FatVolume object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::volumeBlockCount () const
+
+inlineinherited
+
+
Returns
The number of blocks in the volume
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatFile* FatFileSystem::vwd ()
+
+inlineinherited
+
+
Returns
a pointer to the volume working directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::wipe (print_tpr = 0)
+
+inlineinherited
+
+

Wipe all data from the volume. You must reinitialize the volume before accessing it again.

Parameters
+ + +
[in]prprint stream for status dots.
+
+
+
Returns
true for success else false.
+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/SdFat.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x__coll__graph.png b/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x__coll__graph.png new file mode 100644 index 0000000..470ddc4 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x__inherit__graph.png b/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x__inherit__graph.png new file mode 100644 index 0000000..470ddc4 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_fat_soft_spi_e_x__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_file-members.html b/libraries/SdFat/extras/html/class_sd_file-members.html new file mode 100644 index 0000000..b087726 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_file-members.html @@ -0,0 +1,194 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdFile Member List
+
+
+ +

This is the complete list of members for SdFile, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
available()PrintFileinline
clearError()FatFileinline
clearWriteError()FatFileinline
close()FatFile
contiguousRange(uint32_t *bgnBlock, uint32_t *endBlock)FatFile
createContiguous(FatFile *dirFile, const char *path, uint32_t size)FatFile
createContiguous(const char *path, uint32_t size)FatFileinline
curCluster() const FatFileinline
curPosition() const FatFileinline
cwd()FatFileinlinestatic
dateTimeCallback(void(*dateTime)(uint16_t *date, uint16_t *time))FatFileinlinestatic
dateTimeCallbackCancel()FatFileinlinestatic
dirEntry(dir_t *dir)FatFile
dirIndex()FatFileinline
dirName(const dir_t *dir, char *name)FatFilestatic
dirSize()FatFile
dmpFile(print_t *pr, uint32_t pos, size_t n)FatFile
exists(const char *path)FatFileinline
FatFile()FatFileinline
FatFile(const char *path, uint8_t oflag)FatFileinline
fgets(char *str, int16_t num, char *delim=0)FatFile
fileAttr() const FatFileinline
fileSize() const FatFileinline
firstBlock()FatFileinline
firstCluster() const FatFileinline
flush()PrintFileinline
getError()FatFileinline
getName(char *name, size_t size)FatFile
getpos(FatPos_t *pos)FatFile
getSFN(char *name)FatFile
getWriteError()FatFileinline
isDir() const FatFileinline
isFile() const FatFileinline
isHidden() const FatFileinline
isLFN() const FatFileinline
isOpen() const FatFileinline
isReadOnly() const FatFileinline
isRoot() const FatFileinline
isRoot32() const FatFileinline
isRootFixed() const FatFileinline
isSubDir() const FatFileinline
isSystem() const FatFileinline
legal83Char(uint8_t c)FatFileinlinestatic
ls(uint8_t flags=0)FatFileinline
ls(print_t *pr, uint8_t flags=0, uint8_t indent=0)FatFile
mkdir(FatFile *dir, const char *path, bool pFlag=true)FatFile
open(FatFileSystem *fs, const char *path, uint8_t oflag)FatFile
open(FatFile *dirFile, uint16_t index, uint8_t oflag)FatFile
open(FatFile *dirFile, const char *path, uint8_t oflag)FatFile
open(const char *path, uint8_t oflag=O_READ)FatFileinline
openNext(FatFile *dirFile, uint8_t oflag=O_READ)FatFile
openRoot(FatVolume *vol)FatFile
peek()PrintFileinline
printCreateDateTime(print_t *pr)FatFile
printFatDate(uint16_t fatDate)FatFileinlinestatic
printFatDate(print_t *pr, uint16_t fatDate)FatFilestatic
printFatTime(uint16_t fatTime)FatFileinlinestatic
printFatTime(print_t *pr, uint16_t fatTime)FatFilestatic
printField(float value, char term, uint8_t prec=2)FatFile
printField(int16_t value, char term)FatFile
printField(uint16_t value, char term)FatFile
printField(int32_t value, char term)FatFile
printField(uint32_t value, char term)FatFile
PrintFile() (defined in PrintFile)PrintFileinline
PrintFile(const char *path, uint8_t oflag)PrintFileinline
printFileSize(print_t *pr)FatFile
printModifyDateTime(print_t *pr)FatFile
printName()FatFileinline
printName(print_t *pr)FatFile
printSFN(print_t *pr)FatFile
read()FatFileinline
read(void *buf, size_t nbyte)FatFile
readDir(dir_t *dir)FatFile
remove()FatFile
remove(FatFile *dirFile, const char *path)FatFilestatic
rename(FatFile *dirFile, const char *newPath)FatFile
rewind()FatFileinline
rmdir()FatFile
rmRfStar()FatFile
SdFile() (defined in SdFile)SdFileinline
SdFile(const char *path, uint8_t oflag)SdFileinline
seekCur(int32_t offset)FatFileinline
seekEnd(int32_t offset=0)FatFileinline
seekSet(uint32_t pos)FatFile
setCwd(FatFile *dir)FatFileinlinestatic
setpos(FatPos_t *pos)FatFile
sync()FatFile
timestamp(FatFile *file)FatFile
timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)FatFile
truncate(uint32_t length)FatFile
volume() const FatFileinline
write(uint8_t b)PrintFileinline
write(const uint8_t *buf, size_t size)PrintFileinline
FatFile::write(const char *str)FatFileinline
FatFile::write(const void *buf, size_t nbyte)FatFile
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_file.html b/libraries/SdFat/extras/html/class_sd_file.html new file mode 100644 index 0000000..4d80643 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_file.html @@ -0,0 +1,3363 @@ + + + + + + +SdFat: SdFile Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for backward compatibility. + More...

+ +

#include <SdFat.h>

+
+Inheritance diagram for SdFile:
+
+
Inheritance graph
+ + + + +
[legend]
+
+Collaboration diagram for SdFile:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

int available ()
 
void clearError ()
 
void clearWriteError ()
 
bool close ()
 
bool contiguousRange (uint32_t *bgnBlock, uint32_t *endBlock)
 
bool createContiguous (FatFile *dirFile, const char *path, uint32_t size)
 
bool createContiguous (const char *path, uint32_t size)
 
uint32_t curCluster () const
 
uint32_t curPosition () const
 
bool dirEntry (dir_t *dir)
 
uint16_t dirIndex ()
 
uint32_t dirSize ()
 
void dmpFile (print_t *pr, uint32_t pos, size_t n)
 
bool exists (const char *path)
 
int16_t fgets (char *str, int16_t num, char *delim=0)
 
uint8_t fileAttr () const
 
uint32_t fileSize () const
 
uint32_t firstBlock ()
 
uint32_t firstCluster () const
 
void flush ()
 
uint8_t getError ()
 
bool getName (char *name, size_t size)
 
void getpos (FatPos_t *pos)
 
bool getSFN (char *name)
 
bool getWriteError ()
 
bool isDir () const
 
bool isFile () const
 
bool isHidden () const
 
bool isLFN () const
 
bool isOpen () const
 
bool isReadOnly () const
 
bool isRoot () const
 
bool isRoot32 () const
 
bool isRootFixed () const
 
bool isSubDir () const
 
bool isSystem () const
 
void ls (uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0, uint8_t indent=0)
 
bool mkdir (FatFile *dir, const char *path, bool pFlag=true)
 
bool open (FatFileSystem *fs, const char *path, uint8_t oflag)
 
bool open (FatFile *dirFile, uint16_t index, uint8_t oflag)
 
bool open (FatFile *dirFile, const char *path, uint8_t oflag)
 
bool open (const char *path, uint8_t oflag=O_READ)
 
bool openNext (FatFile *dirFile, uint8_t oflag=O_READ)
 
bool openRoot (FatVolume *vol)
 
int peek ()
 
bool printCreateDateTime (print_t *pr)
 
int printField (float value, char term, uint8_t prec=2)
 
int printField (int16_t value, char term)
 
int printField (uint16_t value, char term)
 
int printField (int32_t value, char term)
 
int printField (uint32_t value, char term)
 
size_t printFileSize (print_t *pr)
 
bool printModifyDateTime (print_t *pr)
 
size_t printName ()
 
size_t printName (print_t *pr)
 
size_t printSFN (print_t *pr)
 
int read ()
 
int read (void *buf, size_t nbyte)
 
int8_t readDir (dir_t *dir)
 
bool remove ()
 
bool rename (FatFile *dirFile, const char *newPath)
 
void rewind ()
 
bool rmdir ()
 
bool rmRfStar ()
 
 SdFile (const char *path, uint8_t oflag)
 
bool seekCur (int32_t offset)
 
bool seekEnd (int32_t offset=0)
 
bool seekSet (uint32_t pos)
 
void setpos (FatPos_t *pos)
 
bool sync ()
 
bool timestamp (FatFile *file)
 
bool timestamp (uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
 
bool truncate (uint32_t length)
 
FatVolumevolume () const
 
size_t write (uint8_t b)
 
size_t write (const uint8_t *buf, size_t size)
 
int write (const char *str)
 
int write (const void *buf, size_t nbyte)
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static FatFilecwd ()
 
static void dateTimeCallback (void(*dateTime)(uint16_t *date, uint16_t *time))
 
static void dateTimeCallbackCancel ()
 
static uint8_t dirName (const dir_t *dir, char *name)
 
static bool legal83Char (uint8_t c)
 
static void printFatDate (uint16_t fatDate)
 
static void printFatDate (print_t *pr, uint16_t fatDate)
 
static void printFatTime (uint16_t fatTime)
 
static void printFatTime (print_t *pr, uint16_t fatTime)
 
static bool remove (FatFile *dirFile, const char *path)
 
static bool setCwd (FatFile *dir)
 
+

Detailed Description

+

Class for backward compatibility.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
SdFile::SdFile (const char * path,
uint8_t oflag 
)
+
+inline
+
+

Create a file object and open it in the current working directory.

+
Parameters
+ + + +
[in]pathA path for a file to be opened.
[in]oflagValues for oflag are constructed by a bitwise-inclusive OR of open flags. see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
int PrintFile::available ()
+
+inlineinherited
+
+
Returns
number of bytes available from the current position to EOF or INT_MAX if more than INT_MAX bytes are available.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::clearError ()
+
+inlineinherited
+
+

Clear all error bits.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::clearWriteError ()
+
+inlineinherited
+
+

Set writeError to zero

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::close ()
+
+inherited
+
+

Close a file and force cached data and directory information to be written to the storage device.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::contiguousRange (uint32_t * bgnBlock,
uint32_t * endBlock 
)
+
+inherited
+
+

Check for contiguous file and return its raw block range.

+
Parameters
+ + + +
[out]bgnBlockthe first block address for the file.
[out]endBlockthe last block address for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::createContiguous (FatFiledirFile,
const char * path,
uint32_t size 
)
+
+inherited
+
+

Create and open a new contiguous file of a specified size.

+
Parameters
+ + + + +
[in]dirFileThe directory where the file will be created.
[in]pathA path with a validfile name.
[in]sizeThe desired file size.
+
+
+
Returns
The value true is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::createContiguous (const char * path,
uint32_t size 
)
+
+inlineinherited
+
+

Create and open a new contiguous file of a specified size.

+
Parameters
+ + + +
[in]pathA path with a validfile name.
[in]sizeThe desired file size.
+
+
+
Returns
The value true is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::curCluster () const
+
+inlineinherited
+
+
Returns
The current cluster number for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::curPosition () const
+
+inlineinherited
+
+
Returns
The current position for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static FatFile* FatFile::cwd ()
+
+inlinestaticinherited
+
+
Returns
Current working directory
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::dateTimeCallback (void(*)(uint16_t *date, uint16_t *time) dateTime)
+
+inlinestaticinherited
+
+

Set the date/time callback function

+
Parameters
+ + +
[in]dateTimeThe user's call back function. The callback function is of the form:
+
+
+
void dateTime(uint16_t* date, uint16_t* time) {
+
uint16_t year;
+
uint8_t month, day, hour, minute, second;
+
+
// User gets date and time from GPS or real-time clock here
+
+
// return date using FAT_DATE macro to format fields
+
*date = FAT_DATE(year, month, day);
+
+
// return time using FAT_TIME macro to format fields
+
*time = FAT_TIME(hour, minute, second);
+
}
+

Sets the function that is called when a file is created or when a file's directory entry is modified by sync(). All timestamps, access, creation, and modify, are set when a file is created. sync() maintains the last access date and last modify date/time.

+

See the timestamp() function.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static void FatFile::dateTimeCallbackCancel ()
+
+inlinestaticinherited
+
+

Cancel the date/time callback function.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::dirEntry (dir_tdir)
+
+inherited
+
+

Return a file's directory entry.

+
Parameters
+ + +
[out]dirLocation for return of the file's directory entry.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatFile::dirIndex ()
+
+inlineinherited
+
+
Returns
The index of this file in it's directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t FatFile::dirName (const dir_tdir,
char * name 
)
+
+staticinherited
+
+

Format the name field of dir into the 13 byte array name in standard 8.3 short name format.

+
Parameters
+ + + +
[in]dirThe directory structure containing the name.
[out]nameA 13 byte char array for the formatted name.
+
+
+
Returns
length of the name.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::dirSize ()
+
+inherited
+
+
Returns
The number of bytes allocated to a directory or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFile::dmpFile (print_tpr,
uint32_t pos,
size_t n 
)
+
+inherited
+
+

Dump file in Hex

Parameters
+ + + + +
[in]prPrint stream for list.
[in]posStart position in file.
[in]nnumber of locations to dump.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::exists (const char * path)
+
+inlineinherited
+
+

Test for the existence of a file in a directory

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+

The calling instance must be an open directory file.

+

dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory dirFile.

+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
int16_t FatFile::fgets (char * str,
int16_t num,
char * delim = 0 
)
+
+inherited
+
+

Get a string from a file.

+

fgets() reads bytes from a file into the array pointed to by str, until num - 1 bytes are read, or a delimiter is read and transferred to str, or end-of-file is encountered. The string is then terminated with a null byte.

+

fgets() deletes CR, '\r', from the string. This insures only a '\n' terminates the string for Windows text files which use CRLF for newline.

+
Parameters
+ + + + +
[out]strPointer to the array where the string is stored.
[in]numMaximum number of characters to be read (including the final null byte). Usually the length of the array str is used.
[in]delimOptional set of delimiters. The default is "\n".
+
+
+
Returns
For success fgets() returns the length of the string in str. If no data is read, fgets() returns zero for EOF or -1 if an error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatFile::fileAttr () const
+
+inlineinherited
+
+

Type of file. You should use isFile() or isDir() instead of fileType() if possible.

+
Returns
The file or directory type.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::fileSize () const
+
+inlineinherited
+
+
Returns
The total number of bytes in a file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::firstBlock ()
+
+inlineinherited
+
+
Returns
first block of file or zero for empty file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatFile::firstCluster () const
+
+inlineinherited
+
+
Returns
The first cluster number for a file or directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void PrintFile::flush ()
+
+inlineinherited
+
+

Ensure that any bytes written to the file are saved to the SD card.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatFile::getError ()
+
+inlineinherited
+
+
Returns
All error bits.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::getName (char * name,
size_t size 
)
+
+inherited
+
+

Get a file's name followed by a zero byte.

+
Parameters
+ + + +
[out]nameAn array of characters for the file's name.
[in]sizeThe size of the array in bytes. The array must be at least 13 bytes long. The file's name will be truncated if the file's name is too long.
+
+
+
Returns
The value true, is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::getpos (FatPos_tpos)
+
+inherited
+
+

get position for streams

Parameters
+ + +
[out]posstruct to receive position
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::getSFN (char * name)
+
+inherited
+
+

Get a file's Short File Name followed by a zero byte.

+
Parameters
+ + +
[out]nameAn array of characters for the file's name. The array must be at least 13 bytes long.
+
+
+
Returns
The value true, is returned for success and the value false, is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::getWriteError ()
+
+inlineinherited
+
+
Returns
value of writeError
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isDir () const
+
+inlineinherited
+
+
Returns
True if this is a directory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isFile () const
+
+inlineinherited
+
+
Returns
True if this is a normal file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isHidden () const
+
+inlineinherited
+
+
Returns
True if this is a hidden file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isLFN () const
+
+inlineinherited
+
+
Returns
true if this file has a Long File Name.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isOpen () const
+
+inlineinherited
+
+
Returns
True if this is an open file/directory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isReadOnly () const
+
+inlineinherited
+
+
Returns
True if file is read-only
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRoot () const
+
+inlineinherited
+
+
Returns
True if this is the root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRoot32 () const
+
+inlineinherited
+
+
Returns
True if this is the FAT32 root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isRootFixed () const
+
+inlineinherited
+
+
Returns
True if this is the FAT12 of FAT16 root directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isSubDir () const
+
+inlineinherited
+
+
Returns
True if this is a subdirectory else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::isSystem () const
+
+inlineinherited
+
+
Returns
True if this is a system file else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static bool FatFile::legal83Char (uint8_t c)
+
+inlinestaticinherited
+
+

Check for a legal 8.3 character.

Parameters
+ + +
[in]cCharacter to be checked.
+
+
+
Returns
true for a legal 8.3 character else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::ls (uint8_t flags = 0)
+
+inlineinherited
+
+

List directory contents.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFile::ls (print_tpr,
uint8_t flags = 0,
uint8_t indent = 0 
)
+
+inherited
+
+

List directory contents.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+
Parameters
+ + +
[in]indentAmount of space before file name. Used for recursive list to indicate subdirectory level.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::mkdir (FatFiledir,
const char * path,
bool pFlag = true 
)
+
+inherited
+
+

Make a new directory.

+
Parameters
+ + + + +
[in]dirAn open FatFile instance for the directory that will contain the new directory.
[in]pathA path with a valid 8.3 DOS name for the new directory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFileSystemfs,
const char * path,
uint8_t oflag 
)
+
+inherited
+
+

Open a file in the volume working directory of a FatFileSystem.

+
Parameters
+ + + + +
[in]fsFile System where the file is located.
[in]pathwith a valid 8.3 DOS name for a file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFiledirFile,
uint16_t index,
uint8_t oflag 
)
+
+inherited
+
+

Open a file by index.

+
Parameters
+ + + + +
[in]dirFileAn open FatFile instance for the directory.
[in]indexThe index of the directory entry for the file to be opened. The value for index is (directory file position)/32.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+

See open() by path for definition of flags.

Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::open (FatFiledirFile,
const char * path,
uint8_t oflag 
)
+
+inherited
+
+

Open a file or directory by name.

+
Parameters
+ + + + +
[in]dirFileAn open FatFile instance for the directory containing the file to be opened.
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagValues for oflag are constructed by a bitwise-inclusive OR of flags from the following list
+
+
+

O_READ - Open for reading.

+

O_RDONLY - Same as O_READ.

+

O_WRITE - Open for writing.

+

O_WRONLY - Same as O_WRITE.

+

O_RDWR - Open for reading and writing.

+

O_APPEND - If set, the file offset shall be set to the end of the file prior to each write.

+

O_AT_END - Set the initial position at the end of the file.

+

O_CREAT - If the file exists, this flag has no effect except as noted under O_EXCL below. Otherwise, the file shall be created

+

O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.

+

O_SYNC - Call sync() after each write. This flag should not be used with write(uint8_t) or any functions do character at a time writes since sync() will be called after each byte.

+

O_TRUNC - If the file exists and is a regular file, and the file is successfully opened and is not read only, its length shall be truncated to 0.

+

WARNING: A given file must not be opened by more than one FatFile object or file corruption may occur.

+
Note
Directory files must be opened read only. Write and truncation is not allowed for directory files.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::open (const char * path,
uint8_t oflag = O_READ 
)
+
+inlineinherited
+
+

Open a file in the current working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for a file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::openNext (FatFiledirFile,
uint8_t oflag = O_READ 
)
+
+inherited
+
+

Open the next file or subdirectory in a directory.

+
Parameters
+ + + +
[in]dirFileAn open FatFile instance for the directory containing the file to be opened.
[in]oflagbitwise-inclusive OR of open mode flags. See see FatFile::open(FatFile*, const char*, uint8_t).
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::openRoot (FatVolumevol)
+
+inherited
+
+

Open a volume's root directory.

+
Parameters
+ + +
[in]volThe FAT volume containing the root directory to be opened.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int PrintFile::peek ()
+
+inlineinherited
+
+

Return the next available byte without consuming it.

+
Returns
The byte if no error and not at eof else -1;
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::printCreateDateTime (print_tpr)
+
+inherited
+
+

Print a file's creation date and time

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::printFatDate (uint16_t fatDate)
+
+inlinestaticinherited
+
+

Print a directory date field.

+

Format is yyyy-mm-dd.

+
Parameters
+ + +
[in]fatDateThe date field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFile::printFatDate (print_tpr,
uint16_t fatDate 
)
+
+staticinherited
+
+

Print a directory date field.

+

Format is yyyy-mm-dd.

+
Parameters
+ + + +
[in]prPrint stream for output.
[in]fatDateThe date field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static void FatFile::printFatTime (uint16_t fatTime)
+
+inlinestaticinherited
+
+

Print a directory time field.

+

Format is hh:mm:ss.

+
Parameters
+ + +
[in]fatTimeThe time field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFile::printFatTime (print_tpr,
uint16_t fatTime 
)
+
+staticinherited
+
+

Print a directory time field.

+

Format is hh:mm:ss.

+
Parameters
+ + + +
[in]prPrint stream for output.
[in]fatTimeThe time field from a directory entry.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
int FatFile::printField (float value,
char term,
uint8_t prec = 2 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
[in]precNumber of digits after decimal point.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (int16_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (uint16_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (int32_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::printField (uint32_t value,
char term 
)
+
+inherited
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator. Use '\n' for CR LF.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printFileSize (print_tpr)
+
+inherited
+
+

Print a file's size.

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The number of characters printed is returned for success and zero is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::printModifyDateTime (print_tpr)
+
+inherited
+
+

Print a file's modify date and time

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t FatFile::printName ()
+
+inlineinherited
+
+

Print a file's name.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printName (print_tpr)
+
+inherited
+
+

Print a file's name

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t FatFile::printSFN (print_tpr)
+
+inherited
+
+

Print a file's Short File Name.

+
Parameters
+ + +
[in]prPrint stream for output.
+
+
+
Returns
The number of characters printed is returned for success and zero is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int FatFile::read ()
+
+inlineinherited
+
+

Read the next byte from a file.

+
Returns
For success read returns the next byte in the file as an int. If an error occurs or end of file is reached -1 is returned.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::read (void * buf,
size_t nbyte 
)
+
+inherited
+
+

Read data from a file starting at the current position.

+
Parameters
+ + + +
[out]bufPointer to the location that will receive the data.
[in]nbyteMaximum number of bytes to read.
+
+
+
Returns
For success read() returns the number of bytes read. A value less than nbyte, including zero, will be returned if end of file is reached. If an error occurs, read() returns -1. Possible errors include read() called before a file has been opened, corrupt file system or an I/O error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int8_t FatFile::readDir (dir_tdir)
+
+inherited
+
+

Read the next directory entry from a directory file.

+
Parameters
+ + +
[out]dirThe dir_t struct that will receive the data.
+
+
+
Returns
For success readDir() returns the number of bytes read. A value of zero will be returned if end of file is reached. If an error occurs, readDir() returns -1. Possible errors include readDir() called before a directory has been opened, this is not a directory file or an I/O error occurred.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::remove ()
+
+inherited
+
+

Remove a file.

+

The directory entry and all data for the file are deleted.

+
Note
This function should not be used to delete the 8.3 version of a file that has a long name. For example if a file has the long name "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::remove (FatFiledirFile,
const char * path 
)
+
+staticinherited
+
+

Remove a file.

+

The directory entry and all data for the file are deleted.

+
Parameters
+ + + +
[in]dirFileThe directory that contains the file.
[in]pathPath for the file to be removed.
+
+
+
Note
This function should not be used to delete the 8.3 version of a file that has a long name. For example if a file has the long name "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFile::rename (FatFiledirFile,
const char * newPath 
)
+
+inherited
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]dirFileDirectory for the new path.
[in]newPathNew path name for the file/directory.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFile::rewind ()
+
+inlineinherited
+
+

Set the file's current position to zero.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::rmdir ()
+
+inherited
+
+

Remove a directory file.

+

The directory file will be removed only if it is empty and is not the root directory. rmdir() follows DOS and Windows and ignores the read-only attribute for the directory.

+
Note
This function should not be used to delete the 8.3 version of a directory that has a long name. For example if a directory has the long name "New folder" you should not delete the 8.3 name "NEWFOL~1".
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::rmRfStar ()
+
+inherited
+
+

Recursively delete a directory and all contained files.

+

This is like the Unix/Linux 'rm -rf *' if called with the root directory hence the name.

+

Warning - This will remove all contents of the directory including subdirectories. The directory will then be removed if it is not root. The read-only attribute for files will be ignored.

+
Note
This function should not be used to delete the 8.3 version of a directory that has a long name. See remove() and rmdir().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekCur (int32_t offset)
+
+inlineinherited
+
+

Set the files position to current position + pos. See seekSet().

Parameters
+ + +
[in]offsetThe new position in bytes from the current position.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekEnd (int32_t offset = 0)
+
+inlineinherited
+
+

Set the files position to end-of-file + offset. See seekSet(). Can't be used for directory files since file size is not defined.

Parameters
+ + +
[in]offsetThe new position in bytes from end-of-file.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::seekSet (uint32_t pos)
+
+inherited
+
+

Sets a file's position.

+
Parameters
+ + +
[in]posThe new position in bytes from the beginning of the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
static bool FatFile::setCwd (FatFiledir)
+
+inlinestaticinherited
+
+

Set the current working directory.

+
Parameters
+ + +
[in]dirNew current working directory.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFile::setpos (FatPos_tpos)
+
+inherited
+
+

set position for streams

Parameters
+ + +
[out]posstruct with value for new position
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatFile::sync ()
+
+inherited
+
+

The sync() call causes all modified data and directory fields to be written to the storage device.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::timestamp (FatFilefile)
+
+inherited
+
+

Copy a file's timestamps

+
Parameters
+ + +
[in]fileFile to copy timestamps from.
+
+
+
Note
Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool FatFile::timestamp (uint8_t flags,
uint16_t year,
uint8_t month,
uint8_t day,
uint8_t hour,
uint8_t minute,
uint8_t second 
)
+
+inherited
+
+

Set a file's timestamps in its directory entry.

+
Parameters
+ + +
[in]flagsValues for flags are constructed by a bitwise-inclusive OR of flags from the following list
+
+
+

T_ACCESS - Set the file's last access date.

+

T_CREATE - Set the file's creation date and time.

+

T_WRITE - Set the file's last write/modification date and time.

+
Parameters
+ + + + + + + +
[in]yearValid range 1980 - 2107 inclusive.
[in]monthValid range 1 - 12 inclusive.
[in]dayValid range 1 - 31 inclusive.
[in]hourValid range 0 - 23 inclusive.
[in]minuteValid range 0 - 59 inclusive.
[in]secondValid range 0 - 59 inclusive
+
+
+
Note
It is possible to set an invalid date since there is no check for the number of days in a month.
+
+Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFile::truncate (uint32_t length)
+
+inherited
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + +
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFile::volume () const
+
+inlineinherited
+
+
Returns
FatVolume that contains this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t PrintFile::write (uint8_t b)
+
+inlineinherited
+
+

Read the next byte from a file.

+
Returns
For success return the next byte in the file as an int. If an error occurs or end of file is reached return -1. Write a byte to a file. Required by the Arduino Print class.
+
Parameters
+ + +
[in]bthe byte to be written. Use getWriteError to check for errors.
+
+
+
Returns
1 for success and 0 for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
size_t PrintFile::write (const uint8_t * buf,
size_t size 
)
+
+inlineinherited
+
+

Write data to an open file. Form required by Print.

+
Note
Data is moved to the cache but may not be written to the storage device until sync() is called.
+
Parameters
+ + + +
[in]bufPointer to the location of the data to be written.
[in]sizeNumber of bytes to write.
+
+
+
Returns
For success write() returns the number of bytes written, always nbyte. If an error occurs, write() returns -1. Possible errors include write() is called before a file has been opened, write is called for a read-only file, device is full, a corrupt file system or an I/O error.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int FatFile::write (const char * str)
+
+inlineinherited
+
+

Write a string to a file. Used by the Arduino Print class.

Parameters
+ + +
[in]strPointer to the string. Use getWriteError to check for errors.
+
+
+
Returns
count of characters written for success or -1 for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int FatFile::write (const void * buf,
size_t nbyte 
)
+
+inherited
+
+

Write data to an open file.

+
Note
Data is moved to the cache but may not be written to the storage device until sync() is called.
+
Parameters
+ + + +
[in]bufPointer to the location of the data to be written.
[in]nbyteNumber of bytes to write.
+
+
+
Returns
For success write() returns the number of bytes written, always nbyte. If an error occurs, write() returns -1. Possible errors include write() is called before a file has been opened, write is called for a read-only file, device is full, a corrupt file system or an I/O error.
+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/SdFat.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_file__coll__graph.png b/libraries/SdFat/extras/html/class_sd_file__coll__graph.png new file mode 100644 index 0000000..5112d4b Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_file__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_file__inherit__graph.png b/libraries/SdFat/extras/html/class_sd_file__inherit__graph.png new file mode 100644 index 0000000..5112d4b Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_file__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_file_system-members.html b/libraries/SdFat/extras/html/class_sd_file_system-members.html new file mode 100644 index 0000000..a73d5a8 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_file_system-members.html @@ -0,0 +1,163 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdFileSystem< SdDriverClass > Member List
+
+
+ +

This is the complete list of members for SdFileSystem< SdDriverClass >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin()SdFileSystem< SdDriverClass >inline
FatFileSystem::begin(BlockDriver *blockDev, uint8_t part=0)FatFileSysteminline
blocksPerCluster() const FatVolumeinline
blocksPerFat() const FatVolumeinline
cacheClear()FatVolumeinline
card()SdFileSystem< SdDriverClass >inline
cardErrorCode()SdFileSystem< SdDriverClass >inline
cardErrorData()SdFileSystem< SdDriverClass >inline
chdir(bool set_cwd=false)FatFileSysteminline
chdir(const char *path, bool set_cwd=false)FatFileSysteminline
chvol()FatFileSysteminline
clusterCount() const FatVolumeinline
clusterSizeShift() const FatVolumeinline
dataStartBlock() const FatVolumeinline
dbgFat(uint32_t n, uint32_t *v)FatVolumeinline
errorHalt()SdFileSystem< SdDriverClass >inline
errorHalt(Print *pr)SdFileSystem< SdDriverClass >inline
errorHalt(char const *msg)SdFileSystem< SdDriverClass >inline
errorHalt(Print *pr, char const *msg)SdFileSystem< SdDriverClass >inline
errorHalt(const __FlashStringHelper *msg)SdFileSystem< SdDriverClass >inline
errorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdDriverClass >inline
errorPrint()SdFileSystem< SdDriverClass >inline
errorPrint(Print *pr)SdFileSystem< SdDriverClass >inline
errorPrint(const char *msg)SdFileSystem< SdDriverClass >inline
errorPrint(Print *pr, char const *msg)SdFileSystem< SdDriverClass >inline
errorPrint(const __FlashStringHelper *msg)SdFileSystem< SdDriverClass >inline
errorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdDriverClass >inline
exists(const char *path)FatFileSysteminline
fatCount()FatVolumeinline
fatStartBlock() const FatVolumeinline
fatType() const FatVolumeinline
FatVolume()FatVolumeinline
freeClusterCount()FatVolume
init()FatVolumeinline
init(uint8_t part)FatVolume
initErrorHalt()SdFileSystem< SdDriverClass >inline
initErrorHalt(Print *pr)SdFileSystem< SdDriverClass >inline
initErrorHalt(char const *msg)SdFileSystem< SdDriverClass >inline
initErrorHalt(Print *pr, char const *msg)SdFileSystem< SdDriverClass >inline
initErrorHalt(const __FlashStringHelper *msg)SdFileSystem< SdDriverClass >inline
initErrorHalt(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdDriverClass >inline
initErrorPrint()SdFileSystem< SdDriverClass >inline
initErrorPrint(Print *pr)SdFileSystem< SdDriverClass >inline
initErrorPrint(char const *msg)SdFileSystem< SdDriverClass >inline
initErrorPrint(Print *pr, char const *msg)SdFileSystem< SdDriverClass >inline
initErrorPrint(const __FlashStringHelper *msg)SdFileSystem< SdDriverClass >inline
initErrorPrint(Print *pr, const __FlashStringHelper *msg)SdFileSystem< SdDriverClass >inline
ls(uint8_t flags=0)FatFileSysteminline
ls(const char *path, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, uint8_t flags=0)FatFileSysteminline
ls(print_t *pr, const char *path, uint8_t flags)FatFileSysteminline
mkdir(const char *path, bool pFlag=true)FatFileSysteminline
open(const char *path, uint8_t mode=FILE_READ)FatFileSysteminline
open(const String &path, uint8_t mode=FILE_READ)FatFileSysteminline
remove(const char *path)FatFileSysteminline
rename(const char *oldPath, const char *newPath)FatFileSysteminline
rmdir(const char *path)FatFileSysteminline
rootDirEntryCount() const FatVolumeinline
rootDirStart() const FatVolumeinline
truncate(const char *path, uint32_t length)FatFileSysteminline
vol()FatFileSysteminline
volumeBlockCount() const FatVolumeinline
vwd()FatFileSysteminline
wipe(print_t *pr=0)FatFileSysteminline
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_file_system.html b/libraries/SdFat/extras/html/class_sd_file_system.html new file mode 100644 index 0000000..299e676 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_file_system.html @@ -0,0 +1,2344 @@ + + + + + + +SdFat: SdFileSystem< SdDriverClass > Class Template Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
SdFileSystem< SdDriverClass > Class Template Reference
+
+
+ +

Virtual base class for SdFat library. + More...

+ +

#include <SdFat.h>

+
+Inheritance diagram for SdFileSystem< SdDriverClass >:
+
+
Inheritance graph
+ + + + +
[legend]
+
+Collaboration diagram for SdFileSystem< SdDriverClass >:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin (BlockDriver *blockDev, uint8_t part=0)
 
bool begin ()
 
uint8_t blocksPerCluster () const
 
uint32_t blocksPerFat () const
 
cache_tcacheClear ()
 
SdDriverClass * card ()
 
uint8_t cardErrorCode ()
 
uint32_t cardErrorData ()
 
bool chdir (bool set_cwd=false)
 
bool chdir (const char *path, bool set_cwd=false)
 
void chvol ()
 
uint32_t clusterCount () const
 
uint8_t clusterSizeShift () const
 
uint32_t dataStartBlock () const
 
int8_t dbgFat (uint32_t n, uint32_t *v)
 
void errorHalt ()
 
void errorHalt (Print *pr)
 
void errorHalt (char const *msg)
 
void errorHalt (Print *pr, char const *msg)
 
void errorHalt (const __FlashStringHelper *msg)
 
void errorHalt (Print *pr, const __FlashStringHelper *msg)
 
void errorPrint ()
 
void errorPrint (Print *pr)
 
void errorPrint (const char *msg)
 
void errorPrint (Print *pr, char const *msg)
 
void errorPrint (const __FlashStringHelper *msg)
 
void errorPrint (Print *pr, const __FlashStringHelper *msg)
 
bool exists (const char *path)
 
uint8_t fatCount ()
 
uint32_t fatStartBlock () const
 
uint8_t fatType () const
 
int32_t freeClusterCount ()
 
bool init ()
 
bool init (uint8_t part)
 
void initErrorHalt ()
 
void initErrorHalt (Print *pr)
 
void initErrorHalt (char const *msg)
 
void initErrorHalt (Print *pr, char const *msg)
 
void initErrorHalt (const __FlashStringHelper *msg)
 
void initErrorHalt (Print *pr, const __FlashStringHelper *msg)
 
void initErrorPrint ()
 
void initErrorPrint (Print *pr)
 
void initErrorPrint (char const *msg)
 
void initErrorPrint (Print *pr, char const *msg)
 
void initErrorPrint (const __FlashStringHelper *msg)
 
void initErrorPrint (Print *pr, const __FlashStringHelper *msg)
 
void ls (uint8_t flags=0)
 
void ls (const char *path, uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0)
 
void ls (print_t *pr, const char *path, uint8_t flags)
 
bool mkdir (const char *path, bool pFlag=true)
 
File open (const char *path, uint8_t mode=FILE_READ)
 
File open (const String &path, uint8_t mode=FILE_READ)
 
bool remove (const char *path)
 
bool rename (const char *oldPath, const char *newPath)
 
bool rmdir (const char *path)
 
uint16_t rootDirEntryCount () const
 
uint32_t rootDirStart () const
 
bool truncate (const char *path, uint32_t length)
 
FatVolumevol ()
 
uint32_t volumeBlockCount () const
 
FatFilevwd ()
 
bool wipe (print_t *pr=0)
 
+

Detailed Description

+

template<class SdDriverClass>
+class SdFileSystem< SdDriverClass >

+ +

Virtual base class for SdFat library.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::begin (BlockDriverblockDev,
uint8_t part = 0 
)
+
+inlineinherited
+
+

Initialize an FatFileSystem object.

Parameters
+ + + +
[in]blockDevDevice block driver.
[in]partpartition to initialize.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + +
bool SdFileSystem< SdDriverClass >::begin ()
+
+inline
+
+

Initialize file system.

Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::blocksPerCluster () const
+
+inlineinherited
+
+
Returns
The volume's cluster size in blocks.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::blocksPerFat () const
+
+inlineinherited
+
+
Returns
The number of blocks in one FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
cache_t* FatVolume::cacheClear ()
+
+inlineinherited
+
+

Clear the cache and returns a pointer to the cache. Not for normal apps.

Returns
A pointer to the cache buffer or zero if an error occurs.
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + +
SdDriverClass* SdFileSystem< SdDriverClass >::card ()
+
+inline
+
+
Returns
Pointer to SD card object
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + +
uint8_t SdFileSystem< SdDriverClass >::cardErrorCode ()
+
+inline
+
+
Returns
The card error code
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + +
uint32_t SdFileSystem< SdDriverClass >::cardErrorData ()
+
+inline
+
+
Returns
the card error data
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::chdir (bool set_cwd = false)
+
+inlineinherited
+
+

Change a volume's working directory to root

+

Changes the volume's working directory to the SD's root directory. Optionally set the current working directory to the volume's working directory.

+
Parameters
+ + +
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::chdir (const char * path,
bool set_cwd = false 
)
+
+inlineinherited
+
+

Change a volume's working directory

+

Changes the volume working directory to the path subdirectory. Optionally set the current working directory to the volume's working directory.

+

Example: If the volume's working directory is "/DIR", chdir("SUB") will change the volume's working directory from "/DIR" to "/DIR/SUB".

+

If path is "/", the volume's working directory will be changed to the root directory

+
Parameters
+ + + +
[in]pathThe name of the subdirectory.
[in]set_cwdSet the current working directory to this volume's working directory if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void FatFileSystem::chvol ()
+
+inlineinherited
+
+

Set the current working directory to a volume's working directory.

+

This is useful with multiple SD cards.

+

The current working directory is changed to this volume's working directory.

+

This is like the Windows/DOS <drive letter>: command.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::clusterCount () const
+
+inlineinherited
+
+
Returns
The total number of clusters in the volume.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::clusterSizeShift () const
+
+inlineinherited
+
+
Returns
The shift count required to multiply by blocksPerCluster.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::dataStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of file data.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int8_t FatVolume::dbgFat (uint32_t n,
uint32_t * v 
)
+
+inlineinherited
+
+

Debug access to FAT table

+
Parameters
+ + + +
[in]ncluster number.
[out]vvalue of entry
+
+
+
Returns
true for success or false for failure
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdDriverClass >::errorHalt ()
+
+inline
+
+

Print any SD error code to Serial and halt.

+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::errorHalt (Print * pr)
+
+inline
+
+

Print any SD error code and halt.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::errorHalt (char const * msg)
+
+inline
+
+

Print msg, any SD error code and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdDriverClass >::errorHalt (Print * pr,
char const * msg 
)
+
+inline
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::errorHalt (const __FlashStringHelper * msg)
+
+inline
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdDriverClass >::errorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inline
+
+

Print msg, any SD error code, and halt.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdDriverClass >::errorPrint ()
+
+inline
+
+

Print any SD error code to Serial

+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::errorPrint (Print * pr)
+
+inline
+
+

Print any SD error code.

Parameters
+ + +
[in]prPrint device.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::errorPrint (const char * msg)
+
+inline
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdDriverClass >::errorPrint (Print * pr,
char const * msg 
)
+
+inline
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::errorPrint (const __FlashStringHelper * msg)
+
+inline
+
+

Print msg, any SD error code.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdDriverClass >::errorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inline
+
+

Print msg, any SD error code.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::exists (const char * path)
+
+inlineinherited
+
+

Test for the existence of a file.

+
Parameters
+ + +
[in]pathPath of the file to be tested for.
+
+
+
Returns
true if the file exists else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatCount ()
+
+inlineinherited
+
+
Returns
The number of File Allocation Tables.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::fatStartBlock () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the first FAT.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t FatVolume::fatType () const
+
+inlineinherited
+
+
Returns
The FAT type of the volume. Values are 12, 16 or 32.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int32_t FatVolume::freeClusterCount ()
+
+inherited
+
+

Volume free space in clusters.

+
Returns
Count of free clusters for success or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool FatVolume::init ()
+
+inlineinherited
+
+

Initialize a FAT volume. Try partition one first then try super floppy format.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatVolume::init (uint8_t part)
+
+inherited
+
+

Initialize a FAT volume.

+
Parameters
+ + +
[in]partThe partition to be used. Legal values for part are 1-4 to use the corresponding partition on a device formatted with a MBR, Master Boot Record, or zero if the device is formatted as a super floppy with the FAT boot sector in block zero.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorHalt ()
+
+inline
+
+

Print any SD error code and halt.

+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorHalt (Print * pr)
+
+inline
+
+

Print error details and halt after begin fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorHalt (char const * msg)
+
+inline
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorHalt (Print * pr,
char const * msg 
)
+
+inline
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorHalt (const __FlashStringHelper * msg)
+
+inline
+
+

Print message, error details, and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorHalt (Print * pr,
const __FlashStringHelper * msg 
)
+
+inline
+
+

Print message, error details, and halt after begin() fails.

Parameters
+ + + +
[in]prPrint device for message.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorPrint ()
+
+inline
+
+

Print error details after begin() fails.

+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorPrint (Print * pr)
+
+inline
+
+

Print error details after begin() fails.

+
Parameters
+ + +
[in]prPrint destination.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorPrint (char const * msg)
+
+inline
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorPrint (Print * pr,
char const * msg 
)
+
+inline
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorPrint (const __FlashStringHelper * msg)
+
+inline
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + +
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+
+template<class SdDriverClass>
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void SdFileSystem< SdDriverClass >::initErrorPrint (Print * pr,
const __FlashStringHelper * msg 
)
+
+inline
+
+

Print message and error details and halt after begin() fails.

+
Parameters
+ + + +
[in]prPrint destination.
[in]msgMessage to print.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void FatFileSystem::ls (uint8_t flags = 0)
+
+inlineinherited
+
+

List the directory contents of the volume working directory to Serial.

+
Parameters
+ + +
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (const char * path,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of a directory to Serial.

+
Parameters
+ + + +
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
uint8_t flags = 0 
)
+
+inlineinherited
+
+

List the directory contents of the volume working directory.

+
Parameters
+ + + +
[in]prPrint stream for list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void FatFileSystem::ls (print_tpr,
const char * path,
uint8_t flags 
)
+
+inlineinherited
+
+

List the directory contents of a directory.

+
Parameters
+ + + + +
[in]prPrint stream for list.
[in]pathdirectory to list.
[in]flagsThe inclusive OR of
+
+
+

LS_DATE - Print file modification date

+

LS_SIZE - Print file size.

+

LS_R - Recursive list of subdirectories.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::mkdir (const char * path,
bool pFlag = true 
)
+
+inlineinherited
+
+

Make a subdirectory in the volume working directory.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
[in]pFlagCreate missing parent directories if true.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const char * path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
File FatFileSystem::open (const String & path,
uint8_t mode = FILE_READ 
)
+
+inlineinherited
+
+

open a file

+
Parameters
+ + + +
[in]pathlocation of file to be opened.
[in]modeopen mode flags.
+
+
+
Returns
a File object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::remove (const char * path)
+
+inlineinherited
+
+

Remove a file from the volume working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::rename (const char * oldPath,
const char * newPath 
)
+
+inlineinherited
+
+

Rename a file or subdirectory.

+
Parameters
+ + + +
[in]oldPathPath name to the file or subdirectory to be renamed.
[in]newPathNew path name of the file or subdirectory.
+
+
+

The newPath object must not exist before the rename call.

+

The file to be renamed must not be open. The directory entry may be moved and file system corruption could occur if the file is accessed by a file object that was opened before the rename() call.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::rmdir (const char * path)
+
+inlineinherited
+
+

Remove a subdirectory from the volume's working directory.

+
Parameters
+ + +
[in]pathA path with a valid 8.3 DOS name for the subdirectory.
+
+
+

The subdirectory file will be removed only if it is empty.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint16_t FatVolume::rootDirEntryCount () const
+
+inlineinherited
+
+
Returns
The number of entries in the root directory for FAT16 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::rootDirStart () const
+
+inlineinherited
+
+
Returns
The logical block number for the start of the root directory on FAT16 volumes or the first cluster number on FAT32 volumes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool FatFileSystem::truncate (const char * path,
uint32_t length 
)
+
+inlineinherited
+
+

Truncate a file to a specified length. The current file position will be maintained if it is less than or equal to length otherwise it will be set to end of file.

+
Parameters
+ + + +
[in]pathA path with a valid 8.3 DOS name for the file.
[in]lengthThe desired length for the file.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatVolume* FatFileSystem::vol ()
+
+inlineinherited
+
+
Returns
a pointer to the FatVolume object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t FatVolume::volumeBlockCount () const
+
+inlineinherited
+
+
Returns
The number of blocks in the volume
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
FatFile* FatFileSystem::vwd ()
+
+inlineinherited
+
+
Returns
a pointer to the volume working directory.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool FatFileSystem::wipe (print_tpr = 0)
+
+inlineinherited
+
+

Wipe all data from the volume. You must reinitialize the volume before accessing it again.

Parameters
+ + +
[in]prprint stream for status dots.
+
+
+
Returns
true for success else false.
+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/SdFat.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_file_system__coll__graph.png b/libraries/SdFat/extras/html/class_sd_file_system__coll__graph.png new file mode 100644 index 0000000..1eb49f1 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_file_system__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_file_system__inherit__graph.png b/libraries/SdFat/extras/html/class_sd_file_system__inherit__graph.png new file mode 100644 index 0000000..1eb49f1 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_file_system__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_spi_card-members.html b/libraries/SdFat/extras/html/class_sd_spi_card-members.html new file mode 100644 index 0000000..e318e6a --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_spi_card-members.html @@ -0,0 +1,127 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdSpiCard Member List
+
+
+ +

This is the complete list of members for SdSpiCard, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin(SdSpiDriver *spi, uint8_t csPin, SPISettings spiSettings)SdSpiCard
cardSize()SdSpiCard
erase(uint32_t firstBlock, uint32_t lastBlock)SdSpiCard
eraseSingleBlockEnable()SdSpiCard
error(uint8_t code)SdSpiCardinline
errorCode() const SdSpiCardinline
errorData() const SdSpiCardinline
isBusy()SdSpiCard
readBlock(uint32_t lba, uint8_t *dst)SdSpiCard
readBlocks(uint32_t lba, uint8_t *dst, size_t nb)SdSpiCard
readCID(cid_t *cid)SdSpiCardinline
readCSD(csd_t *csd)SdSpiCardinline
readData(uint8_t *dst)SdSpiCard
readOCR(uint32_t *ocr)SdSpiCard
readStart(uint32_t blockNumber)SdSpiCard
readStatus(uint8_t *status)SdSpiCard
readStop()SdSpiCard
SdSpiCard()SdSpiCardinline
spiStart()SdSpiCard
spiStop()SdSpiCard
syncBlocks()SdSpiCardinline
type() const SdSpiCardinline
writeBlock(uint32_t lba, const uint8_t *src)SdSpiCard
writeBlocks(uint32_t lba, const uint8_t *src, size_t nb)SdSpiCard
writeData(const uint8_t *src)SdSpiCard
writeStart(uint32_t blockNumber)SdSpiCard
writeStart(uint32_t blockNumber, uint32_t eraseCount)SdSpiCard
writeStop()SdSpiCard
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_spi_card.html b/libraries/SdFat/extras/html/class_sd_spi_card.html new file mode 100644 index 0000000..406a316 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_spi_card.html @@ -0,0 +1,923 @@ + + + + + + +SdFat: SdSpiCard Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
SdSpiCard Class Reference
+
+
+ +

Raw access to SD and SDHC flash memory cards via SPI protocol. + More...

+ +

#include <SdSpiCard.h>

+
+Inheritance diagram for SdSpiCard:
+
+
Inheritance graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin (SdSpiDriver *spi, uint8_t csPin, SPISettings spiSettings)
 
uint32_t cardSize ()
 
bool erase (uint32_t firstBlock, uint32_t lastBlock)
 
bool eraseSingleBlockEnable ()
 
void error (uint8_t code)
 
int errorCode () const
 
int errorData () const
 
bool isBusy ()
 
bool readBlock (uint32_t lba, uint8_t *dst)
 
bool readBlocks (uint32_t lba, uint8_t *dst, size_t nb)
 
bool readCID (cid_t *cid)
 
bool readCSD (csd_t *csd)
 
bool readData (uint8_t *dst)
 
bool readOCR (uint32_t *ocr)
 
bool readStart (uint32_t blockNumber)
 
bool readStatus (uint8_t *status)
 
bool readStop ()
 
 SdSpiCard ()
 
void spiStart ()
 
void spiStop ()
 
bool syncBlocks ()
 
int type () const
 
bool writeBlock (uint32_t lba, const uint8_t *src)
 
bool writeBlocks (uint32_t lba, const uint8_t *src, size_t nb)
 
bool writeData (const uint8_t *src)
 
bool writeStart (uint32_t blockNumber)
 
bool writeStart (uint32_t blockNumber, uint32_t eraseCount)
 
bool writeStop ()
 
+

Detailed Description

+

Raw access to SD and SDHC flash memory cards via SPI protocol.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
SdSpiCard::SdSpiCard ()
+
+inline
+
+

Construct an instance of SdSpiCard.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdSpiCard::begin (SdSpiDriver * spi,
uint8_t csPin,
SPISettings spiSettings 
)
+
+

Initialize the SD card.

Parameters
+ + + + +
[in]spiSPI driver for card.
[in]csPincard chip select pin.
[in]spiSettingsSPI speed, mode, and bit order.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + + + +
uint32_t SdSpiCard::cardSize ()
+
+

Determine the size of an SD flash memory card.

+
Returns
The number of 512 byte data blocks in the card or zero if an error occurs.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCard::erase (uint32_t firstBlock,
uint32_t lastBlock 
)
+
+

Erase a range of blocks.

+
Parameters
+ + + +
[in]firstBlockThe address of the first block in the range.
[in]lastBlockThe address of the last block in the range.
+
+
+
Note
This function requests the SD card to do a flash erase for a range of blocks. The data on the card after an erase operation is either 0 or 1, depends on the card vendor. The card must support single block erase.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + +
bool SdSpiCard::eraseSingleBlockEnable ()
+
+

Determine if card supports single block erase.

+
Returns
true is returned if single block erase is supported. false is returned if single block erase is not supported.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdSpiCard::error (uint8_t code)
+
+inline
+
+

Set SD error code.

Parameters
+ + +
[in]codevalue for error code.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SdSpiCard::errorCode () const
+
+inline
+
+
Returns
code for the last error. See SdInfo.h for a list of error codes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SdSpiCard::errorData () const
+
+inline
+
+
Returns
error data for last error.
+ +
+
+ +
+
+ + + + + + + +
bool SdSpiCard::isBusy ()
+
+

Check for busy. MISO low indicates the card is busy.

+
Returns
true if busy else false.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCard::readBlock (uint32_t lba,
uint8_t * dst 
)
+
+

Read a 512 byte block from an SD card.

+
Parameters
+ + + +
[in]lbaLogical block to be read.
[out]dstPointer to the location that will receive the data.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdSpiCard::readBlocks (uint32_t lba,
uint8_t * dst,
size_t nb 
)
+
+

Read multiple 512 byte blocks from an SD card.

+
Parameters
+ + + + +
[in]lbaLogical block to be read.
[in]nbNumber of blocks to be read.
[out]dstPointer to the location that will receive the data.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readCID (cid_t * cid)
+
+inline
+
+

Read a card's CID register. The CID contains card identification information such as Manufacturer ID, Product name, Product serial number and Manufacturing date.

+
Parameters
+ + +
[out]cidpointer to area for returned data.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readCSD (csd_t * csd)
+
+inline
+
+

Read a card's CSD register. The CSD contains Card-Specific Data that provides information regarding access to the card's contents.

+
Parameters
+ + +
[out]csdpointer to area for returned data.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool SdSpiCard::readData (uint8_t * dst)
+
+

Read one data block in a multiple block read sequence

+
Parameters
+ + +
[out]dstPointer to the location for the data to be read.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool SdSpiCard::readOCR (uint32_t * ocr)
+
+

Read OCR register.

+
Parameters
+ + +
[out]ocrValue of OCR register.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + + + + +
bool SdSpiCard::readStart (uint32_t blockNumber)
+
+

Start a read multiple blocks sequence.

+
Parameters
+ + +
[in]blockNumberAddress of first block in sequence.
+
+
+
Note
This function is used with readData() and readStop() for optimized multiple block reads. SPI chipSelect must be low for the entire sequence.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool SdSpiCard::readStatus (uint8_t * status)
+
+

Return the 64 byte card status

Parameters
+ + +
[out]statuslocation for 64 status bytes.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + +
bool SdSpiCard::readStop ()
+
+

End a read multiple blocks sequence.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + +
void SdSpiCard::spiStart ()
+
+

Set CS low and activate the card.

+ +
+
+ +
+
+ + + + + + + +
void SdSpiCard::spiStop ()
+
+

Set CS high and deactivate the card.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdSpiCard::syncBlocks ()
+
+inline
+
+
Returns
success if sync successful. Not for user apps.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SdSpiCard::type () const
+
+inline
+
+

Return the card type: SD V1, SD V2 or SDHC

Returns
0 - SD V1, 1 - SD V2, or 3 - SDHC.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCard::writeBlock (uint32_t lba,
const uint8_t * src 
)
+
+

Writes a 512 byte block to an SD card.

+
Parameters
+ + + +
[in]lbaLogical block to be written.
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdSpiCard::writeBlocks (uint32_t lba,
const uint8_t * src,
size_t nb 
)
+
+

Write multiple 512 byte blocks to an SD card.

+
Parameters
+ + + + +
[in]lbaLogical block to be written.
[in]nbNumber of blocks to be written.
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool SdSpiCard::writeData (const uint8_t * src)
+
+

Write one data block in a multiple block write sequence.

Parameters
+ + +
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool SdSpiCard::writeStart (uint32_t blockNumber)
+
+

Start a write multiple blocks sequence.

+
Parameters
+ + +
[in]blockNumberAddress of first block in sequence.
+
+
+
Note
This function is used with writeData() and writeStop() for optimized multiple block writes.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCard::writeStart (uint32_t blockNumber,
uint32_t eraseCount 
)
+
+

Start a write multiple blocks sequence with pre-erase.

+
Parameters
+ + + +
[in]blockNumberAddress of first block in sequence.
[in]eraseCountThe number of blocks to be pre-erased.
+
+
+
Note
This function is used with writeData() and writeStop() for optimized multiple block writes.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + +
bool SdSpiCard::writeStop ()
+
+

End a write multiple blocks sequence.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • Arduino/libraries/SdFat/src/SdCard/SdSpiCard.h
  • +
  • Arduino/libraries/SdFat/src/SdCard/SdSpiCard.cpp
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_spi_card__inherit__graph.png b/libraries/SdFat/extras/html/class_sd_spi_card__inherit__graph.png new file mode 100644 index 0000000..4f96ac4 Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_spi_card__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_spi_card_e_x-members.html b/libraries/SdFat/extras/html/class_sd_spi_card_e_x-members.html new file mode 100644 index 0000000..1c12ae7 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_spi_card_e_x-members.html @@ -0,0 +1,127 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdSpiCardEX Member List
+
+
+ +

This is the complete list of members for SdSpiCardEX, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin(SdSpiDriver *spi, uint8_t csPin, SPISettings spiSettings)SdSpiCardEXinline
cardSize()SdSpiCard
erase(uint32_t firstBlock, uint32_t lastBlock)SdSpiCard
eraseSingleBlockEnable()SdSpiCard
error(uint8_t code)SdSpiCardinline
errorCode() const SdSpiCardinline
errorData() const SdSpiCardinline
isBusy()SdSpiCard
readBlock(uint32_t block, uint8_t *dst)SdSpiCardEX
readBlocks(uint32_t block, uint8_t *dst, size_t nb)SdSpiCardEX
readCID(cid_t *cid)SdSpiCardinline
readCSD(csd_t *csd)SdSpiCardinline
readData(uint8_t *dst)SdSpiCard
readOCR(uint32_t *ocr)SdSpiCard
readStart(uint32_t blockNumber)SdSpiCard
readStatus(uint8_t *status)SdSpiCard
readStop()SdSpiCard
SdSpiCard()SdSpiCardinline
spiStart()SdSpiCard
spiStop()SdSpiCard
syncBlocks()SdSpiCardEX
type() const SdSpiCardinline
writeBlock(uint32_t block, const uint8_t *src)SdSpiCardEX
writeBlocks(uint32_t block, const uint8_t *src, size_t nb)SdSpiCardEX
writeData(const uint8_t *src)SdSpiCard
writeStart(uint32_t blockNumber)SdSpiCard
writeStart(uint32_t blockNumber, uint32_t eraseCount)SdSpiCard
writeStop()SdSpiCard
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_spi_card_e_x.html b/libraries/SdFat/extras/html/class_sd_spi_card_e_x.html new file mode 100644 index 0000000..722e4f0 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sd_spi_card_e_x.html @@ -0,0 +1,1024 @@ + + + + + + +SdFat: SdSpiCardEX Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
SdSpiCardEX Class Reference
+
+
+ +

Extended SD I/O block driver. + More...

+ +

#include <SdSpiCard.h>

+
+Inheritance diagram for SdSpiCardEX:
+
+
Inheritance graph
+ + + +
[legend]
+
+Collaboration diagram for SdSpiCardEX:
+
+
Collaboration graph
+ + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin (SdSpiDriver *spi, uint8_t csPin, SPISettings spiSettings)
 
uint32_t cardSize ()
 
bool erase (uint32_t firstBlock, uint32_t lastBlock)
 
bool eraseSingleBlockEnable ()
 
void error (uint8_t code)
 
int errorCode () const
 
int errorData () const
 
bool isBusy ()
 
bool readBlock (uint32_t block, uint8_t *dst)
 
bool readBlocks (uint32_t block, uint8_t *dst, size_t nb)
 
bool readCID (cid_t *cid)
 
bool readCSD (csd_t *csd)
 
bool readData (uint8_t *dst)
 
bool readOCR (uint32_t *ocr)
 
bool readStart (uint32_t blockNumber)
 
bool readStatus (uint8_t *status)
 
bool readStop ()
 
void spiStart ()
 
void spiStop ()
 
bool syncBlocks ()
 
int type () const
 
bool writeBlock (uint32_t block, const uint8_t *src)
 
bool writeBlocks (uint32_t block, const uint8_t *src, size_t nb)
 
bool writeData (const uint8_t *src)
 
bool writeStart (uint32_t blockNumber)
 
bool writeStart (uint32_t blockNumber, uint32_t eraseCount)
 
bool writeStop ()
 
+

Detailed Description

+

Extended SD I/O block driver.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdSpiCardEX::begin (SdSpiDriver * spi,
uint8_t csPin,
SPISettings spiSettings 
)
+
+inline
+
+

Initialize the SD card

+
Parameters
+ + + + +
[in]spiSPI driver.
[in]csPinCard chip select pin number.
[in]spiSettingsSPI speed, mode, and bit order.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint32_t SdSpiCard::cardSize ()
+
+inherited
+
+

Determine the size of an SD flash memory card.

+
Returns
The number of 512 byte data blocks in the card or zero if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCard::erase (uint32_t firstBlock,
uint32_t lastBlock 
)
+
+inherited
+
+

Erase a range of blocks.

+
Parameters
+ + + +
[in]firstBlockThe address of the first block in the range.
[in]lastBlockThe address of the last block in the range.
+
+
+
Note
This function requests the SD card to do a flash erase for a range of blocks. The data on the card after an erase operation is either 0 or 1, depends on the card vendor. The card must support single block erase.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdSpiCard::eraseSingleBlockEnable ()
+
+inherited
+
+

Determine if card supports single block erase.

+
Returns
true is returned if single block erase is supported. false is returned if single block erase is not supported.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SdSpiCard::error (uint8_t code)
+
+inlineinherited
+
+

Set SD error code.

Parameters
+ + +
[in]codevalue for error code.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SdSpiCard::errorCode () const
+
+inlineinherited
+
+
Returns
code for the last error. See SdInfo.h for a list of error codes.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SdSpiCard::errorData () const
+
+inlineinherited
+
+
Returns
error data for last error.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdSpiCard::isBusy ()
+
+inherited
+
+

Check for busy. MISO low indicates the card is busy.

+
Returns
true if busy else false.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCardEX::readBlock (uint32_t block,
uint8_t * dst 
)
+
+

Read a 512 byte block from an SD card.

+
Parameters
+ + + +
[in]blockLogical block to be read.
[out]dstPointer to the location that will receive the data.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdSpiCardEX::readBlocks (uint32_t block,
uint8_t * dst,
size_t nb 
)
+
+

Read multiple 512 byte blocks from an SD card.

+
Parameters
+ + + + +
[in]blockLogical block to be read.
[in]nbNumber of blocks to be read.
[out]dstPointer to the location that will receive the data.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readCID (cid_t * cid)
+
+inlineinherited
+
+

Read a card's CID register. The CID contains card identification information such as Manufacturer ID, Product name, Product serial number and Manufacturing date.

+
Parameters
+ + +
[out]cidpointer to area for returned data.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readCSD (csd_t * csd)
+
+inlineinherited
+
+

Read a card's CSD register. The CSD contains Card-Specific Data that provides information regarding access to the card's contents.

+
Parameters
+ + +
[out]csdpointer to area for returned data.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readData (uint8_t * dst)
+
+inherited
+
+

Read one data block in a multiple block read sequence

+
Parameters
+ + +
[out]dstPointer to the location for the data to be read.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readOCR (uint32_t * ocr)
+
+inherited
+
+

Read OCR register.

+
Parameters
+ + +
[out]ocrValue of OCR register.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readStart (uint32_t blockNumber)
+
+inherited
+
+

Start a read multiple blocks sequence.

+
Parameters
+ + +
[in]blockNumberAddress of first block in sequence.
+
+
+
Note
This function is used with readData() and readStop() for optimized multiple block reads. SPI chipSelect must be low for the entire sequence.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::readStatus (uint8_t * status)
+
+inherited
+
+

Return the 64 byte card status

Parameters
+ + +
[out]statuslocation for 64 status bytes.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdSpiCard::readStop ()
+
+inherited
+
+

End a read multiple blocks sequence.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdSpiCard::spiStart ()
+
+inherited
+
+

Set CS low and activate the card.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SdSpiCard::spiStop ()
+
+inherited
+
+

Set CS high and deactivate the card.

+ +
+
+ +
+
+ + + + + + + +
bool SdSpiCardEX::syncBlocks ()
+
+

End multi-block transfer and go to idle state.

Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SdSpiCard::type () const
+
+inlineinherited
+
+

Return the card type: SD V1, SD V2 or SDHC

Returns
0 - SD V1, 1 - SD V2, or 3 - SDHC.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCardEX::writeBlock (uint32_t block,
const uint8_t * src 
)
+
+

Writes a 512 byte block to an SD card.

+
Parameters
+ + + +
[in]blockLogical block to be written.
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdSpiCardEX::writeBlocks (uint32_t block,
const uint8_t * src,
size_t nb 
)
+
+

Write multiple 512 byte blocks to an SD card.

+
Parameters
+ + + + +
[in]blockLogical block to be written.
[in]nbNumber of blocks to be written.
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::writeData (const uint8_t * src)
+
+inherited
+
+

Write one data block in a multiple block write sequence.

Parameters
+ + +
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool SdSpiCard::writeStart (uint32_t blockNumber)
+
+inherited
+
+

Start a write multiple blocks sequence.

+
Parameters
+ + +
[in]blockNumberAddress of first block in sequence.
+
+
+
Note
This function is used with writeData() and writeStop() for optimized multiple block writes.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdSpiCard::writeStart (uint32_t blockNumber,
uint32_t eraseCount 
)
+
+inherited
+
+

Start a write multiple blocks sequence with pre-erase.

+
Parameters
+ + + +
[in]blockNumberAddress of first block in sequence.
[in]eraseCountThe number of blocks to be pre-erased.
+
+
+
Note
This function is used with writeData() and writeStop() for optimized multiple block writes.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdSpiCard::writeStop ()
+
+inherited
+
+

End a write multiple blocks sequence.

+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • Arduino/libraries/SdFat/src/SdCard/SdSpiCard.h
  • +
  • Arduino/libraries/SdFat/src/SdCard/SdSpiCardEX.cpp
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sd_spi_card_e_x__coll__graph.png b/libraries/SdFat/extras/html/class_sd_spi_card_e_x__coll__graph.png new file mode 100644 index 0000000..93643bb Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_spi_card_e_x__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sd_spi_card_e_x__inherit__graph.png b/libraries/SdFat/extras/html/class_sd_spi_card_e_x__inherit__graph.png new file mode 100644 index 0000000..93643bb Binary files /dev/null and b/libraries/SdFat/extras/html/class_sd_spi_card_e_x__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sdio_card-members.html b/libraries/SdFat/extras/html/class_sdio_card-members.html new file mode 100644 index 0000000..35749db --- /dev/null +++ b/libraries/SdFat/extras/html/class_sdio_card-members.html @@ -0,0 +1,115 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SdioCard Member List
+
+
+ +

This is the complete list of members for SdioCard, including all inherited members.

+ + + + + + + + + + + + + + + + + +
begin()SdioCard
cardSize()SdioCard
dmaBusy()SdioCard
erase(uint32_t firstBlock, uint32_t lastBlock)SdioCard
errorCode()SdioCard
errorData()SdioCard
errorLine()SdioCard
readBlock(uint32_t lba, uint8_t *dst)SdioCardvirtual
readBlocks(uint32_t lba, uint8_t *dst, size_t nb)SdioCardvirtual
readCID(void *cid)SdioCard
readCSD(void *csd)SdioCard
readOCR(uint32_t *ocr)SdioCard
syncBlocks()SdioCardvirtual
type()SdioCard
writeBlock(uint32_t lba, const uint8_t *src)SdioCardvirtual
writeBlocks(uint32_t lba, const uint8_t *src, size_t nb)SdioCardvirtual
+ + + + diff --git a/libraries/SdFat/extras/html/class_sdio_card.html b/libraries/SdFat/extras/html/class_sdio_card.html new file mode 100644 index 0000000..9f51aa2 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sdio_card.html @@ -0,0 +1,603 @@ + + + + + + +SdFat: SdioCard Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
SdioCard Class Reference
+
+
+ +

Raw SDIO access to SD and SDHC flash memory cards. + More...

+ +

#include <SdioCard.h>

+
+Inheritance diagram for SdioCard:
+
+
Inheritance graph
+ + + +
[legend]
+
+Collaboration diagram for SdioCard:
+
+
Collaboration graph
+ + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool begin ()
 
uint32_t cardSize ()
 
bool dmaBusy ()
 
bool erase (uint32_t firstBlock, uint32_t lastBlock)
 
uint8_t errorCode ()
 
uint32_t errorData ()
 
uint32_t errorLine ()
 
bool readBlock (uint32_t lba, uint8_t *dst)
 
bool readBlocks (uint32_t lba, uint8_t *dst, size_t nb)
 
bool readCID (void *cid)
 
bool readCSD (void *csd)
 
bool readOCR (uint32_t *ocr)
 
bool syncBlocks ()
 
uint8_t type ()
 
bool writeBlock (uint32_t lba, const uint8_t *src)
 
bool writeBlocks (uint32_t lba, const uint8_t *src, size_t nb)
 
+

Detailed Description

+

Raw SDIO access to SD and SDHC flash memory cards.

+

Member Function Documentation

+ +
+
+ + + + + + + +
bool SdioCard::begin ()
+
+

Initialize the SD card.

Returns
true for success else false.
+ +
+
+ +
+
+ + + + + + + +
uint32_t SdioCard::cardSize ()
+
+

Determine the size of an SD flash memory card.

+
Returns
The number of 512 byte data blocks in the card or zero if an error occurs.
+ +
+
+ +
+
+ + + + + + + +
bool SdioCard::dmaBusy ()
+
+
Returns
DMA transfer status.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool SdioCard::erase (uint32_t firstBlock,
uint32_t lastBlock 
)
+
+

Erase a range of blocks.

+
Parameters
+ + + +
[in]firstBlockThe address of the first block in the range.
[in]lastBlockThe address of the last block in the range.
+
+
+
Note
This function requests the SD card to do a flash erase for a range of blocks. The data on the card after an erase operation is either 0 or 1, depends on the card vendor. The card must support single block erase.
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +
+
+ +
+
+ + + + + + + +
uint8_t SdioCard::errorCode ()
+
+
Returns
code for the last error. See SdInfo.h for a list of error codes.
+ +
+
+ +
+
+ + + + + + + +
uint32_t SdioCard::errorData ()
+
+
Returns
error data for last error.
+ +
+
+ +
+
+ + + + + + + +
uint32_t SdioCard::errorLine ()
+
+
Returns
error line for last error. Tmp function for debug.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdioCard::readBlock (uint32_t lba,
uint8_t * dst 
)
+
+virtual
+
+

Read a 512 byte block from an SD card.

+
Parameters
+ + + +
[in]lbaLogical block to be read.
[out]dstPointer to the location that will receive the data.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +

Implements BaseBlockDriver.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdioCard::readBlocks (uint32_t lba,
uint8_t * dst,
size_t nb 
)
+
+virtual
+
+

Read multiple 512 byte blocks from an SD card.

+
Parameters
+ + + + +
[in]lbaLogical block to be read.
[in]nbNumber of blocks to be read.
[out]dstPointer to the location that will receive the data.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +

Implements BaseBlockDriver.

+ +
+
+ +
+
+ + + + + + + + +
bool SdioCard::readCID (void * cid)
+
+

Read a card's CID register. The CID contains card identification information such as Manufacturer ID, Product name, Product serial number and Manufacturing date.

+
Parameters
+ + +
[out]cidpointer to area for returned data.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool SdioCard::readCSD (void * csd)
+
+

Read a card's CSD register. The CSD contains Card-Specific Data that provides information regarding access to the card's contents.

+
Parameters
+ + +
[out]csdpointer to area for returned data.
+
+
+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + + + + +
bool SdioCard::readOCR (uint32_t * ocr)
+
+

Read OCR register.

+
Parameters
+ + +
[out]ocrValue of OCR register.
+
+
+
Returns
true for success else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool SdioCard::syncBlocks ()
+
+virtual
+
+
Returns
success if sync successful. Not for user apps.
+ +

Implements BaseBlockDriver.

+ +
+
+ +
+
+ + + + + + + +
uint8_t SdioCard::type ()
+
+

Return the card type: SD V1, SD V2 or SDHC

Returns
0 - SD V1, 1 - SD V2, or 3 - SDHC.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool SdioCard::writeBlock (uint32_t lba,
const uint8_t * src 
)
+
+virtual
+
+

Writes a 512 byte block to an SD card.

+
Parameters
+ + + +
[in]lbaLogical block to be written.
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +

Implements BaseBlockDriver.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool SdioCard::writeBlocks (uint32_t lba,
const uint8_t * src,
size_t nb 
)
+
+virtual
+
+

Write multiple 512 byte blocks to an SD card.

+
Parameters
+ + + + +
[in]lbaLogical block to be written.
[in]nbNumber of blocks to be written.
[in]srcPointer to the location of the data to be written.
+
+
+
Returns
The value true is returned for success and the value false is returned for failure.
+ +

Implements BaseBlockDriver.

+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/SdCard/SdioCard.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_sdio_card__coll__graph.png b/libraries/SdFat/extras/html/class_sdio_card__coll__graph.png new file mode 100644 index 0000000..a82e5bc Binary files /dev/null and b/libraries/SdFat/extras/html/class_sdio_card__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sdio_card__inherit__graph.png b/libraries/SdFat/extras/html/class_sdio_card__inherit__graph.png new file mode 100644 index 0000000..a82e5bc Binary files /dev/null and b/libraries/SdFat/extras/html/class_sdio_card__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_stdio_stream-members.html b/libraries/SdFat/extras/html/class_stdio_stream-members.html new file mode 100644 index 0000000..8e77da3 --- /dev/null +++ b/libraries/SdFat/extras/html/class_stdio_stream-members.html @@ -0,0 +1,229 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
StdioStream Member List
+
+
+ +

This is the complete list of members for StdioStream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
available()FatFileinlineprivate
clearerr()StdioStreaminline
clearError()FatFileinlineprivate
clearWriteError()FatFileinlineprivate
close()FatFileprivate
contiguousRange(uint32_t *bgnBlock, uint32_t *endBlock)FatFileprivate
createContiguous(FatFile *dirFile, const char *path, uint32_t size)FatFileprivate
createContiguous(const char *path, uint32_t size)FatFileinlineprivate
curCluster() const FatFileinlineprivate
curPosition() const FatFileinlineprivate
cwd()FatFileinlineprivatestatic
dateTimeCallback(void(*dateTime)(uint16_t *date, uint16_t *time))FatFileinlineprivatestatic
dateTimeCallbackCancel()FatFileinlineprivatestatic
dirEntry(dir_t *dir)FatFileprivate
dirIndex()FatFileinlineprivate
dirName(const dir_t *dir, char *name)FatFileprivatestatic
dirSize()FatFileprivate
dmpFile(print_t *pr, uint32_t pos, size_t n)FatFileprivate
exists(const char *path)FatFileinlineprivate
FatFile()FatFileinlineprivate
FatFile(const char *path, uint8_t oflag)FatFileinlineprivate
fclose()StdioStream
feof()StdioStreaminline
ferror()StdioStreaminline
fflush()StdioStream
fgetc()StdioStreaminline
fgets(char *str, size_t num, size_t *len=0)StdioStream
FatFile::fgets(char *str, int16_t num, char *delim=0)FatFileprivate
fileAttr() const FatFileinlineprivate
fileSize() const FatFileinlineprivate
firstBlock()FatFileinlineprivate
firstCluster() const FatFileinlineprivate
fopen(const char *path, const char *mode)StdioStream
fputc(int c)StdioStreaminline
fputs(const char *str)StdioStream
fread(void *ptr, size_t size, size_t count)StdioStream
fseek(int32_t offset, int origin)StdioStream
ftell()StdioStream
fwrite(const void *ptr, size_t size, size_t count)StdioStream
getc()StdioStreaminline
getError()FatFileinlineprivate
getName(char *name, size_t size)FatFileprivate
getpos(FatPos_t *pos)FatFileprivate
getSFN(char *name)FatFileprivate
getWriteError()FatFileinlineprivate
isDir() const FatFileinlineprivate
isFile() const FatFileinlineprivate
isHidden() const FatFileinlineprivate
isLFN() const FatFileinlineprivate
isOpen() const FatFileinlineprivate
isReadOnly() const FatFileinlineprivate
isRoot() const FatFileinlineprivate
isRoot32() const FatFileinlineprivate
isRootFixed() const FatFileinlineprivate
isSubDir() const FatFileinlineprivate
isSystem() const FatFileinlineprivate
legal83Char(uint8_t c)FatFileinlineprivatestatic
ls(uint8_t flags=0)FatFileinlineprivate
ls(print_t *pr, uint8_t flags=0, uint8_t indent=0)FatFileprivate
mkdir(FatFile *dir, const char *path, bool pFlag=true)FatFileprivate
open(FatFileSystem *fs, const char *path, uint8_t oflag)FatFileprivate
open(FatFile *dirFile, uint16_t index, uint8_t oflag)FatFileprivate
open(FatFile *dirFile, const char *path, uint8_t oflag)FatFileprivate
open(const char *path, uint8_t oflag=O_READ)FatFileinlineprivate
openNext(FatFile *dirFile, uint8_t oflag=O_READ)FatFileprivate
openRoot(FatVolume *vol)FatFileprivate
peek()FatFileprivate
print(char c)StdioStreaminline
print(const char *str)StdioStreaminline
print(const __FlashStringHelper *str)StdioStream
print(double val, uint8_t prec=2)StdioStreaminline
print(float val, uint8_t prec=2)StdioStreaminline
print(T val)StdioStreaminline
printCreateDateTime(print_t *pr)FatFileprivate
printDec(char n)StdioStreaminline
printDec(signed char n)StdioStream
printDec(unsigned char n)StdioStreaminline
printDec(int16_t n)StdioStream
printDec(uint16_t n)StdioStream
printDec(int32_t n)StdioStream
printDec(uint32_t n)StdioStream
printDec(double value, uint8_t prec)StdioStreaminline
printDec(float value, uint8_t prec)StdioStream
printFatDate(uint16_t fatDate)FatFileinlineprivatestatic
printFatDate(print_t *pr, uint16_t fatDate)FatFileprivatestatic
printFatTime(uint16_t fatTime)FatFileinlineprivatestatic
printFatTime(print_t *pr, uint16_t fatTime)FatFileprivatestatic
printField(double value, char term, uint8_t prec=2)StdioStreaminline
printField(float value, char term, uint8_t prec=2)StdioStreaminline
printField(T value, char term)StdioStreaminline
FatFile::printField(int16_t value, char term)FatFileprivate
FatFile::printField(uint16_t value, char term)FatFileprivate
FatFile::printField(int32_t value, char term)FatFileprivate
FatFile::printField(uint32_t value, char term)FatFileprivate
printFileSize(print_t *pr)FatFileprivate
printHex(uint32_t n)StdioStream
printHexln(uint32_t n)StdioStreaminline
println()StdioStreaminline
println(double val, uint8_t prec=2)StdioStreaminline
println(float val, uint8_t prec=2)StdioStreaminline
println(T val)StdioStreaminline
printModifyDateTime(print_t *pr)FatFileprivate
printName()FatFileinlineprivate
printName(print_t *pr)FatFileprivate
printSFN(print_t *pr)FatFileprivate
putc(int c)StdioStreaminline
putCRLF()StdioStreaminline
read()FatFileinlineprivate
read(void *buf, size_t nbyte)FatFileprivate
readDir(dir_t *dir)FatFileprivate
remove()FatFileprivate
remove(FatFile *dirFile, const char *path)FatFileprivatestatic
rename(FatFile *dirFile, const char *newPath)FatFileprivate
rewind()StdioStream
rmdir()FatFileprivate
rmRfStar()FatFileprivate
seekCur(int32_t offset)FatFileinlineprivate
seekEnd(int32_t offset=0)FatFileinlineprivate
seekSet(uint32_t pos)FatFileprivate
setCwd(FatFile *dir)FatFileinlineprivatestatic
setpos(FatPos_t *pos)FatFileprivate
StdioStream()StdioStreaminline
sync()FatFileprivate
timestamp(FatFile *file)FatFileprivate
timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)FatFileprivate
truncate(uint32_t length)FatFileprivate
ungetc(int c)StdioStream
volume() const FatFileinlineprivate
FatFile::write(const char *str)FatFileinlineprivate
FatFile::write(uint8_t b)FatFileinlineprivate
+ + + + diff --git a/libraries/SdFat/extras/html/class_stdio_stream.html b/libraries/SdFat/extras/html/class_stdio_stream.html new file mode 100644 index 0000000..ce244df --- /dev/null +++ b/libraries/SdFat/extras/html/class_stdio_stream.html @@ -0,0 +1,1781 @@ + + + + + + +SdFat: StdioStream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

StdioStream implements a minimal stdio stream. + More...

+ +

#include <StdioStream.h>

+
+Inheritance diagram for StdioStream:
+
+
Inheritance graph
+ + + +
[legend]
+
+Collaboration diagram for StdioStream:
+
+
Collaboration graph
+ + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

void clearerr ()
 
int fclose ()
 
int feof ()
 
int ferror ()
 
int fflush ()
 
int fgetc ()
 
char * fgets (char *str, size_t num, size_t *len=0)
 
bool fopen (const char *path, const char *mode)
 
int fputc (int c)
 
int fputs (const char *str)
 
size_t fread (void *ptr, size_t size, size_t count)
 
int fseek (int32_t offset, int origin)
 
int32_t ftell ()
 
size_t fwrite (const void *ptr, size_t size, size_t count)
 
int getc ()
 
size_t print (char c)
 
size_t print (const char *str)
 
size_t print (const __FlashStringHelper *str)
 
size_t print (double val, uint8_t prec=2)
 
size_t print (float val, uint8_t prec=2)
 
template<typename T >
size_t print (T val)
 
int printDec (char n)
 
int printDec (signed char n)
 
int printDec (unsigned char n)
 
int printDec (int16_t n)
 
int printDec (uint16_t n)
 
int printDec (int32_t n)
 
int printDec (uint32_t n)
 
int printDec (double value, uint8_t prec)
 
int printDec (float value, uint8_t prec)
 
int printField (double value, char term, uint8_t prec=2)
 
int printField (float value, char term, uint8_t prec=2)
 
template<typename T >
int printField (T value, char term)
 
int printHex (uint32_t n)
 
int printHexln (uint32_t n)
 
size_t println ()
 
size_t println (double val, uint8_t prec=2)
 
size_t println (float val, uint8_t prec=2)
 
template<typename T >
size_t println (T val)
 
int putc (int c)
 
int putCRLF ()
 
bool rewind ()
 
 StdioStream ()
 
int ungetc (int c)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

uint32_t available ()
 
void clearError ()
 
void clearWriteError ()
 
bool close ()
 
bool contiguousRange (uint32_t *bgnBlock, uint32_t *endBlock)
 
bool createContiguous (FatFile *dirFile, const char *path, uint32_t size)
 
bool createContiguous (const char *path, uint32_t size)
 
uint32_t curCluster () const
 
uint32_t curPosition () const
 
bool dirEntry (dir_t *dir)
 
uint16_t dirIndex ()
 
uint32_t dirSize ()
 
void dmpFile (print_t *pr, uint32_t pos, size_t n)
 
bool exists (const char *path)
 
int16_t fgets (char *str, int16_t num, char *delim=0)
 
uint8_t fileAttr () const
 
uint32_t fileSize () const
 
uint32_t firstBlock ()
 
uint32_t firstCluster () const
 
uint8_t getError ()
 
bool getName (char *name, size_t size)
 
void getpos (FatPos_t *pos)
 
bool getSFN (char *name)
 
bool getWriteError ()
 
bool isDir () const
 
bool isFile () const
 
bool isHidden () const
 
bool isLFN () const
 
bool isOpen () const
 
bool isReadOnly () const
 
bool isRoot () const
 
bool isRoot32 () const
 
bool isRootFixed () const
 
bool isSubDir () const
 
bool isSystem () const
 
void ls (uint8_t flags=0)
 
void ls (print_t *pr, uint8_t flags=0, uint8_t indent=0)
 
bool mkdir (FatFile *dir, const char *path, bool pFlag=true)
 
bool open (FatFileSystem *fs, const char *path, uint8_t oflag)
 
bool open (FatFile *dirFile, uint16_t index, uint8_t oflag)
 
bool open (FatFile *dirFile, const char *path, uint8_t oflag)
 
bool open (const char *path, uint8_t oflag=O_READ)
 
bool openNext (FatFile *dirFile, uint8_t oflag=O_READ)
 
bool openRoot (FatVolume *vol)
 
int peek ()
 
bool printCreateDateTime (print_t *pr)
 
int printField (int16_t value, char term)
 
int printField (uint16_t value, char term)
 
int printField (int32_t value, char term)
 
int printField (uint32_t value, char term)
 
size_t printFileSize (print_t *pr)
 
bool printModifyDateTime (print_t *pr)
 
size_t printName ()
 
size_t printName (print_t *pr)
 
size_t printSFN (print_t *pr)
 
int read ()
 
int read (void *buf, size_t nbyte)
 
int8_t readDir (dir_t *dir)
 
bool remove ()
 
bool rename (FatFile *dirFile, const char *newPath)
 
bool rmdir ()
 
bool rmRfStar ()
 
bool seekCur (int32_t offset)
 
bool seekEnd (int32_t offset=0)
 
bool seekSet (uint32_t pos)
 
void setpos (FatPos_t *pos)
 
bool sync ()
 
bool timestamp (FatFile *file)
 
bool timestamp (uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
 
bool truncate (uint32_t length)
 
FatVolumevolume () const
 
int write (const char *str)
 
int write (uint8_t b)
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Static Private Member Functions

static FatFilecwd ()
 
static void dateTimeCallback (void(*dateTime)(uint16_t *date, uint16_t *time))
 
static void dateTimeCallbackCancel ()
 
static uint8_t dirName (const dir_t *dir, char *name)
 
static bool legal83Char (uint8_t c)
 
static void printFatDate (uint16_t fatDate)
 
static void printFatDate (print_t *pr, uint16_t fatDate)
 
static void printFatTime (uint16_t fatTime)
 
static void printFatTime (print_t *pr, uint16_t fatTime)
 
static bool remove (FatFile *dirFile, const char *path)
 
static bool setCwd (FatFile *dir)
 
+

Detailed Description

+

StdioStream implements a minimal stdio stream.

+

StdioStream does not support subdirectories or long file names.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
StdioStream::StdioStream ()
+
+inline
+
+

Constructor

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
void StdioStream::clearerr ()
+
+inline
+
+

Clear the stream's end-of-file and error indicators.

+ +
+
+ +
+
+ + + + + + + +
int StdioStream::fclose ()
+
+

Close a stream.

+

A successful call to the fclose function causes the stream to be flushed and the associated file to be closed. Any unwritten buffered data is written to the file; any unread buffered data is discarded. Whether or not the call succeeds, the stream is disassociated from the file.

+
Returns
zero if the stream was successfully closed, or EOF if any any errors are detected.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int StdioStream::feof ()
+
+inline
+
+

Test the stream's end-of-file indicator.

Returns
non-zero if and only if the end-of-file indicator is set.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int StdioStream::ferror ()
+
+inline
+
+

Test the stream's error indicator.

Returns
return non-zero if and only if the error indicator is set.
+ +
+
+ +
+
+ + + + + + + +
int StdioStream::fflush ()
+
+

Flush the stream.

+

If stream is an output stream or an update stream in which the most recent operation was not input, any unwritten data is written to the file; otherwise the call is an error since any buffered input data would be lost.

+
Returns
sets the error indicator for the stream and returns EOF if an error occurs, otherwise it returns zero.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int StdioStream::fgetc ()
+
+inline
+
+

Get a byte from the stream.

+
Returns
If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream is set and the fgetc function returns EOF. Otherwise, the fgetc function returns the next character from the input stream.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
char * StdioStream::fgets (char * str,
size_t num,
size_t * len = 0 
)
+
+

Get a string from a stream.

+

The fgets function reads at most one less than the number of characters specified by num from the stream into the array pointed to by str. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array.

+
Parameters
+ + + + +
[out]strPointer to an array of where the string is copied.
[in]numMaximum number of characters including the null character.
[out]lenIf len is not null and fgets is successful, the length of the string is returned.
+
+
+
Returns
str if successful. If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the array contents are indeterminate and a null pointer is returned.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool StdioStream::fopen (const char * path,
const char * mode 
)
+
+

Open a stream.

+

Open a file and associates the stream with it.

+
Parameters
+ + + +
[in]pathfile to be opened.
[in]modea string that indicates the open mode.
+
+
+ + + + + + + + + + + + + + + + + +
"r" or "rb" Open a file for reading. The file must exist.
"w" or "wb" Truncate an existing to zero length or create an empty file for writing.
"wx" or "wbx" Create a file for writing. Fails if the file already exists.
"a" or "ab" Append; open or create file for writing at end-of-file.
"r+" or "rb+" or "r+b" Open a file for update (reading and writing).
"w+" or "w+b" or "wb+" Truncate an existing to zero length or create a file for update.
"w+x" or "w+bx" or "wb+x" Create a file for update. Fails if the file already exists.
"a+" or "a+b" or "ab+" Append; open or create a file for update, writing at end-of-file.
+

The character 'b' shall have no effect, but is allowed for ISO C standard conformance.

+

Opening a file with append mode causes all subsequent writes to the file to be forced to the then current end-of-file, regardless of intervening calls to the fseek function.

+

When a file is opened with update mode, both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, or rewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.

+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int StdioStream::fputc (int c)
+
+inline
+
+

Write a byte to a stream.

+
Parameters
+ + +
[in]cthe byte to be written (converted to an unsigned char).
+
+
+
Returns
Upon successful completion, fputc() returns the value it has written. Otherwise, it returns EOF and sets the error indicator for the stream.
+ +
+
+ +
+
+ + + + + + + + +
int StdioStream::fputs (const char * str)
+
+

Write a string to a stream.

+
Parameters
+ + +
[in]stra pointer to the string to be written.
+
+
+
Returns
for success, fputs() returns a non-negative number. Otherwise, it returns EOF and sets the error indicator for the stream.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
size_t StdioStream::fread (void * ptr,
size_t size,
size_t count 
)
+
+

Binary input.

+

Reads an array of up to count elements, each one with a size of size bytes.

Parameters
+ + + + +
[out]ptrpointer to area of at least (size*count) bytes where the data will be stored.
[in]sizethe size, in bytes, of each element to be read.
[in]countthe number of elements to be read.
+
+
+
Returns
number of elements successfully read, which may be less than count if a read error or end-of-file is encountered. If size or count is zero, fread returns zero and the contents of the array and the state of the stream remain unchanged.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int StdioStream::fseek (int32_t offset,
int origin 
)
+
+

Set the file position for the stream.

+
Parameters
+ + + +
[in]offsetnumber of offset from the origin.
[in]originposition used as reference for the offset. It is specified by one of the following constants.
+
+
+

SEEK_SET - Beginning of file.

+

SEEK_CUR - Current position of the file pointer.

+

SEEK_END - End of file.

+
Returns
zero for success. Otherwise, it returns non-zero and sets the error indicator for the stream.
+ +
+
+ +
+
+ + + + + + + +
int32_t StdioStream::ftell ()
+
+

Get the current position in a stream.

+
Returns
If successful, ftell return the current value of the position indicator. On failure, ftell returns −1L.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
size_t StdioStream::fwrite (const void * ptr,
size_t size,
size_t count 
)
+
+

Binary output.

+

Writes an array of up to count elements, each one with a size of size bytes.

Parameters
+ + + + +
[in]ptrpointer to (size*count) bytes of data to be written.
[in]sizethe size, in bytes, of each element to be written.
[in]countthe number of elements to be written.
+
+
+
Returns
number of elements successfully written. if this number is less than count, an error has occurred. If size or count is zero, fwrite returns zero.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int StdioStream::getc ()
+
+inline
+
+

Get a byte from the stream.

+

getc and fgetc are equivalent but getc is in-line so it is faster but require more flash memory.

+
Returns
If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream is set and the fgetc function returns EOF. Otherwise, the fgetc function returns the next character from the input stream.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t StdioStream::print (char c)
+
+inline
+
+

Write a character.

Parameters
+ + +
[in]cthe character to write.
+
+
+
Returns
the number of bytes written.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t StdioStream::print (const char * str)
+
+inline
+
+

Write a string.

+
Parameters
+ + +
[in]strthe string to be written.
+
+
+
Returns
the number of bytes written.
+ +
+
+ +
+
+ + + + + + + + +
size_t StdioStream::print (const __FlashStringHelper * str)
+
+

Print a string stored in flash memory.

+
Parameters
+ + +
[in]strthe string to print.
+
+
+
Returns
the number of bytes written.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
size_t StdioStream::print (double val,
uint8_t prec = 2 
)
+
+inline
+
+

Print a floating point number.

+
Parameters
+ + + +
[in]precNumber of digits after decimal point.
[in]valthe number to be printed.
+
+
+
Returns
the number of bytes written.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
size_t StdioStream::print (float val,
uint8_t prec = 2 
)
+
+inline
+
+

Print a floating point number.

+
Parameters
+ + + +
[in]precNumber of digits after decimal point.
[in]valthe number to be printed.
+
+
+
Returns
the number of bytes written.
+ +
+
+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + + +
size_t StdioStream::print (val)
+
+inline
+
+

Print a number.

+
Parameters
+ + +
[in]valthe number to be printed.
+
+
+
Returns
the number of bytes written.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int StdioStream::printDec (char n)
+
+inline
+
+

Print a char as a number.

Parameters
+ + +
[in]nnumber to be printed.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + +
int StdioStream::printDec (signed char n)
+
+

print a signed 8-bit integer

Parameters
+ + +
[in]nnumber to be printed.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int StdioStream::printDec (unsigned char n)
+
+inline
+
+

Print an unsigned 8-bit number.

Parameters
+ + +
[in]nnumber to be print.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + +
int StdioStream::printDec (int16_t n)
+
+

Print a int16_t

Parameters
+ + +
[in]nnumber to be printed.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + +
int StdioStream::printDec (uint16_t n)
+
+

print a uint16_t.

Parameters
+ + +
[in]nnumber to be printed.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + +
int StdioStream::printDec (int32_t n)
+
+

Print a signed 32-bit integer.

Parameters
+ + +
[in]nnumber to be printed.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + +
int StdioStream::printDec (uint32_t n)
+
+

Write an unsigned 32-bit number.

Parameters
+ + +
[in]nnumber to be printed.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int StdioStream::printDec (double value,
uint8_t prec 
)
+
+inline
+
+

Print a double.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]precNumber of digits after decimal point.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int StdioStream::printDec (float value,
uint8_t prec 
)
+
+

Print a float.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]precNumber of digits after decimal point.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
int StdioStream::printField (double value,
char term,
uint8_t prec = 2 
)
+
+inline
+
+

Print a number followed by a field terminator.

Parameters
+ + + + +
[in]valueThe number to be printed.
[in]termThe field terminator.
[in]precNumber of digits after decimal point.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
int StdioStream::printField (float value,
char term,
uint8_t prec = 2 
)
+
+inline
+
+

Print a number followed by a field terminator.

Parameters
+ + + + +
[in]valueThe number to be printed.
[in]termThe field terminator.
[in]precNumber of digits after decimal point.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int StdioStream::printField (value,
char term 
)
+
+inline
+
+

Print a number followed by a field terminator.

Parameters
+ + + +
[in]valueThe number to be printed.
[in]termThe field terminator.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + + + + +
int StdioStream::printHex (uint32_t n)
+
+

Print HEX

Parameters
+ + +
[in]nnumber to be printed as HEX.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int StdioStream::printHexln (uint32_t n)
+
+inline
+
+

Print HEX with CRLF

Parameters
+ + +
[in]nnumber to be printed as HEX.
+
+
+
Returns
The number of bytes written or -1 if an error occurs.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t StdioStream::println ()
+
+inline
+
+

Write a CR/LF.

+
Returns
two, the number of bytes written, for success or zero for failure.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
size_t StdioStream::println (double val,
uint8_t prec = 2 
)
+
+inline
+
+

Print a floating point number followed by CR/LF.

+
Parameters
+ + + +
[in]valthe number to be printed.
[in]precNumber of digits after decimal point.
+
+
+
Returns
the number of bytes written.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
size_t StdioStream::println (float val,
uint8_t prec = 2 
)
+
+inline
+
+

Print a floating point number followed by CR/LF.

+
Parameters
+ + + +
[in]valthe number to be printed.
[in]precNumber of digits after decimal point.
+
+
+
Returns
the number of bytes written.
+ +
+
+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + + +
size_t StdioStream::println (val)
+
+inline
+
+

Print an item followed by CR/LF

+
Parameters
+ + +
[in]valthe item to be printed.
+
+
+
Returns
the number of bytes written.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int StdioStream::putc (int c)
+
+inline
+
+

Write a byte to a stream.

+

putc and fputc are equivalent but putc is in-line so it is faster but require more flash memory.

+
Parameters
+ + +
[in]cthe byte to be written (converted to an unsigned char).
+
+
+
Returns
Upon successful completion, fputc() returns the value it has written. Otherwise, it returns EOF and sets the error indicator for the stream.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int StdioStream::putCRLF ()
+
+inline
+
+

Write a CR/LF.

+
Returns
two, the number of bytes written, for success or -1 for failure.
+ +
+
+ +
+
+ + + + + + + +
bool StdioStream::rewind ()
+
+

Set position of a stream to the beginning.

+

The rewind function sets the file position to the beginning of the file. It is equivalent to fseek(0L, SEEK_SET) except that the error indicator for the stream is also cleared.

+
Returns
true for success or false for failure.
+ +
+
+ +
+
+ + + + + + + + +
int StdioStream::ungetc (int c)
+
+

Push a byte back into an input stream.

+
Parameters
+ + +
[in]cthe byte (converted to an unsigned char) to be pushed back.
+
+
+

One character of push-back is guaranteed. If the ungetc function is called too many times without an intervening read or file positioning operation on that stream, the operation may fail.

+

A successful intervening call to a file positioning function (fseek, fsetpos, or rewind) discards any pushed-back characters for the stream.

+
Returns
Upon successful completion, ungetc() returns the byte pushed back after conversion. Otherwise it returns EOF.
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • Arduino/libraries/SdFat/src/FatLib/StdioStream.h
  • +
  • Arduino/libraries/SdFat/src/FatLib/StdioStream.cpp
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/class_stdio_stream__coll__graph.png b/libraries/SdFat/extras/html/class_stdio_stream__coll__graph.png new file mode 100644 index 0000000..99344ab Binary files /dev/null and b/libraries/SdFat/extras/html/class_stdio_stream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/class_stdio_stream__inherit__graph.png b/libraries/SdFat/extras/html/class_stdio_stream__inherit__graph.png new file mode 100644 index 0000000..99344ab Binary files /dev/null and b/libraries/SdFat/extras/html/class_stdio_stream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/class_sys_call-members.html b/libraries/SdFat/extras/html/class_sys_call-members.html new file mode 100644 index 0000000..d2dd879 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sys_call-members.html @@ -0,0 +1,101 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
SysCall Member List
+
+
+ +

This is the complete list of members for SysCall, including all inherited members.

+ + + +
halt()SysCallinlinestatic
yield()SysCallinlinestatic
+ + + + diff --git a/libraries/SdFat/extras/html/class_sys_call.html b/libraries/SdFat/extras/html/class_sys_call.html new file mode 100644 index 0000000..d67ddb7 --- /dev/null +++ b/libraries/SdFat/extras/html/class_sys_call.html @@ -0,0 +1,166 @@ + + + + + + +SdFat: SysCall Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
SysCall Class Reference
+
+
+ +

SysCall - Class to wrap system calls. + More...

+ +

#include <SysCall.h>

+ + + + + + +

+Static Public Member Functions

static void halt ()
 
static void yield ()
 
+

Detailed Description

+

SysCall - Class to wrap system calls.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
static void SysCall::halt ()
+
+inlinestatic
+
+

Halt execution of this thread.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SysCall::yield ()
+
+inlinestatic
+
+

Yield to other threads.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/classes.html b/libraries/SdFat/extras/html/classes.html new file mode 100644 index 0000000..eb1727f --- /dev/null +++ b/libraries/SdFat/extras/html/classes.html @@ -0,0 +1,134 @@ + + + + + + +SdFat: Class Index + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Index
+
+
+
A | B | C | D | F | I | L | M | O | P | S
+ + + + + + + + + + + + + + + + + + + +
  A  
+
File   SdFatSoftSpiEX   
  f  
+
  l  
+
  M  
+
SdFile   
ArduinoInStream   SdFileSystem   fat32_boot   longDirectoryEntry   
ArduinoOutStream   MinimumSerial   SdioCard   fat32_fsinfo   
  m  
+
  B  
+
  P  
+
SdSpiCard   fat_boot   
SdSpiCardEX   fname_t   masterBootRecord   
BaseBlockDriver   PrintFile   StdioStream   fstream   
  o  
+
  F  
+
  S  
+
SysCall   
  i  
+
  b  
+
obufstream   
FatCache   Sd2Card   ibufstream   ofstream   
FatFile   SdBaseFile   biosParmBlock   ifstream   ostream   
FatFileSystem   SdFat   
  c  
+
ios   
  p  
+
FatPos_t   SdFatEX   ios_base   
FatStreamBase   SdFatSdio   cache_t   iostream   partitionTable   
FatVolume   SdFatSoftSpi   
  d  
+
istream   
  s  
+
directoryEntry   setfill   
+
A | B | C | D | F | I | L | M | O | P | S
+
+ + + + diff --git a/libraries/SdFat/extras/html/classfstream-members.html b/libraries/SdFat/extras/html/classfstream-members.html new file mode 100644 index 0000000..1b2d805 --- /dev/null +++ b/libraries/SdFat/extras/html/classfstream-members.html @@ -0,0 +1,220 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
fstream Member List
+
+
+ +

This is the complete list of members for fstream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)fstreaminline
close()fstreaminline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
flush()ostreaminline
fmtflags typedefios_base
fstream() (defined in fstream)fstreaminline
fstream(const char *path, openmode mode=in|out)fstreaminlineexplicit
gcount() const istreaminline
get()istream
get(char &ch)istream
get(char *str, streamsize n, char delim= '\n')istream
getline(char *str, streamsize n, char delim= '\n')istream
good() const iosinline
goodbitios_basestatic
hexios_basestatic
ignore(streamsize n=1, int delim=-1)istream
inios_basestatic
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
is_open()fstreaminline
istream() (defined in istream)istreaminline
leftios_basestatic
octios_basestatic
off_type typedefios_base
open(const char *path, openmode mode=in|out)fstreaminline
FatStreamBase::open(FatFileSystem *fs, const char *path, uint8_t oflag)FatFileprivate
FatStreamBase::open(FatFile *dirFile, uint16_t index, uint8_t oflag)FatFileprivate
FatStreamBase::open(FatFile *dirFile, const char *path, uint8_t oflag)FatFileprivate
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
operator<<(ostream &(*pf)(ostream &str))ostreaminline
operator<<(ios_base &(*pf)(ios_base &str))ostreaminline
operator<<(bool arg)ostreaminline
operator<<(const char *arg)ostreaminline
operator<<(const signed char *arg)ostreaminline
operator<<(const unsigned char *arg)ostreaminline
operator<<(char arg)ostreaminline
operator<<(signed char arg)ostreaminline
operator<<(unsigned char arg)ostreaminline
operator<<(double arg)ostreaminline
operator<<(float arg)ostreaminline
operator<<(short arg)ostreaminline
operator<<(unsigned short arg)ostreaminline
operator<<(int arg)ostreaminline
operator<<(unsigned int arg)ostreaminline
operator<<(long arg)ostreaminline
operator<<(unsigned long arg)ostreaminline
operator<<(const void *arg)ostreaminline
operator<<(const __FlashStringHelper *arg)ostreaminline
operator>>(istream &(*pf)(istream &str))istreaminline
operator>>(ios_base &(*pf)(ios_base &str))istreaminline
operator>>(ios &(*pf)(ios &str))istreaminline
operator>>(char *str)istreaminline
operator>>(char &ch)istreaminline
operator>>(signed char *str)istreaminline
operator>>(signed char &ch)istreaminline
operator>>(unsigned char *str)istreaminline
operator>>(unsigned char &ch)istreaminline
operator>>(bool &arg)istreaminline
operator>>(short &arg)istreaminline
operator>>(unsigned short &arg)istreaminline
operator>>(int &arg)istreaminline
operator>>(unsigned int &arg)istreaminline
operator>>(long &arg)istreaminline
operator>>(unsigned long &arg)istreaminline
operator>>(double &arg)istreaminline
operator>>(float &arg)istreaminline
operator>>(void *&arg)istreaminline
ostream() (defined in ostream)ostreaminline
outios_basestatic
iostream::peek()istream
FatStreamBase::peek()FatFileprivate
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
put(char ch)ostreaminline
rdstate() const iosinline
rightios_basestatic
seekdir enum nameios_base
seekg(pos_type pos)istreaminline
seekg(off_type off, seekdir way)istreaminline
seekp(pos_type pos)ostreaminline
seekp(off_type off, seekdir way)ostreaminline
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipWhite()istream
skipwsios_basestatic
streamsize typedefios_base
tellg()istreaminline
tellp()ostreaminline
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/classfstream.html b/libraries/SdFat/extras/html/classfstream.html new file mode 100644 index 0000000..324b92e --- /dev/null +++ b/libraries/SdFat/extras/html/classfstream.html @@ -0,0 +1,3451 @@ + + + + + + +SdFat: fstream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

file input/output stream. + More...

+ +

#include <fstream.h>

+
+Inheritance diagram for fstream:
+
+
Inheritance graph
+ + + + + + + + + +
[legend]
+
+Collaboration diagram for fstream:
+
+
Collaboration graph
+ + + + + + + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool bad () const
 
void clear (iostate state=goodbit)
 
void close ()
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
ostreamflush ()
 
 fstream (const char *path, openmode mode=in|out)
 
streamsize gcount () const
 
int get ()
 
istreamget (char &ch)
 
istreamget (char *str, streamsize n, char delim= '\n')
 
istreamgetline (char *str, streamsize n, char delim= '\n')
 
bool good () const
 
istreamignore (streamsize n=1, int delim=-1)
 
bool is_open ()
 
void open (const char *path, openmode mode=in|out)
 
 operator const void * () const
 
bool operator! () const
 
ostreamoperator<< (ostream &(*pf)(ostream &str))
 
ostreamoperator<< (ios_base &(*pf)(ios_base &str))
 
ostreamoperator<< (bool arg)
 
ostreamoperator<< (const char *arg)
 
ostreamoperator<< (const signed char *arg)
 
ostreamoperator<< (const unsigned char *arg)
 
ostreamoperator<< (char arg)
 
ostreamoperator<< (signed char arg)
 
ostreamoperator<< (unsigned char arg)
 
ostreamoperator<< (double arg)
 
ostreamoperator<< (float arg)
 
ostreamoperator<< (short arg)
 
ostreamoperator<< (unsigned short arg)
 
ostreamoperator<< (int arg)
 
ostreamoperator<< (unsigned int arg)
 
ostreamoperator<< (long arg)
 
ostreamoperator<< (unsigned long arg)
 
ostreamoperator<< (const void *arg)
 
ostreamoperator<< (const __FlashStringHelper *arg)
 
istreamoperator>> (istream &(*pf)(istream &str))
 
istreamoperator>> (ios_base &(*pf)(ios_base &str))
 
istreamoperator>> (ios &(*pf)(ios &str))
 
istreamoperator>> (char *str)
 
istreamoperator>> (char &ch)
 
istreamoperator>> (signed char *str)
 
istreamoperator>> (signed char &ch)
 
istreamoperator>> (unsigned char *str)
 
istreamoperator>> (unsigned char &ch)
 
istreamoperator>> (bool &arg)
 
istreamoperator>> (short &arg)
 
istreamoperator>> (unsigned short &arg)
 
istreamoperator>> (int &arg)
 
istreamoperator>> (unsigned int &arg)
 
istreamoperator>> (long &arg)
 
istreamoperator>> (unsigned long &arg)
 
istreamoperator>> (double &arg)
 
istreamoperator>> (float &arg)
 
istreamoperator>> (void *&arg)
 
int peek ()
 
int precision () const
 
int precision (unsigned int n)
 
ostreamput (char ch)
 
iostate rdstate () const
 
istreamseekg (pos_type pos)
 
istreamseekg (off_type off, seekdir way)
 
ostreamseekp (pos_type pos)
 
ostreamseekp (off_type off, seekdir way)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
void skipWhite ()
 
pos_type tellg ()
 
pos_type tellp ()
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+ + + + + + + + + +

+Private Member Functions

bool open (FatFileSystem *fs, const char *path, uint8_t oflag)
 
bool open (FatFile *dirFile, uint16_t index, uint8_t oflag)
 
bool open (FatFile *dirFile, const char *path, uint8_t oflag)
 
int peek ()
 
+

Detailed Description

+

file input/output stream.

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fstream::fstream (const char * path,
openmode mode = in | out 
)
+
+inlineexplicit
+
+

Constructor with open

+
Parameters
+ + + +
[in]pathpath to open
[in]modeopen mode
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void fstream::clear (iostate state = goodbit)
+
+inline
+
+

Clear state and writeError

Parameters
+ + +
[in]statenew state for stream
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void fstream::close ()
+
+inline
+
+

Close a file and force cached data and directory information to be written to the storage device.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ostream& ostream::flush ()
+
+inlineinherited
+
+

Flushes the buffer associated with this stream. The flush function calls the sync function of the associated file.

Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
streamsize istream::gcount () const
+
+inlineinherited
+
+
Returns
The number of characters extracted by the last unformatted input function.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int istream::get ()
+
+inherited
+
+

Extract a character if one is available.

+
Returns
The character or -1 if a failure occurs. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream & istream::get (char & ch)
+
+inherited
+
+

Extract a character if one is available.

+
Parameters
+ + +
[out]chlocation to receive the extracted character.
+
+
+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::get (char * str,
streamsize n,
char delim = '\n' 
)
+
+inherited
+
+

Extract characters.

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, n is less than 1, n-1 characters are extracted, or the next character equals delim (delim is not extracted). If no characters are extracted failbit is set. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::getline (char * str,
streamsize n,
char delim = '\n' 
)
+
+inherited
+
+

Extract characters

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, the next character equals delim (delim is extracted), or n-1 characters are extracted.

+

The failbit is set if no characters are extracted or n-1 characters are extracted. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream & istream::ignore (streamsize n = 1,
int delim = -1 
)
+
+inherited
+
+

Extract characters and discard them.

+
Parameters
+ + + +
[in]nmaximum number of characters to ignore.
[in]delimDelimiter.
+
+
+

Characters are extracted until extraction fails, n characters are extracted, or the next input character equals delim (the delimiter is extracted). If end-of-file occurs the eofbit is set.

+

Failures are indicated by the state of the stream.

+
Returns
*this
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool fstream::is_open ()
+
+inline
+
+
Returns
True if stream is open else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void fstream::open (const char * path,
openmode mode = in | out 
)
+
+inline
+
+

Open a fstream

Parameters
+ + + +
[in]pathfile to open
[in]modeopen mode
+
+
+

Valid open modes are (at end, ios::ate, and/or ios::binary may be added):

+

ios::in - Open file for reading.

+

ios::out or ios::out | ios::trunc - Truncate to 0 length, if existent, or create a file for writing only.

+

ios::app or ios::out | ios::app - Append; open or create file for writing at end-of-file.

+

ios::in | ios::out - Open file for update (reading and writing).

+

ios::in | ios::out | ios::trunc - Truncate to zero length, if existent, or create file for update.

+

ios::in | ios::app or ios::in | ios::out | ios::app - Append; open or create text file for update, writing at end of file.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ostream &(*)(ostream &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ios_base &(*)(ios_base &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (bool arg)
+
+inlineinherited
+
+

Output bool

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const signed char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const unsigned char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (signed char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (double arg)
+
+inlineinherited
+
+

Output double

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (float arg)
+
+inlineinherited
+
+

Output float

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (short arg)
+
+inlineinherited
+
+

Output signed short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned short arg)
+
+inlineinherited
+
+

Output unsigned short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (int arg)
+
+inlineinherited
+
+

Output signed int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned int arg)
+
+inlineinherited
+
+

Output unsigned int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (long arg)
+
+inlineinherited
+
+

Output signed long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned long arg)
+
+inlineinherited
+
+

Output unsigned long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const void * arg)
+
+inlineinherited
+
+

Output pointer

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const __FlashStringHelper * arg)
+
+inlineinherited
+
+

Output a string from flash using the Arduino F() macro.

Parameters
+ + +
[in]argpointing to flash string
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (istream &(*)(istream &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios_base &(*)(ios_base &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios &(*)(ios &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (bool & arg)
+
+inlineinherited
+
+

Extract a value of type bool.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (short & arg)
+
+inlineinherited
+
+

Extract a value of type short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned short & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (int & arg)
+
+inlineinherited
+
+

Extract a value of type int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned int & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (long & arg)
+
+inlineinherited
+
+

Extract a value of type long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned long & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (double & arg)
+
+inlineinherited
+
+

Extract a value of type double.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (float & arg)
+
+inlineinherited
+
+

Extract a value of type float.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (void *& arg)
+
+inlineinherited
+
+

Extract a value of type void*.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int istream::peek ()
+
+inherited
+
+

Return the next available character without consuming it.

+
Returns
The character if the stream state is good else -1;
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::put (char ch)
+
+inlineinherited
+
+

Puts a character in a stream.

+

The unformatted output function inserts the element ch. It returns *this.

+
Parameters
+ + +
[in]chThe character
+
+
+
Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::seekg (pos_type pos)
+
+inlineinherited
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the read pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream& istream::seekg (off_type off,
seekdir way 
)
+
+inlineinherited
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the read pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::seekp (pos_type pos)
+
+inlineinherited
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the write pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ostream& ostream::seekp (off_type off,
seekdir way 
)
+
+inlineinherited
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the write pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void istream::skipWhite ()
+
+inherited
+
+

used to implement ws()

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type istream::tellg ()
+
+inlineinherited
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type ostream::tellp ()
+
+inlineinherited
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/FatLib/fstream.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/classfstream__coll__graph.png b/libraries/SdFat/extras/html/classfstream__coll__graph.png new file mode 100644 index 0000000..94fffce Binary files /dev/null and b/libraries/SdFat/extras/html/classfstream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/classfstream__inherit__graph.png b/libraries/SdFat/extras/html/classfstream__inherit__graph.png new file mode 100644 index 0000000..94fffce Binary files /dev/null and b/libraries/SdFat/extras/html/classfstream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/classibufstream-members.html b/libraries/SdFat/extras/html/classibufstream-members.html new file mode 100644 index 0000000..0ef4df5 --- /dev/null +++ b/libraries/SdFat/extras/html/classibufstream-members.html @@ -0,0 +1,189 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
ibufstream Member List
+
+
+ +

This is the complete list of members for ibufstream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)iosinline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
fmtflags typedefios_base
gcount() const istreaminline
get()istream
get(char &ch)istream
get(char *str, streamsize n, char delim= '\n')istream
getline(char *str, streamsize n, char delim= '\n')istream
good() const iosinline
goodbitios_basestatic
hexios_basestatic
ibufstream()ibufstreaminline
ibufstream(const char *str)ibufstreaminlineexplicit
ignore(streamsize n=1, int delim=-1)istream
inios_basestatic
init(const char *str)ibufstreaminline
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
istream() (defined in istream)istreaminline
leftios_basestatic
octios_basestatic
off_type typedefios_base
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
operator>>(istream &(*pf)(istream &str))istreaminline
operator>>(ios_base &(*pf)(ios_base &str))istreaminline
operator>>(ios &(*pf)(ios &str))istreaminline
operator>>(char *str)istreaminline
operator>>(char &ch)istreaminline
operator>>(signed char *str)istreaminline
operator>>(signed char &ch)istreaminline
operator>>(unsigned char *str)istreaminline
operator>>(unsigned char &ch)istreaminline
operator>>(bool &arg)istreaminline
operator>>(short &arg)istreaminline
operator>>(unsigned short &arg)istreaminline
operator>>(int &arg)istreaminline
operator>>(unsigned int &arg)istreaminline
operator>>(long &arg)istreaminline
operator>>(unsigned long &arg)istreaminline
operator>>(double &arg)istreaminline
operator>>(float &arg)istreaminline
operator>>(void *&arg)istreaminline
outios_basestatic
peek()istream
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
rdstate() const iosinline
rightios_basestatic
seekdir enum nameios_base
seekg(pos_type pos)istreaminline
seekg(off_type off, seekdir way)istreaminline
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipWhite()istream
skipwsios_basestatic
streamsize typedefios_base
tellg()istreaminline
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/classibufstream.html b/libraries/SdFat/extras/html/classibufstream.html new file mode 100644 index 0000000..2e484b4 --- /dev/null +++ b/libraries/SdFat/extras/html/classibufstream.html @@ -0,0 +1,2585 @@ + + + + + + +SdFat: ibufstream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

parse a char string + More...

+ +

#include <bufstream.h>

+
+Inheritance diagram for ibufstream:
+
+
Inheritance graph
+ + + + + + +
[legend]
+
+Collaboration diagram for ibufstream:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool bad () const
 
void clear (iostate state=goodbit)
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
streamsize gcount () const
 
int get ()
 
istreamget (char &ch)
 
istreamget (char *str, streamsize n, char delim= '\n')
 
istreamgetline (char *str, streamsize n, char delim= '\n')
 
bool good () const
 
 ibufstream ()
 
 ibufstream (const char *str)
 
istreamignore (streamsize n=1, int delim=-1)
 
void init (const char *str)
 
 operator const void * () const
 
bool operator! () const
 
istreamoperator>> (istream &(*pf)(istream &str))
 
istreamoperator>> (ios_base &(*pf)(ios_base &str))
 
istreamoperator>> (ios &(*pf)(ios &str))
 
istreamoperator>> (char *str)
 
istreamoperator>> (char &ch)
 
istreamoperator>> (signed char *str)
 
istreamoperator>> (signed char &ch)
 
istreamoperator>> (unsigned char *str)
 
istreamoperator>> (unsigned char &ch)
 
istreamoperator>> (bool &arg)
 
istreamoperator>> (short &arg)
 
istreamoperator>> (unsigned short &arg)
 
istreamoperator>> (int &arg)
 
istreamoperator>> (unsigned int &arg)
 
istreamoperator>> (long &arg)
 
istreamoperator>> (unsigned long &arg)
 
istreamoperator>> (double &arg)
 
istreamoperator>> (float &arg)
 
istreamoperator>> (void *&arg)
 
int peek ()
 
int precision () const
 
int precision (unsigned int n)
 
iostate rdstate () const
 
istreamseekg (pos_type pos)
 
istreamseekg (off_type off, seekdir way)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
void skipWhite ()
 
pos_type tellg ()
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+

Detailed Description

+

parse a char string

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
ibufstream::ibufstream ()
+
+inline
+
+

Constructor

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ibufstream::ibufstream (const char * str)
+
+inlineexplicit
+
+

Constructor

Parameters
+ + +
[in]strpointer to string to be parsed Warning: The string will not be copied so must stay in scope.
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::clear (iostate state = goodbit)
+
+inlineinherited
+
+

Clear iostate bits.

+
Parameters
+ + +
[in]stateThe flags you want to set after clearing all flags.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
streamsize istream::gcount () const
+
+inlineinherited
+
+
Returns
The number of characters extracted by the last unformatted input function.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int istream::get ()
+
+inherited
+
+

Extract a character if one is available.

+
Returns
The character or -1 if a failure occurs. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream & istream::get (char & ch)
+
+inherited
+
+

Extract a character if one is available.

+
Parameters
+ + +
[out]chlocation to receive the extracted character.
+
+
+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::get (char * str,
streamsize n,
char delim = '\n' 
)
+
+inherited
+
+

Extract characters.

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, n is less than 1, n-1 characters are extracted, or the next character equals delim (delim is not extracted). If no characters are extracted failbit is set. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::getline (char * str,
streamsize n,
char delim = '\n' 
)
+
+inherited
+
+

Extract characters

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, the next character equals delim (delim is extracted), or n-1 characters are extracted.

+

The failbit is set if no characters are extracted or n-1 characters are extracted. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream & istream::ignore (streamsize n = 1,
int delim = -1 
)
+
+inherited
+
+

Extract characters and discard them.

+
Parameters
+ + + +
[in]nmaximum number of characters to ignore.
[in]delimDelimiter.
+
+
+

Characters are extracted until extraction fails, n characters are extracted, or the next input character equals delim (the delimiter is extracted). If end-of-file occurs the eofbit is set.

+

Failures are indicated by the state of the stream.

+
Returns
*this
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ibufstream::init (const char * str)
+
+inline
+
+

Initialize an ibufstream

Parameters
+ + +
[in]strpointer to string to be parsed Warning: The string will not be copied so must stay in scope.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (istream &(*)(istream &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios_base &(*)(ios_base &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios &(*)(ios &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (bool & arg)
+
+inlineinherited
+
+

Extract a value of type bool.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (short & arg)
+
+inlineinherited
+
+

Extract a value of type short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned short & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (int & arg)
+
+inlineinherited
+
+

Extract a value of type int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned int & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (long & arg)
+
+inlineinherited
+
+

Extract a value of type long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned long & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (double & arg)
+
+inlineinherited
+
+

Extract a value of type double.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (float & arg)
+
+inlineinherited
+
+

Extract a value of type float.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (void *& arg)
+
+inlineinherited
+
+

Extract a value of type void*.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int istream::peek ()
+
+inherited
+
+

Return the next available character without consuming it.

+
Returns
The character if the stream state is good else -1;
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::seekg (pos_type pos)
+
+inlineinherited
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the read pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream& istream::seekg (off_type off,
seekdir way 
)
+
+inlineinherited
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the read pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void istream::skipWhite ()
+
+inherited
+
+

used to implement ws()

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type istream::tellg ()
+
+inlineinherited
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/classibufstream__coll__graph.png b/libraries/SdFat/extras/html/classibufstream__coll__graph.png new file mode 100644 index 0000000..d91bbc7 Binary files /dev/null and b/libraries/SdFat/extras/html/classibufstream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/classibufstream__inherit__graph.png b/libraries/SdFat/extras/html/classibufstream__inherit__graph.png new file mode 100644 index 0000000..0b88104 Binary files /dev/null and b/libraries/SdFat/extras/html/classibufstream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/classifstream-members.html b/libraries/SdFat/extras/html/classifstream-members.html new file mode 100644 index 0000000..944d789 --- /dev/null +++ b/libraries/SdFat/extras/html/classifstream-members.html @@ -0,0 +1,195 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
ifstream Member List
+
+
+ +

This is the complete list of members for ifstream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)iosinline
close()ifstreaminline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
fmtflags typedefios_base
gcount() const istreaminline
get()istream
get(char &ch)istream
get(char *str, streamsize n, char delim= '\n')istream
getline(char *str, streamsize n, char delim= '\n')istream
good() const iosinline
goodbitios_basestatic
hexios_basestatic
ifstream() (defined in ifstream)ifstreaminline
ifstream(const char *path, openmode mode=in)ifstreaminlineexplicit
ignore(streamsize n=1, int delim=-1)istream
inios_basestatic
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
is_open()ifstreaminline
istream() (defined in istream)istreaminline
leftios_basestatic
octios_basestatic
off_type typedefios_base
open(const char *path, openmode mode=in)ifstreaminline
FatStreamBase::open(FatFileSystem *fs, const char *path, uint8_t oflag)FatFileprivate
FatStreamBase::open(FatFile *dirFile, uint16_t index, uint8_t oflag)FatFileprivate
FatStreamBase::open(FatFile *dirFile, const char *path, uint8_t oflag)FatFileprivate
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
operator>>(istream &(*pf)(istream &str))istreaminline
operator>>(ios_base &(*pf)(ios_base &str))istreaminline
operator>>(ios &(*pf)(ios &str))istreaminline
operator>>(char *str)istreaminline
operator>>(char &ch)istreaminline
operator>>(signed char *str)istreaminline
operator>>(signed char &ch)istreaminline
operator>>(unsigned char *str)istreaminline
operator>>(unsigned char &ch)istreaminline
operator>>(bool &arg)istreaminline
operator>>(short &arg)istreaminline
operator>>(unsigned short &arg)istreaminline
operator>>(int &arg)istreaminline
operator>>(unsigned int &arg)istreaminline
operator>>(long &arg)istreaminline
operator>>(unsigned long &arg)istreaminline
operator>>(double &arg)istreaminline
operator>>(float &arg)istreaminline
operator>>(void *&arg)istreaminline
outios_basestatic
istream::peek()istream
FatStreamBase::peek()FatFileprivate
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
rdstate() const iosinline
rightios_basestatic
seekdir enum nameios_base
seekg(pos_type pos)istreaminline
seekg(off_type off, seekdir way)istreaminline
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipWhite()istream
skipwsios_basestatic
streamsize typedefios_base
tellg()istreaminline
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/classifstream.html b/libraries/SdFat/extras/html/classifstream.html new file mode 100644 index 0000000..6df95f3 --- /dev/null +++ b/libraries/SdFat/extras/html/classifstream.html @@ -0,0 +1,2649 @@ + + + + + + +SdFat: ifstream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

file input stream. + More...

+ +

#include <fstream.h>

+
+Inheritance diagram for ifstream:
+
+
Inheritance graph
+ + + + + + + +
[legend]
+
+Collaboration diagram for ifstream:
+
+
Collaboration graph
+ + + + + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool bad () const
 
void clear (iostate state=goodbit)
 
void close ()
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
streamsize gcount () const
 
int get ()
 
istreamget (char &ch)
 
istreamget (char *str, streamsize n, char delim= '\n')
 
istreamgetline (char *str, streamsize n, char delim= '\n')
 
bool good () const
 
 ifstream (const char *path, openmode mode=in)
 
istreamignore (streamsize n=1, int delim=-1)
 
bool is_open ()
 
void open (const char *path, openmode mode=in)
 
 operator const void * () const
 
bool operator! () const
 
istreamoperator>> (istream &(*pf)(istream &str))
 
istreamoperator>> (ios_base &(*pf)(ios_base &str))
 
istreamoperator>> (ios &(*pf)(ios &str))
 
istreamoperator>> (char *str)
 
istreamoperator>> (char &ch)
 
istreamoperator>> (signed char *str)
 
istreamoperator>> (signed char &ch)
 
istreamoperator>> (unsigned char *str)
 
istreamoperator>> (unsigned char &ch)
 
istreamoperator>> (bool &arg)
 
istreamoperator>> (short &arg)
 
istreamoperator>> (unsigned short &arg)
 
istreamoperator>> (int &arg)
 
istreamoperator>> (unsigned int &arg)
 
istreamoperator>> (long &arg)
 
istreamoperator>> (unsigned long &arg)
 
istreamoperator>> (double &arg)
 
istreamoperator>> (float &arg)
 
istreamoperator>> (void *&arg)
 
int peek ()
 
int precision () const
 
int precision (unsigned int n)
 
iostate rdstate () const
 
istreamseekg (pos_type pos)
 
istreamseekg (off_type off, seekdir way)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
void skipWhite ()
 
pos_type tellg ()
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+ + + + + + + + + +

+Private Member Functions

bool open (FatFileSystem *fs, const char *path, uint8_t oflag)
 
bool open (FatFile *dirFile, uint16_t index, uint8_t oflag)
 
bool open (FatFile *dirFile, const char *path, uint8_t oflag)
 
int peek ()
 
+

Detailed Description

+

file input stream.

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ifstream::ifstream (const char * path,
openmode mode = in 
)
+
+inlineexplicit
+
+

Constructor with open

Parameters
+ + + +
[in]pathfile to open
[in]modeopen mode
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::clear (iostate state = goodbit)
+
+inlineinherited
+
+

Clear iostate bits.

+
Parameters
+ + +
[in]stateThe flags you want to set after clearing all flags.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void ifstream::close ()
+
+inline
+
+

Close a file and force cached data and directory information to be written to the storage device.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
streamsize istream::gcount () const
+
+inlineinherited
+
+
Returns
The number of characters extracted by the last unformatted input function.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int istream::get ()
+
+inherited
+
+

Extract a character if one is available.

+
Returns
The character or -1 if a failure occurs. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream & istream::get (char & ch)
+
+inherited
+
+

Extract a character if one is available.

+
Parameters
+ + +
[out]chlocation to receive the extracted character.
+
+
+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::get (char * str,
streamsize n,
char delim = '\n' 
)
+
+inherited
+
+

Extract characters.

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, n is less than 1, n-1 characters are extracted, or the next character equals delim (delim is not extracted). If no characters are extracted failbit is set. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::getline (char * str,
streamsize n,
char delim = '\n' 
)
+
+inherited
+
+

Extract characters

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, the next character equals delim (delim is extracted), or n-1 characters are extracted.

+

The failbit is set if no characters are extracted or n-1 characters are extracted. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream & istream::ignore (streamsize n = 1,
int delim = -1 
)
+
+inherited
+
+

Extract characters and discard them.

+
Parameters
+ + + +
[in]nmaximum number of characters to ignore.
[in]delimDelimiter.
+
+
+

Characters are extracted until extraction fails, n characters are extracted, or the next input character equals delim (the delimiter is extracted). If end-of-file occurs the eofbit is set.

+

Failures are indicated by the state of the stream.

+
Returns
*this
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ifstream::is_open ()
+
+inline
+
+
Returns
True if stream is open else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void ifstream::open (const char * path,
openmode mode = in 
)
+
+inline
+
+

Open an ifstream

Parameters
+ + + +
[in]pathfile to open
[in]modeopen mode
+
+
+

mode See fstream::open() for valid modes.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (istream &(*)(istream &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios_base &(*)(ios_base &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios &(*)(ios &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (bool & arg)
+
+inlineinherited
+
+

Extract a value of type bool.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (short & arg)
+
+inlineinherited
+
+

Extract a value of type short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned short & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (int & arg)
+
+inlineinherited
+
+

Extract a value of type int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned int & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (long & arg)
+
+inlineinherited
+
+

Extract a value of type long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned long & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (double & arg)
+
+inlineinherited
+
+

Extract a value of type double.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (float & arg)
+
+inlineinherited
+
+

Extract a value of type float.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (void *& arg)
+
+inlineinherited
+
+

Extract a value of type void*.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int istream::peek ()
+
+inherited
+
+

Return the next available character without consuming it.

+
Returns
The character if the stream state is good else -1;
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::seekg (pos_type pos)
+
+inlineinherited
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the read pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream& istream::seekg (off_type off,
seekdir way 
)
+
+inlineinherited
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the read pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void istream::skipWhite ()
+
+inherited
+
+

used to implement ws()

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type istream::tellg ()
+
+inlineinherited
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/FatLib/fstream.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/classifstream__coll__graph.png b/libraries/SdFat/extras/html/classifstream__coll__graph.png new file mode 100644 index 0000000..6a2a32d Binary files /dev/null and b/libraries/SdFat/extras/html/classifstream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/classifstream__inherit__graph.png b/libraries/SdFat/extras/html/classifstream__inherit__graph.png new file mode 100644 index 0000000..6a2a32d Binary files /dev/null and b/libraries/SdFat/extras/html/classifstream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/classios-members.html b/libraries/SdFat/extras/html/classios-members.html new file mode 100644 index 0000000..8d4dbce --- /dev/null +++ b/libraries/SdFat/extras/html/classios-members.html @@ -0,0 +1,155 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
ios Member List
+
+
+ +

This is the complete list of members for ios, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)iosinline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
fmtflags typedefios_base
good() const iosinline
goodbitios_basestatic
hexios_basestatic
inios_basestatic
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
leftios_basestatic
octios_basestatic
off_type typedefios_base
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
outios_basestatic
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
rdstate() const iosinline
rightios_basestatic
seekdir enum nameios_base
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipwsios_basestatic
streamsize typedefios_base
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/classios.html b/libraries/SdFat/extras/html/classios.html new file mode 100644 index 0000000..f076a24 --- /dev/null +++ b/libraries/SdFat/extras/html/classios.html @@ -0,0 +1,1502 @@ + + + + + + +SdFat: ios Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Error and state information for all streams. + More...

+ +

#include <ios.h>

+
+Inheritance diagram for ios:
+
+
Inheritance graph
+ + + + + + + + + + + + + + +
[legend]
+
+Collaboration diagram for ios:
+
+
Collaboration graph
+ + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool bad () const
 
void clear (iostate state=goodbit)
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
bool good () const
 
 ios ()
 
 operator const void * () const
 
bool operator! () const
 
int precision () const
 
int precision (unsigned int n)
 
iostate rdstate () const
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+

Detailed Description

+

Error and state information for all streams.

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
ios::ios ()
+
+inline
+
+

Create ios with no error flags set

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inline
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::clear (iostate state = goodbit)
+
+inline
+
+

Clear iostate bits.

+
Parameters
+ + +
[in]stateThe flags you want to set after clearing all flags.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inline
+
+
Returns
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 ios::fail () const
+
+inline
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inline
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inline
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inline
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inline
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inline
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/FatLib/ios.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/classios__base-members.html b/libraries/SdFat/extras/html/classios__base-members.html new file mode 100644 index 0000000..ec1a743 --- /dev/null +++ b/libraries/SdFat/extras/html/classios__base-members.html @@ -0,0 +1,145 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
ios_base Member List
+
+
+ +

This is the complete list of members for ios_base, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
cur enum valueios_base
decios_basestatic
end enum valueios_base
eofbitios_basestatic
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
fmtflags typedefios_base
goodbitios_basestatic
hexios_basestatic
inios_basestatic
internalios_basestatic
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
leftios_basestatic
octios_basestatic
off_type typedefios_base
openmode typedefios_base
outios_basestatic
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
rightios_basestatic
seekdir enum nameios_base
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipwsios_basestatic
streamsize typedefios_base
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/classios__base.html b/libraries/SdFat/extras/html/classios__base.html new file mode 100644 index 0000000..f3d3af7 --- /dev/null +++ b/libraries/SdFat/extras/html/classios__base.html @@ -0,0 +1,1161 @@ + + + + + + +SdFat: ios_base Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Base class for all streams. + More...

+ +

#include <ios.h>

+
+Inheritance diagram for ios_base:
+
+
Inheritance graph
+ + + + + + + + + + + + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
int precision () const
 
int precision (unsigned int n)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+

Detailed Description

+

Base class for all streams.

+

Member Typedef Documentation

+ +
+
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+

type for format flags

+ +
+
+ +
+
+ + + + +
typedef unsigned char ios_base::iostate
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + +
typedef int32_t ios_base::off_type
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + +
typedef uint8_t ios_base::openmode
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + +
typedef uint32_t ios_base::pos_type
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + +
typedef uint32_t ios_base::streamsize
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum ios_base::seekdir
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inline
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inline
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inline
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inline
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inline
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inline
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inline
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inline
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inline
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inline
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inline
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+static
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+static
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+static
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+static
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+static
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+static
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+static
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+static
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+static
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+static
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+static
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+static
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+static
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+static
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+static
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+static
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+static
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+static
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+static
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+static
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+static
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+static
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+static
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+static
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/FatLib/ios.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/classios__base__inherit__graph.png b/libraries/SdFat/extras/html/classios__base__inherit__graph.png new file mode 100644 index 0000000..a6d2cfc Binary files /dev/null and b/libraries/SdFat/extras/html/classios__base__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/classios__coll__graph.png b/libraries/SdFat/extras/html/classios__coll__graph.png new file mode 100644 index 0000000..d817f0a Binary files /dev/null and b/libraries/SdFat/extras/html/classios__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/classios__inherit__graph.png b/libraries/SdFat/extras/html/classios__inherit__graph.png new file mode 100644 index 0000000..ffb918c Binary files /dev/null and b/libraries/SdFat/extras/html/classios__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/classiostream-members.html b/libraries/SdFat/extras/html/classiostream-members.html new file mode 100644 index 0000000..5b4d60b --- /dev/null +++ b/libraries/SdFat/extras/html/classiostream-members.html @@ -0,0 +1,211 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
iostream Member List
+
+
+ +

This is the complete list of members for iostream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)iosinline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
flush()ostreaminline
fmtflags typedefios_base
gcount() const istreaminline
get()istream
get(char &ch)istream
get(char *str, streamsize n, char delim= '\n')istream
getline(char *str, streamsize n, char delim= '\n')istream
good() const iosinline
goodbitios_basestatic
hexios_basestatic
ignore(streamsize n=1, int delim=-1)istream
inios_basestatic
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
istream() (defined in istream)istreaminline
leftios_basestatic
octios_basestatic
off_type typedefios_base
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
operator<<(ostream &(*pf)(ostream &str))ostreaminline
operator<<(ios_base &(*pf)(ios_base &str))ostreaminline
operator<<(bool arg)ostreaminline
operator<<(const char *arg)ostreaminline
operator<<(const signed char *arg)ostreaminline
operator<<(const unsigned char *arg)ostreaminline
operator<<(char arg)ostreaminline
operator<<(signed char arg)ostreaminline
operator<<(unsigned char arg)ostreaminline
operator<<(double arg)ostreaminline
operator<<(float arg)ostreaminline
operator<<(short arg)ostreaminline
operator<<(unsigned short arg)ostreaminline
operator<<(int arg)ostreaminline
operator<<(unsigned int arg)ostreaminline
operator<<(long arg)ostreaminline
operator<<(unsigned long arg)ostreaminline
operator<<(const void *arg)ostreaminline
operator<<(const __FlashStringHelper *arg)ostreaminline
operator>>(istream &(*pf)(istream &str))istreaminline
operator>>(ios_base &(*pf)(ios_base &str))istreaminline
operator>>(ios &(*pf)(ios &str))istreaminline
operator>>(char *str)istreaminline
operator>>(char &ch)istreaminline
operator>>(signed char *str)istreaminline
operator>>(signed char &ch)istreaminline
operator>>(unsigned char *str)istreaminline
operator>>(unsigned char &ch)istreaminline
operator>>(bool &arg)istreaminline
operator>>(short &arg)istreaminline
operator>>(unsigned short &arg)istreaminline
operator>>(int &arg)istreaminline
operator>>(unsigned int &arg)istreaminline
operator>>(long &arg)istreaminline
operator>>(unsigned long &arg)istreaminline
operator>>(double &arg)istreaminline
operator>>(float &arg)istreaminline
operator>>(void *&arg)istreaminline
ostream() (defined in ostream)ostreaminline
outios_basestatic
peek()istream
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
put(char ch)ostreaminline
rdstate() const iosinline
rightios_basestatic
seekdir enum nameios_base
seekg(pos_type pos)istreaminline
seekg(off_type off, seekdir way)istreaminline
seekp(pos_type pos)ostreaminline
seekp(off_type off, seekdir way)ostreaminline
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipWhite()istream
skipwsios_basestatic
streamsize typedefios_base
tellg()istreaminline
tellp()ostreaminline
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/classiostream.html b/libraries/SdFat/extras/html/classiostream.html new file mode 100644 index 0000000..e3cf212 --- /dev/null +++ b/libraries/SdFat/extras/html/classiostream.html @@ -0,0 +1,3288 @@ + + + + + + +SdFat: iostream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Input/Output stream. + More...

+ +

#include <iostream.h>

+
+Inheritance diagram for iostream:
+
+
Inheritance graph
+ + + + + + + +
[legend]
+
+Collaboration diagram for iostream:
+
+
Collaboration graph
+ + + + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool bad () const
 
void clear (iostate state=goodbit)
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
ostreamflush ()
 
streamsize gcount () const
 
int get ()
 
istreamget (char &ch)
 
istreamget (char *str, streamsize n, char delim= '\n')
 
istreamgetline (char *str, streamsize n, char delim= '\n')
 
bool good () const
 
istreamignore (streamsize n=1, int delim=-1)
 
 operator const void * () const
 
bool operator! () const
 
ostreamoperator<< (ostream &(*pf)(ostream &str))
 
ostreamoperator<< (ios_base &(*pf)(ios_base &str))
 
ostreamoperator<< (bool arg)
 
ostreamoperator<< (const char *arg)
 
ostreamoperator<< (const signed char *arg)
 
ostreamoperator<< (const unsigned char *arg)
 
ostreamoperator<< (char arg)
 
ostreamoperator<< (signed char arg)
 
ostreamoperator<< (unsigned char arg)
 
ostreamoperator<< (double arg)
 
ostreamoperator<< (float arg)
 
ostreamoperator<< (short arg)
 
ostreamoperator<< (unsigned short arg)
 
ostreamoperator<< (int arg)
 
ostreamoperator<< (unsigned int arg)
 
ostreamoperator<< (long arg)
 
ostreamoperator<< (unsigned long arg)
 
ostreamoperator<< (const void *arg)
 
ostreamoperator<< (const __FlashStringHelper *arg)
 
istreamoperator>> (istream &(*pf)(istream &str))
 
istreamoperator>> (ios_base &(*pf)(ios_base &str))
 
istreamoperator>> (ios &(*pf)(ios &str))
 
istreamoperator>> (char *str)
 
istreamoperator>> (char &ch)
 
istreamoperator>> (signed char *str)
 
istreamoperator>> (signed char &ch)
 
istreamoperator>> (unsigned char *str)
 
istreamoperator>> (unsigned char &ch)
 
istreamoperator>> (bool &arg)
 
istreamoperator>> (short &arg)
 
istreamoperator>> (unsigned short &arg)
 
istreamoperator>> (int &arg)
 
istreamoperator>> (unsigned int &arg)
 
istreamoperator>> (long &arg)
 
istreamoperator>> (unsigned long &arg)
 
istreamoperator>> (double &arg)
 
istreamoperator>> (float &arg)
 
istreamoperator>> (void *&arg)
 
int peek ()
 
int precision () const
 
int precision (unsigned int n)
 
ostreamput (char ch)
 
iostate rdstate () const
 
istreamseekg (pos_type pos)
 
istreamseekg (off_type off, seekdir way)
 
ostreamseekp (pos_type pos)
 
ostreamseekp (off_type off, seekdir way)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
void skipWhite ()
 
pos_type tellg ()
 
pos_type tellp ()
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+

Detailed Description

+

Input/Output stream.

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::clear (iostate state = goodbit)
+
+inlineinherited
+
+

Clear iostate bits.

+
Parameters
+ + +
[in]stateThe flags you want to set after clearing all flags.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ostream& ostream::flush ()
+
+inlineinherited
+
+

Flushes the buffer associated with this stream. The flush function calls the sync function of the associated file.

Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
streamsize istream::gcount () const
+
+inlineinherited
+
+
Returns
The number of characters extracted by the last unformatted input function.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int istream::get ()
+
+inherited
+
+

Extract a character if one is available.

+
Returns
The character or -1 if a failure occurs. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream & istream::get (char & ch)
+
+inherited
+
+

Extract a character if one is available.

+
Parameters
+ + +
[out]chlocation to receive the extracted character.
+
+
+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::get (char * str,
streamsize n,
char delim = '\n' 
)
+
+inherited
+
+

Extract characters.

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, n is less than 1, n-1 characters are extracted, or the next character equals delim (delim is not extracted). If no characters are extracted failbit is set. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::getline (char * str,
streamsize n,
char delim = '\n' 
)
+
+inherited
+
+

Extract characters

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, the next character equals delim (delim is extracted), or n-1 characters are extracted.

+

The failbit is set if no characters are extracted or n-1 characters are extracted. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream & istream::ignore (streamsize n = 1,
int delim = -1 
)
+
+inherited
+
+

Extract characters and discard them.

+
Parameters
+ + + +
[in]nmaximum number of characters to ignore.
[in]delimDelimiter.
+
+
+

Characters are extracted until extraction fails, n characters are extracted, or the next input character equals delim (the delimiter is extracted). If end-of-file occurs the eofbit is set.

+

Failures are indicated by the state of the stream.

+
Returns
*this
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ostream &(*)(ostream &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ios_base &(*)(ios_base &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (bool arg)
+
+inlineinherited
+
+

Output bool

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const signed char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const unsigned char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (signed char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (double arg)
+
+inlineinherited
+
+

Output double

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (float arg)
+
+inlineinherited
+
+

Output float

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (short arg)
+
+inlineinherited
+
+

Output signed short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned short arg)
+
+inlineinherited
+
+

Output unsigned short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (int arg)
+
+inlineinherited
+
+

Output signed int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned int arg)
+
+inlineinherited
+
+

Output unsigned int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (long arg)
+
+inlineinherited
+
+

Output signed long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned long arg)
+
+inlineinherited
+
+

Output unsigned long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const void * arg)
+
+inlineinherited
+
+

Output pointer

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const __FlashStringHelper * arg)
+
+inlineinherited
+
+

Output a string from flash using the Arduino F() macro.

Parameters
+ + +
[in]argpointing to flash string
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (istream &(*)(istream &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios_base &(*)(ios_base &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios &(*)(ios &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char * str)
+
+inlineinherited
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char & ch)
+
+inlineinherited
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (bool & arg)
+
+inlineinherited
+
+

Extract a value of type bool.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (short & arg)
+
+inlineinherited
+
+

Extract a value of type short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned short & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (int & arg)
+
+inlineinherited
+
+

Extract a value of type int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned int & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (long & arg)
+
+inlineinherited
+
+

Extract a value of type long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned long & arg)
+
+inlineinherited
+
+

Extract a value of type unsigned long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (double & arg)
+
+inlineinherited
+
+

Extract a value of type double.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (float & arg)
+
+inlineinherited
+
+

Extract a value of type float.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (void *& arg)
+
+inlineinherited
+
+

Extract a value of type void*.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int istream::peek ()
+
+inherited
+
+

Return the next available character without consuming it.

+
Returns
The character if the stream state is good else -1;
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::put (char ch)
+
+inlineinherited
+
+

Puts a character in a stream.

+

The unformatted output function inserts the element ch. It returns *this.

+
Parameters
+ + +
[in]chThe character
+
+
+
Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::seekg (pos_type pos)
+
+inlineinherited
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the read pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream& istream::seekg (off_type off,
seekdir way 
)
+
+inlineinherited
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the read pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::seekp (pos_type pos)
+
+inlineinherited
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the write pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ostream& ostream::seekp (off_type off,
seekdir way 
)
+
+inlineinherited
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the write pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void istream::skipWhite ()
+
+inherited
+
+

used to implement ws()

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type istream::tellg ()
+
+inlineinherited
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type ostream::tellp ()
+
+inlineinherited
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/classiostream__coll__graph.png b/libraries/SdFat/extras/html/classiostream__coll__graph.png new file mode 100644 index 0000000..749d653 Binary files /dev/null and b/libraries/SdFat/extras/html/classiostream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/classiostream__inherit__graph.png b/libraries/SdFat/extras/html/classiostream__inherit__graph.png new file mode 100644 index 0000000..644dd2d Binary files /dev/null and b/libraries/SdFat/extras/html/classiostream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/classistream-members.html b/libraries/SdFat/extras/html/classistream-members.html new file mode 100644 index 0000000..3d57592 --- /dev/null +++ b/libraries/SdFat/extras/html/classistream-members.html @@ -0,0 +1,186 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
istream Member List
+
+
+ +

This is the complete list of members for istream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)iosinline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
fmtflags typedefios_base
gcount() const istreaminline
get()istream
get(char &ch)istream
get(char *str, streamsize n, char delim= '\n')istream
getline(char *str, streamsize n, char delim= '\n')istream
good() const iosinline
goodbitios_basestatic
hexios_basestatic
ignore(streamsize n=1, int delim=-1)istream
inios_basestatic
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
istream() (defined in istream)istreaminline
leftios_basestatic
octios_basestatic
off_type typedefios_base
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
operator>>(istream &(*pf)(istream &str))istreaminline
operator>>(ios_base &(*pf)(ios_base &str))istreaminline
operator>>(ios &(*pf)(ios &str))istreaminline
operator>>(char *str)istreaminline
operator>>(char &ch)istreaminline
operator>>(signed char *str)istreaminline
operator>>(signed char &ch)istreaminline
operator>>(unsigned char *str)istreaminline
operator>>(unsigned char &ch)istreaminline
operator>>(bool &arg)istreaminline
operator>>(short &arg)istreaminline
operator>>(unsigned short &arg)istreaminline
operator>>(int &arg)istreaminline
operator>>(unsigned int &arg)istreaminline
operator>>(long &arg)istreaminline
operator>>(unsigned long &arg)istreaminline
operator>>(double &arg)istreaminline
operator>>(float &arg)istreaminline
operator>>(void *&arg)istreaminline
outios_basestatic
peek()istream
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
rdstate() const iosinline
rightios_basestatic
seekdir enum nameios_base
seekg(pos_type pos)istreaminline
seekg(off_type off, seekdir way)istreaminline
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipWhite()istream
skipwsios_basestatic
streamsize typedefios_base
tellg()istreaminline
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/classistream.html b/libraries/SdFat/extras/html/classistream.html new file mode 100644 index 0000000..dc8d0de --- /dev/null +++ b/libraries/SdFat/extras/html/classistream.html @@ -0,0 +1,2441 @@ + + + + + + +SdFat: istream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Input Stream. + More...

+ +

#include <istream.h>

+
+Inheritance diagram for istream:
+
+
Inheritance graph
+ + + + + + + + + +
[legend]
+
+Collaboration diagram for istream:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool bad () const
 
void clear (iostate state=goodbit)
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
streamsize gcount () const
 
int get ()
 
istreamget (char &ch)
 
istreamget (char *str, streamsize n, char delim= '\n')
 
istreamgetline (char *str, streamsize n, char delim= '\n')
 
bool good () const
 
istreamignore (streamsize n=1, int delim=-1)
 
 operator const void * () const
 
bool operator! () const
 
istreamoperator>> (istream &(*pf)(istream &str))
 
istreamoperator>> (ios_base &(*pf)(ios_base &str))
 
istreamoperator>> (ios &(*pf)(ios &str))
 
istreamoperator>> (char *str)
 
istreamoperator>> (char &ch)
 
istreamoperator>> (signed char *str)
 
istreamoperator>> (signed char &ch)
 
istreamoperator>> (unsigned char *str)
 
istreamoperator>> (unsigned char &ch)
 
istreamoperator>> (bool &arg)
 
istreamoperator>> (short &arg)
 
istreamoperator>> (unsigned short &arg)
 
istreamoperator>> (int &arg)
 
istreamoperator>> (unsigned int &arg)
 
istreamoperator>> (long &arg)
 
istreamoperator>> (unsigned long &arg)
 
istreamoperator>> (double &arg)
 
istreamoperator>> (float &arg)
 
istreamoperator>> (void *&arg)
 
int peek ()
 
int precision () const
 
int precision (unsigned int n)
 
iostate rdstate () const
 
istreamseekg (pos_type pos)
 
istreamseekg (off_type off, seekdir way)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
void skipWhite ()
 
pos_type tellg ()
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+

Detailed Description

+

Input Stream.

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::clear (iostate state = goodbit)
+
+inlineinherited
+
+

Clear iostate bits.

+
Parameters
+ + +
[in]stateThe flags you want to set after clearing all flags.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
streamsize istream::gcount () const
+
+inline
+
+
Returns
The number of characters extracted by the last unformatted input function.
+ +
+
+ +
+
+ + + + + + + +
int istream::get ()
+
+

Extract a character if one is available.

+
Returns
The character or -1 if a failure occurs. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + + + + +
istream & istream::get (char & ch)
+
+

Extract a character if one is available.

+
Parameters
+ + +
[out]chlocation to receive the extracted character.
+
+
+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::get (char * str,
streamsize n,
char delim = '\n' 
)
+
+

Extract characters.

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, n is less than 1, n-1 characters are extracted, or the next character equals delim (delim is not extracted). If no characters are extracted failbit is set. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
istream & istream::getline (char * str,
streamsize n,
char delim = '\n' 
)
+
+

Extract characters

+
Parameters
+ + + + +
[out]strLocation to receive extracted characters.
[in]nSize of str.
[in]delimDelimiter
+
+
+

Characters are extracted until extraction fails, the next character equals delim (delim is extracted), or n-1 characters are extracted.

+

The failbit is set if no characters are extracted or n-1 characters are extracted. If end-of-file occurs the eofbit is set.

+
Returns
always returns *this. A failure is indicated by the stream state.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
istream & istream::ignore (streamsize n = 1,
int delim = -1 
)
+
+

Extract characters and discard them.

+
Parameters
+ + + +
[in]nmaximum number of characters to ignore.
[in]delimDelimiter.
+
+
+

Characters are extracted until extraction fails, n characters are extracted, or the next input character equals delim (the delimiter is extracted). If end-of-file occurs the eofbit is set.

+

Failures are indicated by the state of the stream.

+
Returns
*this
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (istream &(*)(istream &str) pf)
+
+inline
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios_base &(*)(ios_base &str) pf)
+
+inline
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (ios &(*)(ios &str) pf)
+
+inline
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char * str)
+
+inline
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (char & ch)
+
+inline
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char * str)
+
+inline
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (signed char & ch)
+
+inline
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char * str)
+
+inline
+
+

Extract a character string

Parameters
+ + +
[out]strlocation to store the string.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned char & ch)
+
+inline
+
+

Extract a character

Parameters
+ + +
[out]chlocation to store the character.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (bool & arg)
+
+inline
+
+

Extract a value of type bool.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (short & arg)
+
+inline
+
+

Extract a value of type short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned short & arg)
+
+inline
+
+

Extract a value of type unsigned short.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (int & arg)
+
+inline
+
+

Extract a value of type int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned int & arg)
+
+inline
+
+

Extract a value of type unsigned int.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (long & arg)
+
+inline
+
+

Extract a value of type long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (unsigned long & arg)
+
+inline
+
+

Extract a value of type unsigned long.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (double & arg)
+
+inline
+
+

Extract a value of type double.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (float & arg)
+
+inline
+
+

Extract a value of type float.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::operator>> (void *& arg)
+
+inline
+
+

Extract a value of type void*.

Parameters
+ + +
[out]arglocation to store the value.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + + + +
int istream::peek ()
+
+

Return the next available character without consuming it.

+
Returns
The character if the stream state is good else -1;
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& istream::seekg (pos_type pos)
+
+inline
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the read pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream& istream::seekg (off_type off,
seekdir way 
)
+
+inline
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the read pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + + + +
void istream::skipWhite ()
+
+

used to implement ws()

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type istream::tellg ()
+
+inline
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following files:
    +
  • Arduino/libraries/SdFat/src/FatLib/istream.h
  • +
  • Arduino/libraries/SdFat/src/FatLib/istream.cpp
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/classistream__coll__graph.png b/libraries/SdFat/extras/html/classistream__coll__graph.png new file mode 100644 index 0000000..d4c4e3a Binary files /dev/null and b/libraries/SdFat/extras/html/classistream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/classistream__inherit__graph.png b/libraries/SdFat/extras/html/classistream__inherit__graph.png new file mode 100644 index 0000000..aa20a7a Binary files /dev/null and b/libraries/SdFat/extras/html/classistream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/classobufstream-members.html b/libraries/SdFat/extras/html/classobufstream-members.html new file mode 100644 index 0000000..8a13942 --- /dev/null +++ b/libraries/SdFat/extras/html/classobufstream-members.html @@ -0,0 +1,185 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
obufstream Member List
+
+
+ +

This is the complete list of members for obufstream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
buf()obufstreaminline
clear(iostate state=goodbit)iosinline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
flush()ostreaminline
fmtflags typedefios_base
good() const iosinline
goodbitios_basestatic
hexios_basestatic
inios_basestatic
init(char *buf, size_t size)obufstreaminline
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
leftios_basestatic
length()obufstreaminline
obufstream()obufstreaminline
obufstream(char *buf, size_t size)obufstreaminline
octios_basestatic
off_type typedefios_base
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
operator<<(ostream &(*pf)(ostream &str))ostreaminline
operator<<(ios_base &(*pf)(ios_base &str))ostreaminline
operator<<(bool arg)ostreaminline
operator<<(const char *arg)ostreaminline
operator<<(const signed char *arg)ostreaminline
operator<<(const unsigned char *arg)ostreaminline
operator<<(char arg)ostreaminline
operator<<(signed char arg)ostreaminline
operator<<(unsigned char arg)ostreaminline
operator<<(double arg)ostreaminline
operator<<(float arg)ostreaminline
operator<<(short arg)ostreaminline
operator<<(unsigned short arg)ostreaminline
operator<<(int arg)ostreaminline
operator<<(unsigned int arg)ostreaminline
operator<<(long arg)ostreaminline
operator<<(unsigned long arg)ostreaminline
operator<<(const void *arg)ostreaminline
operator<<(const __FlashStringHelper *arg)ostreaminline
ostream() (defined in ostream)ostreaminline
outios_basestatic
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
put(char ch)ostreaminline
rdstate() const iosinline
rightios_basestatic
seekdir enum nameios_base
seekp(pos_type pos)ostreaminline
seekp(off_type off, seekdir way)ostreaminline
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipwsios_basestatic
streamsize typedefios_base
tellp()ostreaminline
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/classobufstream.html b/libraries/SdFat/extras/html/classobufstream.html new file mode 100644 index 0000000..8a8d7a6 --- /dev/null +++ b/libraries/SdFat/extras/html/classobufstream.html @@ -0,0 +1,2425 @@ + + + + + + +SdFat: obufstream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

format a char string + More...

+ +

#include <bufstream.h>

+
+Inheritance diagram for obufstream:
+
+
Inheritance graph
+ + + + + +
[legend]
+
+Collaboration diagram for obufstream:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool bad () const
 
char * buf ()
 
void clear (iostate state=goodbit)
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
ostreamflush ()
 
bool good () const
 
void init (char *buf, size_t size)
 
size_t length ()
 
 obufstream ()
 
 obufstream (char *buf, size_t size)
 
 operator const void * () const
 
bool operator! () const
 
ostreamoperator<< (ostream &(*pf)(ostream &str))
 
ostreamoperator<< (ios_base &(*pf)(ios_base &str))
 
ostreamoperator<< (bool arg)
 
ostreamoperator<< (const char *arg)
 
ostreamoperator<< (const signed char *arg)
 
ostreamoperator<< (const unsigned char *arg)
 
ostreamoperator<< (char arg)
 
ostreamoperator<< (signed char arg)
 
ostreamoperator<< (unsigned char arg)
 
ostreamoperator<< (double arg)
 
ostreamoperator<< (float arg)
 
ostreamoperator<< (short arg)
 
ostreamoperator<< (unsigned short arg)
 
ostreamoperator<< (int arg)
 
ostreamoperator<< (unsigned int arg)
 
ostreamoperator<< (long arg)
 
ostreamoperator<< (unsigned long arg)
 
ostreamoperator<< (const void *arg)
 
ostreamoperator<< (const __FlashStringHelper *arg)
 
int precision () const
 
int precision (unsigned int n)
 
ostreamput (char ch)
 
iostate rdstate () const
 
ostreamseekp (pos_type pos)
 
ostreamseekp (off_type off, seekdir way)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
pos_type tellp ()
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+

Detailed Description

+

format a char string

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
obufstream::obufstream ()
+
+inline
+
+

constructor

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
obufstream::obufstream (char * buf,
size_t size 
)
+
+inline
+
+

Constructor

Parameters
+ + + +
[in]bufbuffer for formatted string
[in]sizebuffer size
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char* obufstream::buf ()
+
+inline
+
+
Returns
a pointer to the buffer
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::clear (iostate state = goodbit)
+
+inlineinherited
+
+

Clear iostate bits.

+
Parameters
+ + +
[in]stateThe flags you want to set after clearing all flags.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ostream& ostream::flush ()
+
+inlineinherited
+
+

Flushes the buffer associated with this stream. The flush function calls the sync function of the associated file.

Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void obufstream::init (char * buf,
size_t size 
)
+
+inline
+
+

Initialize an obufstream

Parameters
+ + + +
[in]bufbuffer for formatted string
[in]sizebuffer size
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t obufstream::length ()
+
+inline
+
+
Returns
the length of the formatted string
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ostream &(*)(ostream &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ios_base &(*)(ios_base &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (bool arg)
+
+inlineinherited
+
+

Output bool

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const signed char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const unsigned char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (signed char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (double arg)
+
+inlineinherited
+
+

Output double

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (float arg)
+
+inlineinherited
+
+

Output float

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (short arg)
+
+inlineinherited
+
+

Output signed short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned short arg)
+
+inlineinherited
+
+

Output unsigned short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (int arg)
+
+inlineinherited
+
+

Output signed int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned int arg)
+
+inlineinherited
+
+

Output unsigned int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (long arg)
+
+inlineinherited
+
+

Output signed long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned long arg)
+
+inlineinherited
+
+

Output unsigned long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const void * arg)
+
+inlineinherited
+
+

Output pointer

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const __FlashStringHelper * arg)
+
+inlineinherited
+
+

Output a string from flash using the Arduino F() macro.

Parameters
+ + +
[in]argpointing to flash string
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::put (char ch)
+
+inlineinherited
+
+

Puts a character in a stream.

+

The unformatted output function inserts the element ch. It returns *this.

+
Parameters
+ + +
[in]chThe character
+
+
+
Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::seekp (pos_type pos)
+
+inlineinherited
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the write pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ostream& ostream::seekp (off_type off,
seekdir way 
)
+
+inlineinherited
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the write pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type ostream::tellp ()
+
+inlineinherited
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/classobufstream__coll__graph.png b/libraries/SdFat/extras/html/classobufstream__coll__graph.png new file mode 100644 index 0000000..24cb78c Binary files /dev/null and b/libraries/SdFat/extras/html/classobufstream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/classobufstream__inherit__graph.png b/libraries/SdFat/extras/html/classobufstream__inherit__graph.png new file mode 100644 index 0000000..24cb78c Binary files /dev/null and b/libraries/SdFat/extras/html/classobufstream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/classofstream-members.html b/libraries/SdFat/extras/html/classofstream-members.html new file mode 100644 index 0000000..20f4929 --- /dev/null +++ b/libraries/SdFat/extras/html/classofstream-members.html @@ -0,0 +1,188 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
ofstream Member List
+
+
+ +

This is the complete list of members for ofstream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)ofstreaminline
close()ofstreaminline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
flush()ostreaminline
fmtflags typedefios_base
good() const iosinline
goodbitios_basestatic
hexios_basestatic
inios_basestatic
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
is_open()ofstreaminline
leftios_basestatic
octios_basestatic
off_type typedefios_base
ofstream() (defined in ofstream)ofstreaminline
ofstream(const char *path, ios::openmode mode=out)ofstreaminlineexplicit
open(const char *path, openmode mode=out)ofstreaminline
FatStreamBase::open(FatFileSystem *fs, const char *path, uint8_t oflag)FatFileprivate
FatStreamBase::open(FatFile *dirFile, uint16_t index, uint8_t oflag)FatFileprivate
FatStreamBase::open(FatFile *dirFile, const char *path, uint8_t oflag)FatFileprivate
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
operator<<(ostream &(*pf)(ostream &str))ostreaminline
operator<<(ios_base &(*pf)(ios_base &str))ostreaminline
operator<<(bool arg)ostreaminline
operator<<(const char *arg)ostreaminline
operator<<(const signed char *arg)ostreaminline
operator<<(const unsigned char *arg)ostreaminline
operator<<(char arg)ostreaminline
operator<<(signed char arg)ostreaminline
operator<<(unsigned char arg)ostreaminline
operator<<(double arg)ostreaminline
operator<<(float arg)ostreaminline
operator<<(short arg)ostreaminline
operator<<(unsigned short arg)ostreaminline
operator<<(int arg)ostreaminline
operator<<(unsigned int arg)ostreaminline
operator<<(long arg)ostreaminline
operator<<(unsigned long arg)ostreaminline
operator<<(const void *arg)ostreaminline
operator<<(const __FlashStringHelper *arg)ostreaminline
ostream() (defined in ostream)ostreaminline
outios_basestatic
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
put(char ch)ostreaminline
rdstate() const iosinline
rightios_basestatic
seekdir enum nameios_base
seekp(pos_type pos)ostreaminline
seekp(off_type off, seekdir way)ostreaminline
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipwsios_basestatic
streamsize typedefios_base
tellp()ostreaminline
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/classofstream.html b/libraries/SdFat/extras/html/classofstream.html new file mode 100644 index 0000000..bd05951 --- /dev/null +++ b/libraries/SdFat/extras/html/classofstream.html @@ -0,0 +1,2413 @@ + + + + + + +SdFat: ofstream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

file output stream. + More...

+ +

#include <fstream.h>

+
+Inheritance diagram for ofstream:
+
+
Inheritance graph
+ + + + + + + +
[legend]
+
+Collaboration diagram for ofstream:
+
+
Collaboration graph
+ + + + + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool bad () const
 
void clear (iostate state=goodbit)
 
void close ()
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
ostreamflush ()
 
bool good () const
 
bool is_open ()
 
 ofstream (const char *path, ios::openmode mode=out)
 
void open (const char *path, openmode mode=out)
 
 operator const void * () const
 
bool operator! () const
 
ostreamoperator<< (ostream &(*pf)(ostream &str))
 
ostreamoperator<< (ios_base &(*pf)(ios_base &str))
 
ostreamoperator<< (bool arg)
 
ostreamoperator<< (const char *arg)
 
ostreamoperator<< (const signed char *arg)
 
ostreamoperator<< (const unsigned char *arg)
 
ostreamoperator<< (char arg)
 
ostreamoperator<< (signed char arg)
 
ostreamoperator<< (unsigned char arg)
 
ostreamoperator<< (double arg)
 
ostreamoperator<< (float arg)
 
ostreamoperator<< (short arg)
 
ostreamoperator<< (unsigned short arg)
 
ostreamoperator<< (int arg)
 
ostreamoperator<< (unsigned int arg)
 
ostreamoperator<< (long arg)
 
ostreamoperator<< (unsigned long arg)
 
ostreamoperator<< (const void *arg)
 
ostreamoperator<< (const __FlashStringHelper *arg)
 
int precision () const
 
int precision (unsigned int n)
 
ostreamput (char ch)
 
iostate rdstate () const
 
ostreamseekp (pos_type pos)
 
ostreamseekp (off_type off, seekdir way)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
pos_type tellp ()
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+ + + + + + + +

+Private Member Functions

bool open (FatFileSystem *fs, const char *path, uint8_t oflag)
 
bool open (FatFile *dirFile, uint16_t index, uint8_t oflag)
 
bool open (FatFile *dirFile, const char *path, uint8_t oflag)
 
+

Detailed Description

+

file output stream.

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ofstream::ofstream (const char * path,
ios::openmode mode = out 
)
+
+inlineexplicit
+
+

Constructor with open

Parameters
+ + + +
[in]pathfile to open
[in]modeopen mode
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ofstream::clear (iostate state = goodbit)
+
+inline
+
+

Clear state and writeError

Parameters
+ + +
[in]statenew state for stream
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void ofstream::close ()
+
+inline
+
+

Close a file and force cached data and directory information to be written to the storage device.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ostream& ostream::flush ()
+
+inlineinherited
+
+

Flushes the buffer associated with this stream. The flush function calls the sync function of the associated file.

Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ofstream::is_open ()
+
+inline
+
+
Returns
True if stream is open else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void ofstream::open (const char * path,
openmode mode = out 
)
+
+inline
+
+

Open an ofstream

Parameters
+ + + +
[in]pathfile to open
[in]modeopen mode
+
+
+

mode See fstream::open() for valid modes.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ostream &(*)(ostream &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ios_base &(*)(ios_base &str) pf)
+
+inlineinherited
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (bool arg)
+
+inlineinherited
+
+

Output bool

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const signed char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const unsigned char * arg)
+
+inlineinherited
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (signed char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned char arg)
+
+inlineinherited
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (double arg)
+
+inlineinherited
+
+

Output double

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (float arg)
+
+inlineinherited
+
+

Output float

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (short arg)
+
+inlineinherited
+
+

Output signed short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned short arg)
+
+inlineinherited
+
+

Output unsigned short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (int arg)
+
+inlineinherited
+
+

Output signed int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned int arg)
+
+inlineinherited
+
+

Output unsigned int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (long arg)
+
+inlineinherited
+
+

Output signed long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned long arg)
+
+inlineinherited
+
+

Output unsigned long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const void * arg)
+
+inlineinherited
+
+

Output pointer

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const __FlashStringHelper * arg)
+
+inlineinherited
+
+

Output a string from flash using the Arduino F() macro.

Parameters
+ + +
[in]argpointing to flash string
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::put (char ch)
+
+inlineinherited
+
+

Puts a character in a stream.

+

The unformatted output function inserts the element ch. It returns *this.

+
Parameters
+ + +
[in]chThe character
+
+
+
Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::seekp (pos_type pos)
+
+inlineinherited
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the write pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ostream& ostream::seekp (off_type off,
seekdir way 
)
+
+inlineinherited
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the write pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type ostream::tellp ()
+
+inlineinherited
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/FatLib/fstream.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/classofstream__coll__graph.png b/libraries/SdFat/extras/html/classofstream__coll__graph.png new file mode 100644 index 0000000..bb2fc85 Binary files /dev/null and b/libraries/SdFat/extras/html/classofstream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/classofstream__inherit__graph.png b/libraries/SdFat/extras/html/classofstream__inherit__graph.png new file mode 100644 index 0000000..bb2fc85 Binary files /dev/null and b/libraries/SdFat/extras/html/classofstream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/classostream-members.html b/libraries/SdFat/extras/html/classostream-members.html new file mode 100644 index 0000000..c0238d2 --- /dev/null +++ b/libraries/SdFat/extras/html/classostream-members.html @@ -0,0 +1,180 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
ostream Member List
+
+
+ +

This is the complete list of members for ostream, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
adjustfieldios_basestatic
appios_basestatic
ateios_basestatic
bad() const iosinline
badbitios_basestatic
basefieldios_basestatic
beg enum valueios_base
binaryios_basestatic
boolalphaios_basestatic
clear(iostate state=goodbit)iosinline
cur enum valueios_base
decios_basestatic
end enum valueios_base
eof() const iosinline
eofbitios_basestatic
fail() const iosinline
failbitios_basestatic
fill()ios_baseinline
fill(char c)ios_baseinline
flags() const ios_baseinline
flags(fmtflags fl)ios_baseinline
flush()ostreaminline
fmtflags typedefios_base
good() const iosinline
goodbitios_basestatic
hexios_basestatic
inios_basestatic
internalios_basestatic
ios()iosinline
ios_base() (defined in ios_base)ios_baseinline
iostate typedefios_base
leftios_basestatic
octios_basestatic
off_type typedefios_base
openmode typedefios_base
operator const void *() const iosinline
operator!() const iosinline
operator<<(ostream &(*pf)(ostream &str))ostreaminline
operator<<(ios_base &(*pf)(ios_base &str))ostreaminline
operator<<(bool arg)ostreaminline
operator<<(const char *arg)ostreaminline
operator<<(const signed char *arg)ostreaminline
operator<<(const unsigned char *arg)ostreaminline
operator<<(char arg)ostreaminline
operator<<(signed char arg)ostreaminline
operator<<(unsigned char arg)ostreaminline
operator<<(double arg)ostreaminline
operator<<(float arg)ostreaminline
operator<<(short arg)ostreaminline
operator<<(unsigned short arg)ostreaminline
operator<<(int arg)ostreaminline
operator<<(unsigned int arg)ostreaminline
operator<<(long arg)ostreaminline
operator<<(unsigned long arg)ostreaminline
operator<<(const void *arg)ostreaminline
operator<<(const __FlashStringHelper *arg)ostreaminline
ostream() (defined in ostream)ostreaminline
outios_basestatic
pos_type typedefios_base
precision() const ios_baseinline
precision(unsigned int n)ios_baseinline
put(char ch)ostreaminline
rdstate() const iosinline
rightios_basestatic
seekdir enum nameios_base
seekp(pos_type pos)ostreaminline
seekp(off_type off, seekdir way)ostreaminline
setf(fmtflags fl)ios_baseinline
setf(fmtflags fl, fmtflags mask)ios_baseinline
setstate(iostate state)iosinline
showbaseios_basestatic
showpointios_basestatic
showposios_basestatic
skipwsios_basestatic
streamsize typedefios_base
tellp()ostreaminline
truncios_basestatic
unsetf(fmtflags fl)ios_baseinline
uppercaseios_basestatic
width()ios_baseinline
width(unsigned n)ios_baseinline
+ + + + diff --git a/libraries/SdFat/extras/html/classostream.html b/libraries/SdFat/extras/html/classostream.html new file mode 100644 index 0000000..d90519e --- /dev/null +++ b/libraries/SdFat/extras/html/classostream.html @@ -0,0 +1,2264 @@ + + + + + + +SdFat: ostream Class Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Output Stream. + More...

+ +

#include <ostream.h>

+
+Inheritance diagram for ostream:
+
+
Inheritance graph
+ + + + + + + + + +
[legend]
+
+Collaboration diagram for ostream:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

typedef unsigned int fmtflags
 
typedef unsigned char iostate
 
typedef int32_t off_type
 
typedef uint8_t openmode
 
typedef uint32_t pos_type
 
enum  seekdir { beg, +cur, +end + }
 
typedef uint32_t streamsize
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

bool bad () const
 
void clear (iostate state=goodbit)
 
bool eof () const
 
bool fail () const
 
char fill ()
 
char fill (char c)
 
fmtflags flags () const
 
fmtflags flags (fmtflags fl)
 
ostreamflush ()
 
bool good () const
 
 operator const void * () const
 
bool operator! () const
 
ostreamoperator<< (ostream &(*pf)(ostream &str))
 
ostreamoperator<< (ios_base &(*pf)(ios_base &str))
 
ostreamoperator<< (bool arg)
 
ostreamoperator<< (const char *arg)
 
ostreamoperator<< (const signed char *arg)
 
ostreamoperator<< (const unsigned char *arg)
 
ostreamoperator<< (char arg)
 
ostreamoperator<< (signed char arg)
 
ostreamoperator<< (unsigned char arg)
 
ostreamoperator<< (double arg)
 
ostreamoperator<< (float arg)
 
ostreamoperator<< (short arg)
 
ostreamoperator<< (unsigned short arg)
 
ostreamoperator<< (int arg)
 
ostreamoperator<< (unsigned int arg)
 
ostreamoperator<< (long arg)
 
ostreamoperator<< (unsigned long arg)
 
ostreamoperator<< (const void *arg)
 
ostreamoperator<< (const __FlashStringHelper *arg)
 
int precision () const
 
int precision (unsigned int n)
 
ostreamput (char ch)
 
iostate rdstate () const
 
ostreamseekp (pos_type pos)
 
ostreamseekp (off_type off, seekdir way)
 
fmtflags setf (fmtflags fl)
 
fmtflags setf (fmtflags fl, fmtflags mask)
 
void setstate (iostate state)
 
pos_type tellp ()
 
void unsetf (fmtflags fl)
 
unsigned width ()
 
unsigned width (unsigned n)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

static const fmtflags adjustfield = left | right | internal
 
static const openmode app = 0X4
 
static const openmode ate = 0X8
 
static const iostate badbit = 0X01
 
static const fmtflags basefield = dec | hex | oct
 
static const openmode binary = 0X10
 
static const fmtflags boolalpha = 0x0100
 
static const fmtflags dec = 0x0008
 
static const iostate eofbit = 0x02
 
static const iostate failbit = 0X04
 
static const iostate goodbit = 0x00
 
static const fmtflags hex = 0x0010
 
static const openmode in = 0X20
 
static const fmtflags internal = 0x0004
 
static const fmtflags left = 0x0001
 
static const fmtflags oct = 0x0020
 
static const openmode out = 0X40
 
static const fmtflags right = 0x0002
 
static const fmtflags showbase = 0x0200
 
static const fmtflags showpoint = 0x0400
 
static const fmtflags showpos = 0x0800
 
static const fmtflags skipws = 0x1000
 
static const openmode trunc = 0X80
 
static const fmtflags uppercase = 0x4000
 
+

Detailed Description

+

Output Stream.

+

Member Typedef Documentation

+ +
+
+ + + + + +
+ + + + +
typedef unsigned int ios_base::fmtflags
+
+inherited
+
+

type for format flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef unsigned char ios_base::iostate
+
+inherited
+
+

typedef for iostate bitmask

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef int32_t ios_base::off_type
+
+inherited
+
+

type for relative seek offset

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint8_t ios_base::openmode
+
+inherited
+
+

typedef for iostream open mode

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::pos_type
+
+inherited
+
+

type for absolute seek position

+ +
+
+ +
+
+ + + + + +
+ + + + +
typedef uint32_t ios_base::streamsize
+
+inherited
+
+

unsigned size that can represent maximum file size. (violates spec - should be signed)

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + + +
+ + + + +
enum ios_base::seekdir
+
+inherited
+
+

enumerated type for the direction of relative seeks

+ + + + +
Enumerator
beg  +

seek relative to the beginning of the stream

+
cur  +

seek relative to the current stream position

+
end  +

seek relative to the end of the stream

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool ios::bad () const
+
+inlineinherited
+
+
Returns
true if bad bit is set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::clear (iostate state = goodbit)
+
+inlineinherited
+
+

Clear iostate bits.

+
Parameters
+ + +
[in]stateThe flags you want to set after clearing all flags.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::eof () const
+
+inlineinherited
+
+
Returns
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 ios::fail () const
+
+inlineinherited
+
+
Returns
true if any iostate bit other than eof are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
char ios_base::fill ()
+
+inlineinherited
+
+
Returns
fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
char ios_base::fill (char c)
+
+inlineinherited
+
+

Set fill character

Parameters
+ + +
[in]cnew fill character
+
+
+
Returns
old fill character
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
fmtflags ios_base::flags () const
+
+inlineinherited
+
+
Returns
format flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::flags (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flag
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ostream& ostream::flush ()
+
+inline
+
+

Flushes the buffer associated with this stream. The flush function calls the sync function of the associated file.

Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::good () const
+
+inlineinherited
+
+
Returns
True if no iostate flags are set else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
ios::operator const void * () const
+
+inlineinherited
+
+
Returns
null pointer if fail() is true.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool ios::operator! () const
+
+inlineinherited
+
+
Returns
true if fail() else false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ostream &(*)(ostream &str) pf)
+
+inline
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (ios_base &(*)(ios_base &str) pf)
+
+inline
+
+

call manipulator

Parameters
+ + +
[in]pffunction to call
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (bool arg)
+
+inline
+
+

Output bool

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const char * arg)
+
+inline
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const signed char * arg)
+
+inline
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const unsigned char * arg)
+
+inline
+
+

Output string

Parameters
+ + +
[in]argstring to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (char arg)
+
+inline
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (signed char arg)
+
+inline
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned char arg)
+
+inline
+
+

Output character

Parameters
+ + +
[in]argcharacter to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (double arg)
+
+inline
+
+

Output double

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (float arg)
+
+inline
+
+

Output float

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (short arg)
+
+inline
+
+

Output signed short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned short arg)
+
+inline
+
+

Output unsigned short

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (int arg)
+
+inline
+
+

Output signed int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned int arg)
+
+inline
+
+

Output unsigned int

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (long arg)
+
+inline
+
+

Output signed long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (unsigned long arg)
+
+inline
+
+

Output unsigned long

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const void * arg)
+
+inline
+
+

Output pointer

Parameters
+ + +
[in]argvalue to output
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::operator<< (const __FlashStringHelper * arg)
+
+inline
+
+

Output a string from flash using the Arduino F() macro.

Parameters
+ + +
[in]argpointing to flash string
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int ios_base::precision () const
+
+inlineinherited
+
+
Returns
precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int ios_base::precision (unsigned int n)
+
+inlineinherited
+
+

set precision

Parameters
+ + +
[in]nnew precision
+
+
+
Returns
old precision
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::put (char ch)
+
+inline
+
+

Puts a character in a stream.

+

The unformatted output function inserts the element ch. It returns *this.

+
Parameters
+ + +
[in]chThe character
+
+
+
Returns
A reference to the ostream object.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
iostate ios::rdstate () const
+
+inlineinherited
+
+
Returns
The iostate flags for this file.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& ostream::seekp (pos_type pos)
+
+inline
+
+

Set the stream position

Parameters
+ + +
[in]posThe absolute position in which to move the write pointer.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ostream& ostream::seekp (off_type off,
seekdir way 
)
+
+inline
+
+

Set the stream position.

+
Parameters
+ + + +
[in]offAn offset to move the write pointer relative to way. off is a signed 32-bit int so the offset is limited to +- 2GB.
[in]wayOne of ios::beg, ios::cur, or ios::end.
+
+
+
Returns
Is always *this. Failure is indicated by the state of *this.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
fmtflags ios_base::setf (fmtflags fl)
+
+inlineinherited
+
+

set format flags

Parameters
+ + +
[in]flnew flags to be or'ed in
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
fmtflags ios_base::setf (fmtflags fl,
fmtflags mask 
)
+
+inlineinherited
+
+

modify format flags

Parameters
+ + + +
[in]maskflags to be removed
[in]flflags to be set after mask bits have been cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios::setstate (iostate state)
+
+inlineinherited
+
+

Set iostate bits.

+
Parameters
+ + +
[in]stateBitts to set.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pos_type ostream::tellp ()
+
+inline
+
+
Returns
the stream position
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void ios_base::unsetf (fmtflags fl)
+
+inlineinherited
+
+

clear format flags

Parameters
+ + +
[in]flflags to be cleared
+
+
+
Returns
old flags
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned ios_base::width ()
+
+inlineinherited
+
+
Returns
width
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
unsigned ios_base::width (unsigned n)
+
+inlineinherited
+
+

set width

Parameters
+ + +
[in]nnew width
+
+
+
Returns
old width
+ +
+
+

Member Data Documentation

+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::adjustfield = left | right | internal
+
+staticinherited
+
+

mask for adjustfield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::app = 0X4
+
+staticinherited
+
+

seek to end before each write

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::ate = 0X8
+
+staticinherited
+
+

open and seek to end immediately after opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::badbit = 0X01
+
+staticinherited
+
+

iostate bad bit for a nonrecoverable error.

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::basefield = dec | hex | oct
+
+staticinherited
+
+

mask for basefield

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::binary = 0X10
+
+staticinherited
+
+

perform input and output in binary mode (as opposed to text mode)

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::boolalpha = 0x0100
+
+staticinherited
+
+

use strings true/false for bool

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::dec = 0x0008
+
+staticinherited
+
+

base 10 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::eofbit = 0x02
+
+staticinherited
+
+

iostate bit for end of file reached

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::failbit = 0X04
+
+staticinherited
+
+

iostate fail bit for nonfatal error

+ +
+
+ +
+
+ + + + + +
+ + + + +
const iostate ios_base::goodbit = 0x00
+
+staticinherited
+
+

iostate for no flags

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::hex = 0x0010
+
+staticinherited
+
+

base 16 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::in = 0X20
+
+staticinherited
+
+

open for input

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::internal = 0x0004
+
+staticinherited
+
+

fill between sign/base prefix and number

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::left = 0x0001
+
+staticinherited
+
+

left adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::oct = 0x0020
+
+staticinherited
+
+

base 8 flag

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::out = 0X40
+
+staticinherited
+
+

open for output

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::right = 0x0002
+
+staticinherited
+
+

right adjust fields

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showbase = 0x0200
+
+staticinherited
+
+

use prefix 0X for hex and 0 for oct

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpoint = 0x0400
+
+staticinherited
+
+

always show '.' for floating numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::showpos = 0x0800
+
+staticinherited
+
+

show + sign for nonnegative numbers

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::skipws = 0x1000
+
+staticinherited
+
+

skip initial white space

+ +
+
+ +
+
+ + + + + +
+ + + + +
const openmode ios_base::trunc = 0X80
+
+staticinherited
+
+

truncate an existing stream when opening

+ +
+
+ +
+
+ + + + + +
+ + + + +
const fmtflags ios_base::uppercase = 0x4000
+
+staticinherited
+
+

use uppercase letters in number representations

+ +
+
+
The documentation for this class was generated from the following files:
    +
  • Arduino/libraries/SdFat/src/FatLib/ostream.h
  • +
  • Arduino/libraries/SdFat/src/FatLib/ostream.cpp
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/classostream__coll__graph.png b/libraries/SdFat/extras/html/classostream__coll__graph.png new file mode 100644 index 0000000..361df37 Binary files /dev/null and b/libraries/SdFat/extras/html/classostream__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/classostream__inherit__graph.png b/libraries/SdFat/extras/html/classostream__inherit__graph.png new file mode 100644 index 0000000..e83f407 Binary files /dev/null and b/libraries/SdFat/extras/html/classostream__inherit__graph.png differ diff --git a/libraries/SdFat/extras/html/closed.png b/libraries/SdFat/extras/html/closed.png new file mode 100644 index 0000000..98cc2c9 Binary files /dev/null and b/libraries/SdFat/extras/html/closed.png differ diff --git a/libraries/SdFat/extras/html/dir_000004_000006.html b/libraries/SdFat/extras/html/dir_000004_000006.html new file mode 100644 index 0000000..221cbdb --- /dev/null +++ b/libraries/SdFat/extras/html/dir_000004_000006.html @@ -0,0 +1,89 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src -> SdCard Relation + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+
+ + +
+ +
+ + +
+
+

src → SdCard Relation

File in Arduino/libraries/SdFat/srcIncludes file in Arduino/libraries/SdFat/src/SdCard
BlockDriver.hSdSpiCard.h
+ + + + diff --git a/libraries/SdFat/extras/html/dir_1281b15c327061056ab3b326e90c50cf.html b/libraries/SdFat/extras/html/dir_1281b15c327061056ab3b326e90c50cf.html new file mode 100644 index 0000000..bd9af57 --- /dev/null +++ b/libraries/SdFat/extras/html/dir_1281b15c327061056ab3b326e90c50cf.html @@ -0,0 +1,112 @@ + + + + + + +SdFat: Arduino/libraries/SdFat Directory Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+
+ + +
+ +
+ + +
+
+
+
SdFat Directory Reference
+
+
+
+Directory dependency graph for SdFat:
+
+
Arduino/libraries/SdFat
+ + + + + + +
+ + + + + + +

+Directories

directory  MainPage
 
directory  src
 
+
+ + + + diff --git a/libraries/SdFat/extras/html/dir_1281b15c327061056ab3b326e90c50cf_dep.png b/libraries/SdFat/extras/html/dir_1281b15c327061056ab3b326e90c50cf_dep.png new file mode 100644 index 0000000..15491fb Binary files /dev/null and b/libraries/SdFat/extras/html/dir_1281b15c327061056ab3b326e90c50cf_dep.png differ diff --git a/libraries/SdFat/extras/html/dir_481cc946b8a81b8d9363a4aad6201160.html b/libraries/SdFat/extras/html/dir_481cc946b8a81b8d9363a4aad6201160.html new file mode 100644 index 0000000..48ffe01 --- /dev/null +++ b/libraries/SdFat/extras/html/dir_481cc946b8a81b8d9363a4aad6201160.html @@ -0,0 +1,109 @@ + + + + + + +SdFat: Arduino/libraries Directory Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+
+ + +
+ +
+ + +
+
+
+
libraries Directory Reference
+
+
+
+Directory dependency graph for libraries:
+
+
Arduino/libraries
+ + + + + +
+ + + + +

+Directories

directory  SdFat
 
+
+ + + + diff --git a/libraries/SdFat/extras/html/dir_481cc946b8a81b8d9363a4aad6201160_dep.png b/libraries/SdFat/extras/html/dir_481cc946b8a81b8d9363a4aad6201160_dep.png new file mode 100644 index 0000000..c1c4249 Binary files /dev/null and b/libraries/SdFat/extras/html/dir_481cc946b8a81b8d9363a4aad6201160_dep.png differ diff --git a/libraries/SdFat/extras/html/dir_63fabcaba1b3b939579f46003349a6c5.html b/libraries/SdFat/extras/html/dir_63fabcaba1b3b939579f46003349a6c5.html new file mode 100644 index 0000000..68f2bcd --- /dev/null +++ b/libraries/SdFat/extras/html/dir_63fabcaba1b3b939579f46003349a6c5.html @@ -0,0 +1,108 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/MainPage Directory Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+
+ + +
+ +
+ + +
+
+
+
MainPage Directory Reference
+
+
+
+Directory dependency graph for MainPage:
+
+
Arduino/libraries/SdFat/MainPage
+ + + + +
+ + + + +

+Files

file  SdFatmainpage.h
 
+
+ + + + diff --git a/libraries/SdFat/extras/html/dir_63fabcaba1b3b939579f46003349a6c5_dep.png b/libraries/SdFat/extras/html/dir_63fabcaba1b3b939579f46003349a6c5_dep.png new file mode 100644 index 0000000..61b4195 Binary files /dev/null and b/libraries/SdFat/extras/html/dir_63fabcaba1b3b939579f46003349a6c5_dep.png differ diff --git a/libraries/SdFat/extras/html/dir_7e472674a7b7d2590a789f197241f95f.html b/libraries/SdFat/extras/html/dir_7e472674a7b7d2590a789f197241f95f.html new file mode 100644 index 0000000..7e61463 --- /dev/null +++ b/libraries/SdFat/extras/html/dir_7e472674a7b7d2590a789f197241f95f.html @@ -0,0 +1,176 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib Directory Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+
+ + +
+ +
+ + +
+
+
+
FatLib Directory Reference
+
+
+
+Directory dependency graph for FatLib:
+
+
Arduino/libraries/SdFat/src/FatLib
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Files

file  ArduinoFiles.h
 PrintFile class.
 
file  ArduinoStream.h
 ArduinoInStream and ArduinoOutStream classes.
 
file  BaseBlockDriver.h
 
file  bufstream.h
 ibufstream and obufstream classes
 
file  FatApiConstants.h
 
file  FatFile.cpp
 
file  FatFile.h
 FatFile class.
 
file  FatFileLFN.cpp
 
file  FatFilePrint.cpp
 
file  FatFileSFN.cpp
 
file  FatFileSystem.h
 FatFileSystem class.
 
file  FatLib.h
 
file  FatLibConfig.h
 configuration definitions
 
file  FatStructs.h
 FAT file structures.
 
file  FatVolume.cpp
 
file  FatVolume.h
 FatVolume class.
 
file  FmtNumber.cpp
 
file  FmtNumber.h
 
file  fstream.cpp
 
file  fstream.h
 fstream, ifstream, and ofstream classes
 
file  ios.h
 ios_base and ios classes
 
file  iostream.h
 iostream class
 
file  istream.cpp
 
file  istream.h
 istream class
 
file  ostream.cpp
 
file  ostream.h
 ostream class
 
file  StdioStream.cpp
 
file  StdioStream.h
 StdioStream class.
 
+
+ + + + diff --git a/libraries/SdFat/extras/html/dir_7e472674a7b7d2590a789f197241f95f_dep.png b/libraries/SdFat/extras/html/dir_7e472674a7b7d2590a789f197241f95f_dep.png new file mode 100644 index 0000000..0495e08 Binary files /dev/null and b/libraries/SdFat/extras/html/dir_7e472674a7b7d2590a789f197241f95f_dep.png differ diff --git a/libraries/SdFat/extras/html/dir_a70af2fb8f1edf8b7124f41d82dbf480.html b/libraries/SdFat/extras/html/dir_a70af2fb8f1edf8b7124f41d82dbf480.html new file mode 100644 index 0000000..d989928 --- /dev/null +++ b/libraries/SdFat/extras/html/dir_a70af2fb8f1edf8b7124f41d82dbf480.html @@ -0,0 +1,117 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/SdCard Directory Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+
+ + +
+ +
+ + +
+
+
+
SdCard Directory Reference
+
+
+
+Directory dependency graph for SdCard:
+
+
Arduino/libraries/SdFat/src/SdCard
+ + + + +
+ + + + + + + + + + + + + +

+Files

file  SdioCard.h
 
file  SdioTeensy.cpp
 
file  SdSpiCard.cpp
 
file  SdSpiCard.h
 SdSpiCard class for V2 SD/SDHC cards.
 
file  SdSpiCardEX.cpp
 
+
+ + + + diff --git a/libraries/SdFat/extras/html/dir_a70af2fb8f1edf8b7124f41d82dbf480_dep.png b/libraries/SdFat/extras/html/dir_a70af2fb8f1edf8b7124f41d82dbf480_dep.png new file mode 100644 index 0000000..74f6510 Binary files /dev/null and b/libraries/SdFat/extras/html/dir_a70af2fb8f1edf8b7124f41d82dbf480_dep.png differ diff --git a/libraries/SdFat/extras/html/dir_a991eec27578c865874ede3d8ec657c2.html b/libraries/SdFat/extras/html/dir_a991eec27578c865874ede3d8ec657c2.html new file mode 100644 index 0000000..5194bad --- /dev/null +++ b/libraries/SdFat/extras/html/dir_a991eec27578c865874ede3d8ec657c2.html @@ -0,0 +1,108 @@ + + + + + + +SdFat: Arduino Directory Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+
+ + +
+ +
+ + +
+
+
+
Arduino Directory Reference
+
+
+
+Directory dependency graph for Arduino:
+
+
Arduino
+ + + + +
+ + + + +

+Directories

directory  libraries
 
+
+ + + + diff --git a/libraries/SdFat/extras/html/dir_a991eec27578c865874ede3d8ec657c2_dep.png b/libraries/SdFat/extras/html/dir_a991eec27578c865874ede3d8ec657c2_dep.png new file mode 100644 index 0000000..d3e8747 Binary files /dev/null and b/libraries/SdFat/extras/html/dir_a991eec27578c865874ede3d8ec657c2_dep.png differ diff --git a/libraries/SdFat/extras/html/dir_c18d6c86f7b0afecac5c3a8a9885031e.html b/libraries/SdFat/extras/html/dir_c18d6c86f7b0afecac5c3a8a9885031e.html new file mode 100644 index 0000000..27a61b4 --- /dev/null +++ b/libraries/SdFat/extras/html/dir_c18d6c86f7b0afecac5c3a8a9885031e.html @@ -0,0 +1,136 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src Directory Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+
+ + +
+ +
+ + +
+
+
+
src Directory Reference
+
+
+
+Directory dependency graph for src:
+
+
Arduino/libraries/SdFat/src
+ + + + + + + +
+ + + + + + +

+Directories

directory  FatLib
 
directory  SdCard
 
+ + + + + + + + + + + + + + + + + + + + + +

+Files

file  BlockDriver.h
 Define block driver.
 
file  FreeStack.h
 FreeStack() function.
 
file  MinimumSerial.cpp
 
file  MinimumSerial.h
 Minimal AVR Serial driver.
 
file  SdFat.h
 SdFat class.
 
file  SdFatConfig.h
 configuration definitions
 
file  SysCall.h
 SysCall class.
 
+
+ + + + diff --git a/libraries/SdFat/extras/html/dir_c18d6c86f7b0afecac5c3a8a9885031e_dep.png b/libraries/SdFat/extras/html/dir_c18d6c86f7b0afecac5c3a8a9885031e_dep.png new file mode 100644 index 0000000..52514a4 Binary files /dev/null and b/libraries/SdFat/extras/html/dir_c18d6c86f7b0afecac5c3a8a9885031e_dep.png differ diff --git a/libraries/SdFat/extras/html/doc.png b/libraries/SdFat/extras/html/doc.png new file mode 100644 index 0000000..17edabf Binary files /dev/null and b/libraries/SdFat/extras/html/doc.png differ diff --git a/libraries/SdFat/extras/html/doxygen.css b/libraries/SdFat/extras/html/doxygen.css new file mode 100644 index 0000000..b2c94ac --- /dev/null +++ b/libraries/SdFat/extras/html/doxygen.css @@ -0,0 +1,1454 @@ +/* The standard CSS for doxygen 1.8.10 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px 6px; + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 20px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + diff --git a/libraries/SdFat/extras/html/doxygen.png b/libraries/SdFat/extras/html/doxygen.png new file mode 100644 index 0000000..3ff17d8 Binary files /dev/null and b/libraries/SdFat/extras/html/doxygen.png differ diff --git a/libraries/SdFat/extras/html/dynsections.js b/libraries/SdFat/extras/html/dynsections.js new file mode 100644 index 0000000..85e1836 --- /dev/null +++ b/libraries/SdFat/extras/html/dynsections.js @@ -0,0 +1,97 @@ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + +SdFat: File List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+ +
+
+ + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+
[detail level 123456]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
  Arduino
  libraries
  SdFat
  src
  FatLib
 ArduinoFiles.hPrintFile class
 ArduinoStream.hArduinoInStream and ArduinoOutStream classes
 bufstream.hibufstream and obufstream classes
 FatFile.hFatFile class
 FatFileSystem.hFatFileSystem class
 FatLibConfig.hConfiguration definitions
 FatStructs.hFAT file structures
 FatVolume.hFatVolume class
 fstream.hfstream, ifstream, and ofstream classes
 ios.hios_base and ios classes
 iostream.hiostream class
 istream.histream class
 ostream.hostream class
 StdioStream.hStdioStream class
  SdCard
 SdSpiCard.hSdSpiCard class for V2 SD/SDHC cards
 BlockDriver.hDefine block driver
 FreeStack.hFreeStack() function
 MinimumSerial.hMinimal AVR Serial driver
 SdFat.hSdFat class
 SdFatConfig.hConfiguration definitions
 SysCall.hSysCall class
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/folderclosed.png b/libraries/SdFat/extras/html/folderclosed.png new file mode 100644 index 0000000..bb8ab35 Binary files /dev/null and b/libraries/SdFat/extras/html/folderclosed.png differ diff --git a/libraries/SdFat/extras/html/folderopen.png b/libraries/SdFat/extras/html/folderopen.png new file mode 100644 index 0000000..d6c7f67 Binary files /dev/null and b/libraries/SdFat/extras/html/folderopen.png differ diff --git a/libraries/SdFat/extras/html/fstream_8h.html b/libraries/SdFat/extras/html/fstream_8h.html new file mode 100644 index 0000000..231b7b3 --- /dev/null +++ b/libraries/SdFat/extras/html/fstream_8h.html @@ -0,0 +1,143 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/fstream.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
fstream.h File Reference
+
+
+ +

fstream, ifstream, and ofstream classes +More...

+
#include "FatFile.h"
+#include "iostream.h"
+
+Include dependency graph for fstream.h:
+
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + +

+Classes

class  FatStreamBase
 Base class for C++ style streams. More...
 
class  fstream
 file input/output stream. More...
 
class  ifstream
 file input stream. More...
 
class  ofstream
 file output stream. More...
 
+

Detailed Description

+

fstream, ifstream, and ofstream classes

+
+ + + + diff --git a/libraries/SdFat/extras/html/fstream_8h__incl.png b/libraries/SdFat/extras/html/fstream_8h__incl.png new file mode 100644 index 0000000..a0b3642 Binary files /dev/null and b/libraries/SdFat/extras/html/fstream_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/functions.html b/libraries/SdFat/extras/html/functions.html new file mode 100644 index 0000000..5181cdd --- /dev/null +++ b/libraries/SdFat/extras/html/functions.html @@ -0,0 +1,159 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- a -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_b.html b/libraries/SdFat/extras/html/functions_b.html new file mode 100644 index 0000000..a36bf55 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_b.html @@ -0,0 +1,212 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- b -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_c.html b/libraries/SdFat/extras/html/functions_c.html new file mode 100644 index 0000000..a13f5bb --- /dev/null +++ b/libraries/SdFat/extras/html/functions_c.html @@ -0,0 +1,244 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- c -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_d.html b/libraries/SdFat/extras/html/functions_d.html new file mode 100644 index 0000000..851ba0b --- /dev/null +++ b/libraries/SdFat/extras/html/functions_d.html @@ -0,0 +1,181 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- d -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_e.html b/libraries/SdFat/extras/html/functions_e.html new file mode 100644 index 0000000..eb701a0 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_e.html @@ -0,0 +1,184 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- e -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_enum.html b/libraries/SdFat/extras/html/functions_enum.html new file mode 100644 index 0000000..23ba8a6 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_enum.html @@ -0,0 +1,107 @@ + + + + + + +SdFat: Class Members - Enumerations + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_eval.html b/libraries/SdFat/extras/html/functions_eval.html new file mode 100644 index 0000000..b9c32f7 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_eval.html @@ -0,0 +1,113 @@ + + + + + + +SdFat: Class Members - Enumerator + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_f.html b/libraries/SdFat/extras/html/functions_f.html new file mode 100644 index 0000000..6e20235 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_f.html @@ -0,0 +1,293 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- f -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func.html b/libraries/SdFat/extras/html/functions_func.html new file mode 100644 index 0000000..8af25a3 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func.html @@ -0,0 +1,143 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_b.html b/libraries/SdFat/extras/html/functions_func_b.html new file mode 100644 index 0000000..d73052a --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_b.html @@ -0,0 +1,160 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- b -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_c.html b/libraries/SdFat/extras/html/functions_func_c.html new file mode 100644 index 0000000..74f5567 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_c.html @@ -0,0 +1,198 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- c -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_d.html b/libraries/SdFat/extras/html/functions_func_d.html new file mode 100644 index 0000000..4860e75 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_d.html @@ -0,0 +1,164 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- d -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_e.html b/libraries/SdFat/extras/html/functions_func_e.html new file mode 100644 index 0000000..529e680 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_e.html @@ -0,0 +1,165 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- e -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_f.html b/libraries/SdFat/extras/html/functions_func_f.html new file mode 100644 index 0000000..ccc6ecf --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_f.html @@ -0,0 +1,226 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- f -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_g.html b/libraries/SdFat/extras/html/functions_func_g.html new file mode 100644 index 0000000..d534db0 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_g.html @@ -0,0 +1,161 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- g -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_h.html b/libraries/SdFat/extras/html/functions_func_h.html new file mode 100644 index 0000000..105bee3 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_h.html @@ -0,0 +1,134 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- h -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_i.html b/libraries/SdFat/extras/html/functions_func_i.html new file mode 100644 index 0000000..2629982 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_i.html @@ -0,0 +1,202 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- i -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_l.html b/libraries/SdFat/extras/html/functions_func_l.html new file mode 100644 index 0000000..1100063 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_l.html @@ -0,0 +1,144 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- l -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_m.html b/libraries/SdFat/extras/html/functions_func_m.html new file mode 100644 index 0000000..8358b38 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_m.html @@ -0,0 +1,135 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- m -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_n.html b/libraries/SdFat/extras/html/functions_func_n.html new file mode 100644 index 0000000..d146086 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_n.html @@ -0,0 +1,134 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- n -

    +
  • name() +: File +
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_o.html b/libraries/SdFat/extras/html/functions_func_o.html new file mode 100644 index 0000000..d3b3fc0 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_o.html @@ -0,0 +1,169 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- o -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_p.html b/libraries/SdFat/extras/html/functions_func_p.html new file mode 100644 index 0000000..0bf6965 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_p.html @@ -0,0 +1,195 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- p -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_r.html b/libraries/SdFat/extras/html/functions_func_r.html new file mode 100644 index 0000000..7fa6dff --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_r.html @@ -0,0 +1,210 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- r -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_s.html b/libraries/SdFat/extras/html/functions_func_s.html new file mode 100644 index 0000000..11dd4b9 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_s.html @@ -0,0 +1,210 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- s -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_t.html b/libraries/SdFat/extras/html/functions_func_t.html new file mode 100644 index 0000000..80cb77c --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_t.html @@ -0,0 +1,148 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- t -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_u.html b/libraries/SdFat/extras/html/functions_func_u.html new file mode 100644 index 0000000..5aa7794 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_u.html @@ -0,0 +1,137 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- u -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_v.html b/libraries/SdFat/extras/html/functions_func_v.html new file mode 100644 index 0000000..4748e10 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_v.html @@ -0,0 +1,143 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- v -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_w.html b/libraries/SdFat/extras/html/functions_func_w.html new file mode 100644 index 0000000..d8f9805 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_w.html @@ -0,0 +1,165 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- w -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_func_y.html b/libraries/SdFat/extras/html/functions_func_y.html new file mode 100644 index 0000000..7da89ff --- /dev/null +++ b/libraries/SdFat/extras/html/functions_func_y.html @@ -0,0 +1,134 @@ + + + + + + +SdFat: Class Members - Functions + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- y -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_g.html b/libraries/SdFat/extras/html/functions_g.html new file mode 100644 index 0000000..2e27d12 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_g.html @@ -0,0 +1,165 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- g -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_h.html b/libraries/SdFat/extras/html/functions_h.html new file mode 100644 index 0000000..1d3f14e --- /dev/null +++ b/libraries/SdFat/extras/html/functions_h.html @@ -0,0 +1,148 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- h -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_i.html b/libraries/SdFat/extras/html/functions_i.html new file mode 100644 index 0000000..5d8d8ea --- /dev/null +++ b/libraries/SdFat/extras/html/functions_i.html @@ -0,0 +1,212 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- i -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_j.html b/libraries/SdFat/extras/html/functions_j.html new file mode 100644 index 0000000..90eab97 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_j.html @@ -0,0 +1,136 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- j -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_l.html b/libraries/SdFat/extras/html/functions_l.html new file mode 100644 index 0000000..f0bacce --- /dev/null +++ b/libraries/SdFat/extras/html/functions_l.html @@ -0,0 +1,166 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- l -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_m.html b/libraries/SdFat/extras/html/functions_m.html new file mode 100644 index 0000000..45d8cb4 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_m.html @@ -0,0 +1,153 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- m -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_n.html b/libraries/SdFat/extras/html/functions_n.html new file mode 100644 index 0000000..90488c6 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_n.html @@ -0,0 +1,148 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- n -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_o.html b/libraries/SdFat/extras/html/functions_o.html new file mode 100644 index 0000000..89bd98b --- /dev/null +++ b/libraries/SdFat/extras/html/functions_o.html @@ -0,0 +1,189 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- o -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_p.html b/libraries/SdFat/extras/html/functions_p.html new file mode 100644 index 0000000..242d53d --- /dev/null +++ b/libraries/SdFat/extras/html/functions_p.html @@ -0,0 +1,206 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- p -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_r.html b/libraries/SdFat/extras/html/functions_r.html new file mode 100644 index 0000000..53beed9 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_r.html @@ -0,0 +1,233 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- r -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_s.html b/libraries/SdFat/extras/html/functions_s.html new file mode 100644 index 0000000..1477592 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_s.html @@ -0,0 +1,259 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- s -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_t.html b/libraries/SdFat/extras/html/functions_t.html new file mode 100644 index 0000000..7937c10 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_t.html @@ -0,0 +1,170 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- t -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_type.html b/libraries/SdFat/extras/html/functions_type.html new file mode 100644 index 0000000..9abee0f --- /dev/null +++ b/libraries/SdFat/extras/html/functions_type.html @@ -0,0 +1,122 @@ + + + + + + +SdFat: Class Members - Typedefs + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_u.html b/libraries/SdFat/extras/html/functions_u.html new file mode 100644 index 0000000..3a7854b --- /dev/null +++ b/libraries/SdFat/extras/html/functions_u.html @@ -0,0 +1,144 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- u -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_v.html b/libraries/SdFat/extras/html/functions_v.html new file mode 100644 index 0000000..2510426 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_v.html @@ -0,0 +1,152 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- v -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_vars.html b/libraries/SdFat/extras/html/functions_vars.html new file mode 100644 index 0000000..1eb0b1d --- /dev/null +++ b/libraries/SdFat/extras/html/functions_vars.html @@ -0,0 +1,623 @@ + + + + + + +SdFat: Class Members - Variables + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- j -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+ + +

- w -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_w.html b/libraries/SdFat/extras/html/functions_w.html new file mode 100644 index 0000000..3159313 --- /dev/null +++ b/libraries/SdFat/extras/html/functions_w.html @@ -0,0 +1,169 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- w -

+
+ + + + diff --git a/libraries/SdFat/extras/html/functions_y.html b/libraries/SdFat/extras/html/functions_y.html new file mode 100644 index 0000000..b9a885b --- /dev/null +++ b/libraries/SdFat/extras/html/functions_y.html @@ -0,0 +1,135 @@ + + + + + + +SdFat: Class Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- y -

+
+ + + + diff --git a/libraries/SdFat/extras/html/globals.html b/libraries/SdFat/extras/html/globals.html new file mode 100644 index 0000000..71269bb --- /dev/null +++ b/libraries/SdFat/extras/html/globals.html @@ -0,0 +1,559 @@ + + + + + + +SdFat: File Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented file members with links to the documentation:
+ +

- _ -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- h -

+ + +

- i -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- u -

+ + +

- w -

+
+ + + + diff --git a/libraries/SdFat/extras/html/globals_defs.html b/libraries/SdFat/extras/html/globals_defs.html new file mode 100644 index 0000000..17b2f9c --- /dev/null +++ b/libraries/SdFat/extras/html/globals_defs.html @@ -0,0 +1,251 @@ + + + + + + +SdFat: File Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- i -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- s -

+ + +

- u -

+ + +

- w -

+
+ + + + diff --git a/libraries/SdFat/extras/html/globals_func.html b/libraries/SdFat/extras/html/globals_func.html new file mode 100644 index 0000000..0332d80 --- /dev/null +++ b/libraries/SdFat/extras/html/globals_func.html @@ -0,0 +1,291 @@ + + + + + + +SdFat: File Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- b -

    +
  • boolalpha() +: ios.h +
  • +
+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- h -

+ + +

- i -

    +
  • internal() +: ios.h +
  • +
+ + +

- l -

+ + +

- n -

    +
  • noboolalpha() +: ios.h +
  • +
  • noshowbase() +: ios.h +
  • +
  • noshowpoint() +: ios.h +
  • +
  • noshowpos() +: ios.h +
  • +
  • noskipws() +: ios.h +
  • +
  • nouppercase() +: ios.h +
  • +
+ + +

- o -

+ + +

- r -

+ + +

- s -

+ + +

- u -

    +
  • uppercase() +: ios.h +
  • +
+ + +

- w -

+
+ + + + diff --git a/libraries/SdFat/extras/html/globals_type.html b/libraries/SdFat/extras/html/globals_type.html new file mode 100644 index 0000000..85cf48f --- /dev/null +++ b/libraries/SdFat/extras/html/globals_type.html @@ -0,0 +1,132 @@ + + + + + + +SdFat: File Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/libraries/SdFat/extras/html/globals_vars.html b/libraries/SdFat/extras/html/globals_vars.html new file mode 100644 index 0000000..3164f34 --- /dev/null +++ b/libraries/SdFat/extras/html/globals_vars.html @@ -0,0 +1,270 @@ + + + + + + +SdFat: File Members + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- _ -

+ + +

- b -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- l -

+ + +

- s -

+ + +

- u -

+
+ + + + diff --git a/libraries/SdFat/extras/html/graph_legend.html b/libraries/SdFat/extras/html/graph_legend.html new file mode 100644 index 0000000..9261ac4 --- /dev/null +++ b/libraries/SdFat/extras/html/graph_legend.html @@ -0,0 +1,152 @@ + + + + + + +SdFat: Graph Legend + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + +
+ +
+
+ + +
+ +
+ +
+
+
Graph Legend
+
+
+

This page explains how to interpret the graphs that are generated by doxygen.

+

Consider the following example:

1 /*! Invisible class because of truncation */
+
2 class Invisible { };
+
3 
+
4 /*! Truncated class, inheritance relation is hidden */
+
5 class Truncated : public Invisible { };
+
6 
+
7 /* Class not documented with doxygen comments */
+
8 class Undocumented { };
+
9 
+
10 /*! Class that is inherited using public inheritance */
+
11 class PublicBase : public Truncated { };
+
12 
+
13 /*! A template class */
+
14 template<class T> class Templ { };
+
15 
+
16 /*! Class that is inherited using protected inheritance */
+
17 class ProtectedBase { };
+
18 
+
19 /*! Class that is inherited using private inheritance */
+
20 class PrivateBase { };
+
21 
+
22 /*! Class that is used by the Inherited class */
+
23 class Used { };
+
24 
+
25 /*! Super class that inherits a number of other classes */
+
26 class Inherited : public PublicBase,
+
27  protected ProtectedBase,
+
28  private PrivateBase,
+
29  public Undocumented,
+
30  public Templ<int>
+
31 {
+
32  private:
+
33  Used *m_usedClass;
+
34 };
+

This will result in the following graph:

+
+ +
+

The boxes in the above graph have the following meaning:

+
    +
  • +A filled gray box represents the struct or class for which the graph is generated.
  • +
  • +A box with a black border denotes a documented struct or class.
  • +
  • +A box with a gray border denotes an undocumented struct or class.
  • +
  • +A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
  • +
+

The arrows have the following meaning:

+
    +
  • +A dark blue arrow is used to visualize a public inheritance relation between two classes.
  • +
  • +A dark green arrow is used for protected inheritance.
  • +
  • +A dark red arrow is used for private inheritance.
  • +
  • +A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible.
  • +
  • +A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance.
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/graph_legend.png b/libraries/SdFat/extras/html/graph_legend.png new file mode 100644 index 0000000..c0d711b Binary files /dev/null and b/libraries/SdFat/extras/html/graph_legend.png differ diff --git a/libraries/SdFat/extras/html/hierarchy.html b/libraries/SdFat/extras/html/hierarchy.html new file mode 100644 index 0000000..d915409 --- /dev/null +++ b/libraries/SdFat/extras/html/hierarchy.html @@ -0,0 +1,163 @@ + + + + + + +SdFat: Class Hierarchy + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Hierarchy
+
+
+
+

Go to the graphical class hierarchy

+This inheritance list is sorted roughly, but not completely, alphabetically:
+
[detail level 12345]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 CBaseBlockDriverBase block driver
 CSdioCardRaw SDIO access to SD and SDHC flash memory cards
 CbiosParmBlockBIOS parameter block
 Ccache_tCache for an raw data block
 CdirectoryEntryFAT short directory entry
 Cfat32_bootBoot sector for a FAT32 volume
 Cfat32_fsinfoFSINFO sector for a FAT32 volume
 Cfat_bootBoot sector for a FAT12/FAT16 volume
 CFatCacheBlock cache
 CFatFileBasic file class
 CFatStreamBaseBase class for C++ style streams
 CfstreamFile input/output stream
 CifstreamFile input stream
 CofstreamFile output stream
 CFileArduino SD.h style File API
 CPrintFileFatFile with Print
 CSdFileClass for backward compatibility
 CSdBaseFileClass for backward compatibility
 CStdioStreamStdioStream implements a minimal stdio stream
 CFatPos_tInternal type for file position - do not use in user apps
 CFatVolumeAccess FAT16 and FAT32 volumes on raw file devices
 CFatFileSystemIntegration class for the FatLib library
 CSdFileSystem< SdDriverClass >Virtual base class for SdFat library
 CSdFileSystem< SdioCard >
 CSdFatSdioSdFat class using SDIO
 CSdFileSystem< SdSpiCard >
 CSdFatMain file system class for SdFat library
 CSdFatSoftSpi< MisoPin, MosiPin, SckPin >SdFat class using software SPI
 CSdFileSystem< SdSpiCardEX >
 CSdFatEXSdFat class with extended SD I/O
 CSdFatSoftSpiEX< MisoPin, MosiPin, SckPin >SdFat class using software SPI and extended SD I/O
 Cfname_tInternal type for Short File Name - do not use in user apps
 Cios_baseBase class for all streams
 CiosError and state information for all streams
 CFatStreamBaseBase class for C++ style streams
 CistreamInput Stream
 CibufstreamParse a char string
 CArduinoInStreamInput stream for Arduino Stream objects
 CifstreamFile input stream
 CiostreamInput/Output stream
 CfstreamFile input/output stream
 CostreamOutput Stream
 CArduinoOutStreamOutput stream for Arduino Print objects
 CiostreamInput/Output stream
 CobufstreamFormat a char string
 CofstreamFile output stream
 ClongDirectoryEntryFAT long directory entry
 CmasterBootRecordMaster Boot Record
 CpartitionTableMBR partition table entry
 CPrint
 CMinimumSerialMini serial class for the SdFat library
 CPrintFileFatFile with Print
 CSdSpiCardRaw access to SD and SDHC flash memory cards via SPI protocol
 CSd2CardRaw access to SD and SDHC card using default SPI library
 CSdSpiCardEXExtended SD I/O block driver
 CsetfillType for setfill manipulator
 CsetprecisionType for setprecision manipulator
 CsetwType for setw manipulator
 CStream
 CFileArduino SD.h style File API
 CSysCallSysCall - Class to wrap system calls
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/index.html b/libraries/SdFat/extras/html/index.html new file mode 100644 index 0000000..5051d70 --- /dev/null +++ b/libraries/SdFat/extras/html/index.html @@ -0,0 +1,255 @@ + + + + + + +SdFat: Arduino SdFat Library + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + +
+ +
+
+ + +
+ +
+ +
+
+
Arduino SdFat Library
+
+
+
Copyright © 2012, 2013, 2014, 2015, 2016 by William Greiman

+Introduction

+

The Arduino SdFat Library is a minimal implementation of FAT16 and FAT32 file systems on SD flash memory cards. Standard SD and high capacity SDHC cards are supported.

+

Experimental support for FAT12 can be enabled by setting FAT12_SUPPORT nonzero in SdFatConfig.h.

+

The SdFat library supports Long File Names or short 8.3 names. Edit the SdFatConfig.h file to select short or long file names.

+

The main classes in SdFat are SdFat, SdFatEX, SdFatSoftSpi, SdFatSoftSpiEX, SdBaseFile, SdFile, File, StdioStream, fstream, ifstream, and ofstream.

+

The SdFat, SdFatEX, SdFatSoftSpi and SdFatSoftSpiEX classes maintain a FAT volume, a current working directory, and simplify initialization of other classes. The SdFat and SdFatEX classes uses a fast custom hardware SPI implementation. The SdFatSoftSpi and SdFatSoftSpiEX classes uses software SPI.

+

the SdFatEX and SdFatSoftSpiEX use extended multi-block I/O for enhanced performance. These classes must have exclusive use of the SPI bus.

+

The SdBaseFile class provides basic file access functions such as open(), binary read(), binary write(), close(), remove(), and sync(). SdBaseFile is the smallest file class.

+

The SdFile class has all the SdBaseFile class functions plus the Arduino Print class functions.

+

The File class has all the SdBaseFile functions plus the functions in the Arduino SD.h File class. This provides compatibility with the Arduino SD.h library.

+

The StdioStream class implements functions similar to Linux/Unix standard buffered input/output.

+

The fstream class implements C++ iostreams for both reading and writing text files.

+

The ifstream class implements C++ iostreams for reading text files.

+

The ofstream class implements C++ iostreams for writing text files.

+

The classes ifstream, ofstream, istream, and ostream follow the C++ iostream standard when possible.

+

There are many tutorials and much documentation about using C++ iostreams on the web.

+

http://www.cplusplus.com/ is a good C++ site for learning iostreams.

+

The classes ibufstream and obufstream format and parse character strings in memory buffers.

+

the classes ArduinoInStream and ArduinoOutStream provide iostream functions for Serial, LiquidCrystal, and other devices.

+

A number of example are provided in the SdFat/examples folder. These were developed to test SdFat and illustrate its use.

+

+Installation

+

You must manually install SdFat by copying the SdFat folder from the download package to the Arduino libraries folder in your sketch folder.

+

See the Manual installation section of this guide.

+

http://arduino.cc/en/Guide/Libraries

+

+SdFat Configuration

+

Several configuration options may be changed by editing the SdFatConfig.h file in the SdFat folder.

+

Set USE_LONG_FILE_NAMES nonzero to enable Long File Names. By default, Long File Names are enabled. For the leanest fastest library disable Long File Names. Long File names require extra flash but no extra RAM. Opening Long File Names can be slower than opening Short File Names. Data read and write performance is not changed by the type of File Name.

+

If the symbol ENABLE_EXTENDED_TRANSFER_CLASS is nonzero, the class SdFatEX will be defined. If the symbol ENABLE_SOFTWARE_SPI_CLASS is also nonzero, the class SdFatSoftSpiEX will be defined. These classes used extended multi-block SD I/O for better performance. the SPI bus may not be shared with other devices in this mode.

+

Set USE_STANDARD_SPI_LIBRARY and ENABLE_SOFTWARE_SPI_CLASS to enable various SPI options. set USE_STANDARD_SPI_LIBRARY to use the standard Arduino SPI library. set ENABLE_SOFTWARE_SPI_CLASS to enable the SdFatSoftSpi class which uses software SPI.

+

To enable SD card CRC checking set USE_SD_CRC nonzero.

+

Set FAT12_SUPPORT nonzero to enable use of FAT12 volumes. FAT12 has not been well tested and requires additional flash.

+

+Paths and Working Directories

+

Relative paths in SdFat are resolved in a manner similar to Windows.

+

Each instance of SdFat has a current directory. In SdFat this directory is called the volume working directory, vwd. Initially this directory is the root directory for the volume.

+

The volume working directory is changed by calling SdFat::chdir(path).

+

The call sd.chdir("/2014") will change the volume working directory for sd to "/2014", assuming "/2014" exists.

+

Relative paths for SdFat member functions are resolved by starting at the volume working directory.

+

For example, the call sd.mkdir("April") will create the directory "/2014/April" assuming the volume working directory is "/2014".

+

SdFat has a current working directory, cwd, that is used to resolve paths for file.open() calls.

+

For a single SD card the current working directory is always the volume working directory for that card.

+

For multiple SD cards the current working directory is set to the volume working directory of a card by calling the SdFat::chvol() member function. The chvol() call is like the Windows <drive letter>: command.

+

The call sd2.chvol() will set the current working directory to the volume working directory for sd2.

+

If the volume working directory for sd2 is "/music" the call

+

file.open("BigBand.wav", O_READ);

+

will then open "/music/BigBand.wav" on sd2.

+

The following functions are used to change or get current directories. See the html documentation for more information.

bool SdFat::chdir(bool set_cwd = false);
+
bool SdFat::chdir(const char* path, bool set_cwd = false);
+
void SdFat::chvol();
+ + +

+SD\SDHC Cards

+

Arduinos access SD cards using the cards SPI protocol. PCs, Macs, and most consumer devices use the 4-bit parallel SD protocol. A card that functions well on A PC or Mac may not work well on the Arduino.

+

Most cards have good SPI read performance but cards vary widely in SPI write performance. Write performance is limited by how efficiently the card manages internal erase/remapping operations. The Arduino cannot optimize writes to reduce erase operations because of its limit RAM.

+

SanDisk cards generally have good write performance. They seem to have more internal RAM buffering than other cards and therefore can limit the number of flash erase operations that the Arduino forces due to its limited RAM.

+

+Hardware Configuration

+

SdFat was developed using an Adafruit Industries Data Logging Shield.

+

The hardware interface to the SD card should not use a resistor based level shifter. SdFat sets the SPI bus frequency to 8 MHz which results in signal rise times that are too slow for the edge detectors in many newer SD card controllers when resistor voltage dividers are used.

+

The 5 to 3.3 V level shifter for 5 V Arduinos should be IC based like the 74HC4050N based circuit shown in the file SdLevel.png. The Adafruit Wave Shield uses a 74AHC125N. Gravitech sells SD and MicroSD Card Adapters based on the 74LCX245.

+

If you are using a resistor based level shifter and are having problems try setting the SPI bus frequency to 4 MHz. This can be done by using card.init(SPI_HALF_SPEED) to initialize the SD card.

+

A feature to use software SPI is available. Software SPI is slower than hardware SPI but allows any digital pins to be used. See SdFatConfig.h for software SPI definitions.

+

+Bugs and Comments

+

If you wish to report bugs or have comments, send email to fat16.nosp@m.lib@.nosp@m.sbcgl.nosp@m.obal.nosp@m..net. If possible, include a simple program that illustrates the bug or problem.

+

+Troubleshooting

+

The two example programs QuickStart, and SdInfo are useful for troubleshooting.

+

A message like this from SdInfo with erorCode 0X1 indicates the SD card is not seen by SdFat. This is often caused by a wiring error and reformatting the card will not solve the problem.

+cardBegin failed
+SD errorCode: 0X1
+SD errorData: 0XFF
+

Here is a similar message from QuickStart:

+SD initialization failed.
+Do not reformat the card!
+Is the card correctly inserted?
+Is chipSelect set to the correct value?
+Does another SPI device need to be disabled?
+Is there a wiring/soldering problem?
errorCode: 0x1, errorData: 0xff
+

Here is a message from QuickStart that indicates a formatting problem:

+Card successfully initialized.
+Can't find a valid FAT16/FAT32 partition.
+Try reformatting the card.  For best results use
+the SdFormatter program in SdFat/examples or download
+and use SDFormatter from www.sdcard.org/downloads.
+

The best source of recent information and help is the Arduino forum.

+

http://arduino.cc/forum/

+

Also search the Adafruit forum.

+

http://forums.adafruit.com/

+

If you are using a Teensy try.

+

http://forum.pjrc.com/forum.php

+

+SdFat Usage

+

SdFat supports Long File Names. Long names in SdFat are limited to 7-bit ASCII characters in the range 0X20 - 0XFE The following are reserved characters:

    +
  • +< (less than)
  • +
  • +> (greater than)
  • +
  • +: (colon)
  • +
  • +" (double quote)
  • +
  • +/ (forward slash)
  • +
  • +\ (backslash)
  • +
  • +| (vertical bar or pipe)
  • +
  • +? (question mark)
  • +
  • +* (asterisk)
  • +
+

SdFat uses a slightly restricted form of short names. Short names are limited to 8 characters followed by an optional period (.) and extension of up to 3 characters. The characters may be any combination of letters and digits. The following special characters are also allowed:

+

$ % ' - _ @ ~ ` ! ( ) { } ^ # &

+

Short names are always converted to upper case and their original case value is lost. Files that have a base-name where all characters have the same case and an extension where all characters have the same case will display properly. Examples this type name are UPPER.low, lower.TXT, UPPER.TXT, and lower.txt.

+

An application which writes to a file using print(), println() or write() must close the file or call sync() at the appropriate time to force data and directory information to be written to the SD Card.

+

Applications must use care calling sync() sync() since 2048 bytes of I/O is required to update file and directory information. This includes writing the current data block, reading the block that contains the directory entry for update, writing the directory block back and reading back the current data block.

+

It is possible to open a file with two or more instances of a file object. A file may be corrupted if data is written to the file by more than one instance of a file object.

+

+How to format SD Cards as FAT Volumes

+

The best way to restore an SD card's format on a PC or Mac is to use SDFormatter which can be downloaded from:

+

http://www.sdcard.org/downloads

+

A formatter program, SdFormatter.ino, is included in the SdFat/examples/SdFormatter directory. This program attempts to emulate SD Association's SDFormatter.

+

SDFormatter aligns flash erase boundaries with file system structures which reduces write latency and file system overhead.

+

The PC/Mac SDFormatter does not have an option for FAT type so it may format very small cards as FAT12. Use the SdFat formatter to force FAT16 formatting of small cards.

+

Do not format the SD card with an OS utility, OS utilities do not format SD cards in conformance with the SD standard.

+

You should use a freshly formatted SD card for best performance. FAT file systems become slower if many files have been created and deleted. This is because the directory entry for a deleted file is marked as deleted, but is not deleted. When a new file is created, these entries must be scanned before creating the file. Also files can become fragmented which causes reads and writes to be slower.

+

+Examples

+

A number of examples are provided in the SdFat/examples folder. See the html documentation for a list.

+

To access these examples from the Arduino development environment go to: File -> Examples -> SdFat -> <program Name>

+

Compile, upload to your Arduino and click on Serial Monitor to run the example.

+

Here is a list:

+

AnalogBinLogger - Fast AVR ADC logger - see the AnalogBinLoggerExtras folder.

+

bench - A read/write benchmark.

+

dataLogger - A simple modifiable data logger.

+

DirectoryFunctions - Demo of chdir(), ls(), mkdir(), and rmdir().

+

fgets - Demo of the fgets read line/string function.

+

formating - Print a table with various formatting options.

+

getline - Example of getline from section 27.7.1.3 of the C++ standard.

+

LongFileName - Example use of openNext, printName, and open by index.

+

LowLatencyLogger - A data logger for higher data rates. ADC version.

+

LowLatencyLoggerADXL345 - A data logger for higher data rates. ADXL345 SPI.

+

LowLatencyLoggerMPU6050 - A data logger for higher data rates. MPU6050 I2C.

+

OpenNext - Open all files in the root dir and print their filename.

+

PrintBenchmark - A simple benchmark for printing to a text file.

+

QuickStart - A program to quickly test your SD card and SD shield/module.

+

RawWrite - A test of raw write functions for contiguous files.

+

ReadCsv - Function to read a CSV text file one field at a time.

+

ReadCsvStream - Read a comma-separated value file using iostream extractors.

+

ReadCsvArray - Read a two dimensional array from a CSV file.

+

ReadWrite - Compatibility test of Arduino SD ReadWrite example.

+

rename - A demo of SdFat::rename(old, new) and SdFile::rename(dirFile, newPath).

+

SdFormatter - This program will format an SD or SDHC card.

+

SoftwareSpi - Simple demonstration of the SdFatSoftSpi template class.

+

SdInfo - Initialize an SD card and analyze its structure for trouble shooting.

+

StdioBench - Demo and test of stdio style stream.

+

Timestamp - Sets file create, modify, and access timestamps.

+

TwoCards - Example using two SD cards.

+

VolumeFreeSpace - Demonstrate the freeClusterCount() call.

+

wipe - Example to wipe all data from an already formatted SD.

+
+ + + + diff --git a/libraries/SdFat/extras/html/inherit_graph_0.png b/libraries/SdFat/extras/html/inherit_graph_0.png new file mode 100644 index 0000000..f0e85e4 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_0.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_1.png b/libraries/SdFat/extras/html/inherit_graph_1.png new file mode 100644 index 0000000..aaa3349 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_1.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_10.png b/libraries/SdFat/extras/html/inherit_graph_10.png new file mode 100644 index 0000000..93805fc Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_10.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_11.png b/libraries/SdFat/extras/html/inherit_graph_11.png new file mode 100644 index 0000000..aeccc52 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_11.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_12.png b/libraries/SdFat/extras/html/inherit_graph_12.png new file mode 100644 index 0000000..6e9deb2 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_12.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_13.png b/libraries/SdFat/extras/html/inherit_graph_13.png new file mode 100644 index 0000000..27cef82 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_13.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_14.png b/libraries/SdFat/extras/html/inherit_graph_14.png new file mode 100644 index 0000000..1a576ca Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_14.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_15.png b/libraries/SdFat/extras/html/inherit_graph_15.png new file mode 100644 index 0000000..abcb0be Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_15.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_16.png b/libraries/SdFat/extras/html/inherit_graph_16.png new file mode 100644 index 0000000..adae800 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_16.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_17.png b/libraries/SdFat/extras/html/inherit_graph_17.png new file mode 100644 index 0000000..6815203 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_17.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_18.png b/libraries/SdFat/extras/html/inherit_graph_18.png new file mode 100644 index 0000000..5092885 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_18.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_19.png b/libraries/SdFat/extras/html/inherit_graph_19.png new file mode 100644 index 0000000..cb756b5 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_19.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_2.png b/libraries/SdFat/extras/html/inherit_graph_2.png new file mode 100644 index 0000000..1638251 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_2.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_3.png b/libraries/SdFat/extras/html/inherit_graph_3.png new file mode 100644 index 0000000..26465d5 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_3.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_4.png b/libraries/SdFat/extras/html/inherit_graph_4.png new file mode 100644 index 0000000..9efa23d Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_4.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_5.png b/libraries/SdFat/extras/html/inherit_graph_5.png new file mode 100644 index 0000000..f2d4b5e Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_5.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_6.png b/libraries/SdFat/extras/html/inherit_graph_6.png new file mode 100644 index 0000000..24c8f4d Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_6.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_7.png b/libraries/SdFat/extras/html/inherit_graph_7.png new file mode 100644 index 0000000..ab58880 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_7.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_8.png b/libraries/SdFat/extras/html/inherit_graph_8.png new file mode 100644 index 0000000..9ac4458 Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_8.png differ diff --git a/libraries/SdFat/extras/html/inherit_graph_9.png b/libraries/SdFat/extras/html/inherit_graph_9.png new file mode 100644 index 0000000..d79483f Binary files /dev/null and b/libraries/SdFat/extras/html/inherit_graph_9.png differ diff --git a/libraries/SdFat/extras/html/inherits.html b/libraries/SdFat/extras/html/inherits.html new file mode 100644 index 0000000..b418518 --- /dev/null +++ b/libraries/SdFat/extras/html/inherits.html @@ -0,0 +1,232 @@ + + + + + + +SdFat: Class Hierarchy + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Hierarchy
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+
+ + + + diff --git a/libraries/SdFat/extras/html/ios_8h.html b/libraries/SdFat/extras/html/ios_8h.html new file mode 100644 index 0000000..237c2bf --- /dev/null +++ b/libraries/SdFat/extras/html/ios_8h.html @@ -0,0 +1,745 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/ios.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ios.h File Reference
+
+
+ +

ios_base and ios classes +More...

+
#include "FatFile.h"
+
+Include dependency graph for ios.h:
+
+
+ + + + + + + + + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + + + +
+
+ + + + + + + +

+Classes

class  ios
 Error and state information for all streams. More...
 
class  ios_base
 Base class for all streams. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

ios_baseboolalpha (ios_base &str)
 
ios_basedec (ios_base &str)
 
ios_basehex (ios_base &str)
 
ios_baseinternal (ios_base &str)
 
ios_baseleft (ios_base &str)
 
ios_basenoboolalpha (ios_base &str)
 
ios_basenoshowbase (ios_base &str)
 
ios_basenoshowpoint (ios_base &str)
 
ios_basenoshowpos (ios_base &str)
 
ios_basenoskipws (ios_base &str)
 
ios_basenouppercase (ios_base &str)
 
ios_baseoct (ios_base &str)
 
ios_baseright (ios_base &str)
 
ios_baseshowbase (ios_base &str)
 
ios_baseshowpoint (ios_base &str)
 
ios_baseshowpos (ios_base &str)
 
ios_baseskipws (ios_base &str)
 
ios_baseuppercase (ios_base &str)
 
+

Detailed Description

+

ios_base and ios classes

+

Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& boolalpha (ios_basestr)
+
+inline
+
+

function for boolalpha manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& dec (ios_basestr)
+
+inline
+
+

function for dec manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& hex (ios_basestr)
+
+inline
+
+

function for hex manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& internal (ios_basestr)
+
+inline
+
+

function for internal manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& left (ios_basestr)
+
+inline
+
+

function for left manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& noboolalpha (ios_basestr)
+
+inline
+
+

function for noboolalpha manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& noshowbase (ios_basestr)
+
+inline
+
+

function for noshowbase manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& noshowpoint (ios_basestr)
+
+inline
+
+

function for noshowpoint manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& noshowpos (ios_basestr)
+
+inline
+
+

function for noshowpos manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& noskipws (ios_basestr)
+
+inline
+
+

function for noskipws manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& nouppercase (ios_basestr)
+
+inline
+
+

function for nouppercase manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& oct (ios_basestr)
+
+inline
+
+

function for oct manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& right (ios_basestr)
+
+inline
+
+

function for right manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& showbase (ios_basestr)
+
+inline
+
+

function for showbase manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& showpoint (ios_basestr)
+
+inline
+
+

function for showpoint manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& showpos (ios_basestr)
+
+inline
+
+

function for showpos manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& skipws (ios_basestr)
+
+inline
+
+

function for skipws manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ios_base& uppercase (ios_basestr)
+
+inline
+
+

function for uppercase manipulator

Parameters
+ + +
[in]strThe stream
+
+
+
Returns
The stream
+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/ios_8h__dep__incl.png b/libraries/SdFat/extras/html/ios_8h__dep__incl.png new file mode 100644 index 0000000..a1c2285 Binary files /dev/null and b/libraries/SdFat/extras/html/ios_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/ios_8h__incl.png b/libraries/SdFat/extras/html/ios_8h__incl.png new file mode 100644 index 0000000..c7b8515 Binary files /dev/null and b/libraries/SdFat/extras/html/ios_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/iostream_8h.html b/libraries/SdFat/extras/html/iostream_8h.html new file mode 100644 index 0000000..c369bc3 --- /dev/null +++ b/libraries/SdFat/extras/html/iostream_8h.html @@ -0,0 +1,521 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/iostream.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
iostream.h File Reference
+
+
+ +

iostream class +More...

+
#include "istream.h"
+#include "ostream.h"
+
+Include dependency graph for iostream.h:
+
+
+ + + + + + + + + + + + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + +

+Classes

class  iostream
 Input/Output stream. More...
 
struct  setfill
 type for setfill manipulator More...
 
struct  setprecision
 type for setprecision manipulator More...
 
struct  setw
 type for setw manipulator More...
 
+ + + + + + + + + + + + + + + + + + + +

+Functions

ostreamendl (ostream &os)
 
ostreamflush (ostream &os)
 
ostreamoperator<< (ostream &os, const setfill &arg)
 
ostreamoperator<< (ostream &os, const setprecision &arg)
 
ostreamoperator<< (ostream &os, const setw &arg)
 
istreamoperator>> (istream &obj, const setfill &arg)
 
istreamoperator>> (istream &is, const setprecision &arg)
 
istreamoperator>> (istream &is, const setw &arg)
 
istreamws (istream &is)
 
+

Detailed Description

+

iostream class

+

Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
ostream& endl (ostreamos)
+
+inline
+
+

insert endline

Parameters
+ + +
[in]osThe Stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
ostream& flush (ostreamos)
+
+inline
+
+

flush manipulator

Parameters
+ + +
[in]osThe stream
+
+
+
Returns
The stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ostream& operator<< (ostreamos,
const setfillarg 
)
+
+inline
+
+

setfill manipulator

Parameters
+ + + +
[in]osthe stream
[in]argset setfill object
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ostream& operator<< (ostreamos,
const setprecisionarg 
)
+
+inline
+
+

setprecision manipulator

Parameters
+ + + +
[in]osthe stream
[in]argset setprecision object
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ostream& operator<< (ostreamos,
const setwarg 
)
+
+inline
+
+

setw manipulator

Parameters
+ + + +
[in]osthe stream
[in]argset setw object
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream& operator>> (istreamobj,
const setfillarg 
)
+
+inline
+
+

setfill manipulator

Parameters
+ + + +
[in]objthe stream
[in]argset setfill object
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream& operator>> (istreamis,
const setprecisionarg 
)
+
+inline
+
+

setprecision manipulator

Parameters
+ + + +
[in]isthe stream
[in]argset setprecision object
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
istream& operator>> (istreamis,
const setwarg 
)
+
+inline
+
+

setw manipulator

Parameters
+ + + +
[in]isthe stream
[in]argset setw object
+
+
+
Returns
the stream
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
istream& ws (istreamis)
+
+inline
+
+

Skip white space

Parameters
+ + +
[in]isthe Stream
+
+
+
Returns
The stream
+ +
+
+
+ + + + diff --git a/libraries/SdFat/extras/html/iostream_8h__dep__incl.png b/libraries/SdFat/extras/html/iostream_8h__dep__incl.png new file mode 100644 index 0000000..2ca56a3 Binary files /dev/null and b/libraries/SdFat/extras/html/iostream_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/iostream_8h__incl.png b/libraries/SdFat/extras/html/iostream_8h__incl.png new file mode 100644 index 0000000..2c4ee90 Binary files /dev/null and b/libraries/SdFat/extras/html/iostream_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/istream_8h.html b/libraries/SdFat/extras/html/istream_8h.html new file mode 100644 index 0000000..4002edb --- /dev/null +++ b/libraries/SdFat/extras/html/istream_8h.html @@ -0,0 +1,142 @@ + + + + + + +SdFat: Arduino/libraries/SdFat/src/FatLib/istream.h File Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
istream.h File Reference
+
+
+ +

istream class +More...

+
#include "ios.h"
+
+Include dependency graph for istream.h:
+
+
+ + + + + + + + + + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + +
+
+ + + + +

+Classes

class  istream
 Input Stream. More...
 
+

Detailed Description

+

istream class

+
+ + + + diff --git a/libraries/SdFat/extras/html/istream_8h__dep__incl.png b/libraries/SdFat/extras/html/istream_8h__dep__incl.png new file mode 100644 index 0000000..adf498b Binary files /dev/null and b/libraries/SdFat/extras/html/istream_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/istream_8h__incl.png b/libraries/SdFat/extras/html/istream_8h__incl.png new file mode 100644 index 0000000..99b0e85 Binary files /dev/null and b/libraries/SdFat/extras/html/istream_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/jquery.js b/libraries/SdFat/extras/html/jquery.js new file mode 100644 index 0000000..1f4d0b4 --- /dev/null +++ b/libraries/SdFat/extras/html/jquery.js @@ -0,0 +1,68 @@ +/*! + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/*! + * jQuery UI 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*! + * jQuery UI Widget 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Widget + */ +(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*! + * jQuery UI Mouse 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*! + * jQuery hashchange event - v1.3 - 7/21/2010 + * http://benalman.com/projects/jquery-hashchange-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$(' + + + + +
+ +
+
ostream.h File Reference
+
+
+ +

ostream class +More...

+
#include "ios.h"
+
+Include dependency graph for ostream.h:
+
+
+ + + + + + + + + + + +
+
+This graph shows which files directly or indirectly include this file:
+
+
+ + + + + + + +
+
+ + + + +

+Classes

class  ostream
 Output Stream. More...
 
+

Detailed Description

+

ostream class

+
+ + + + diff --git a/libraries/SdFat/extras/html/ostream_8h__dep__incl.png b/libraries/SdFat/extras/html/ostream_8h__dep__incl.png new file mode 100644 index 0000000..bd6bf5b Binary files /dev/null and b/libraries/SdFat/extras/html/ostream_8h__dep__incl.png differ diff --git a/libraries/SdFat/extras/html/ostream_8h__incl.png b/libraries/SdFat/extras/html/ostream_8h__incl.png new file mode 100644 index 0000000..aa29793 Binary files /dev/null and b/libraries/SdFat/extras/html/ostream_8h__incl.png differ diff --git a/libraries/SdFat/extras/html/search/all_0.html b/libraries/SdFat/extras/html/search/all_0.html new file mode 100644 index 0000000..1d46950 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_0.js b/libraries/SdFat/extras/html/search/all_0.js new file mode 100644 index 0000000..c3aa3dc --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['_5f_5fbrkval',['__brkval',['../_free_stack_8h.html#ad193a2cc121e0d4614a1c21eb463fb56',1,'FreeStack.h']]], + ['_5f_5fbss_5fend',['__bss_end',['../_free_stack_8h.html#adbad17f740c2d7f2bc4833681c93c932',1,'FreeStack.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_1.html b/libraries/SdFat/extras/html/search/all_1.html new file mode 100644 index 0000000..1fbc509 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_1.js b/libraries/SdFat/extras/html/search/all_1.js new file mode 100644 index 0000000..b82534e --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_1.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['adjustfield',['adjustfield',['../classios__base.html#adaaf735381254aa096ebe3605e8bbd0a',1,'ios_base']]], + ['app',['app',['../classios__base.html#a8380aac3c405730708888fdc68905820',1,'ios_base']]], + ['arduinofiles_2eh',['ArduinoFiles.h',['../_arduino_files_8h.html',1,'']]], + ['arduinoinstream',['ArduinoInStream',['../class_arduino_in_stream.html',1,'ArduinoInStream'],['../class_arduino_in_stream.html#a61ee22a5824849ec3261ee2f814dfb93',1,'ArduinoInStream::ArduinoInStream()']]], + ['arduinooutstream',['ArduinoOutStream',['../class_arduino_out_stream.html',1,'ArduinoOutStream'],['../class_arduino_out_stream.html#a228b667f9f53dc91c6ed7735d34f04a8',1,'ArduinoOutStream::ArduinoOutStream()']]], + ['arduinostream_2eh',['ArduinoStream.h',['../_arduino_stream_8h.html',1,'']]], + ['ate',['ate',['../classios__base.html#aa434355c165500065276d955d8b36e99',1,'ios_base']]], + ['attr',['attr',['../structlong_directory_entry.html#aa36bf1210d0c2b3b80948e5f697eb02e',1,'longDirectoryEntry']]], + ['attributes',['attributes',['../structdirectory_entry.html#a16c6cde55c8175c90935c386f1cfb21a',1,'directoryEntry']]], + ['available',['available',['../class_minimum_serial.html#a2abe4370989968938b5dc4872d51c3df',1,'MinimumSerial::available()'],['../class_print_file.html#a600592235b2bee6bdb3a9701d0d6eee3',1,'PrintFile::available()'],['../class_file.html#acf613c4e75bae85f543b30e701ebcc44',1,'File::available()'],['../class_fat_file.html#ac1fa779d98db7ffdb96f8019ab0060d6',1,'FatFile::available()']]], + ['arduino_20_25sdfat_20library',['Arduino %SdFat Library',['../index.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_10.html b/libraries/SdFat/extras/html/search/all_10.html new file mode 100644 index 0000000..80581d5 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_10.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_10.js b/libraries/SdFat/extras/html/search/all_10.js new file mode 100644 index 0000000..2bf4e35 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_10.js @@ -0,0 +1,29 @@ +var searchData= +[ + ['rdstate',['rdstate',['../classios.html#aacc57e1e46e23f2f54898ff6a89129a2',1,'ios']]], + ['read',['read',['../class_minimum_serial.html#a4890dd60f2ffb61eba0821cc80d411ad',1,'MinimumSerial::read()'],['../class_file.html#a4c46a1975e66c37977bf07c58ec10b4e',1,'File::read()'],['../class_fat_file.html#a60ae55ff6fe158c2340071d702a363c5',1,'FatFile::read()'],['../class_fat_file.html#a200e6e0553d5b709520c9dfac9ef77dd',1,'FatFile::read(void *buf, size_t nbyte)'],['../class_fat_cache.html#ac2bb0b8f2ce3ab5cd86cf30b4a663cea',1,'FatCache::read()']]], + ['readblock',['readBlock',['../class_base_block_driver.html#a16bb3305f3130253dd7ab6e19aa1b524',1,'BaseBlockDriver::readBlock()'],['../class_sdio_card.html#ac94605c428fa9258106835cceec470d8',1,'SdioCard::readBlock()'],['../class_sd_spi_card.html#a4393634a82c6683ee94d1fefe0be332a',1,'SdSpiCard::readBlock()'],['../class_sd_spi_card_e_x.html#abb69c8bd538dafed1e7f33382ee48d61',1,'SdSpiCardEX::readBlock()']]], + ['readblocks',['readBlocks',['../class_base_block_driver.html#a3a029a2d02fc7cbdd7c15c8d622565c4',1,'BaseBlockDriver::readBlocks()'],['../class_sdio_card.html#a7de36d26a01dc39b7dc122c54ee03b12',1,'SdioCard::readBlocks()'],['../class_sd_spi_card.html#ac630f77c3137923b47c1bd12a9bbfadf',1,'SdSpiCard::readBlocks()'],['../class_sd_spi_card_e_x.html#a9e158cda94fadd12267fe7e63d06622a',1,'SdSpiCardEX::readBlocks()']]], + ['readcid',['readCID',['../class_sdio_card.html#add77777fbcf91cc41e8ec62fda169e79',1,'SdioCard::readCID()'],['../class_sd_spi_card.html#aa073dc42828164883db1b9faeff909ea',1,'SdSpiCard::readCID()']]], + ['readcsd',['readCSD',['../class_sdio_card.html#a1da0ca418c153e24b4e13b4c1e20d450',1,'SdioCard::readCSD()'],['../class_sd_spi_card.html#a9fbea9525e70f6e3602fe5153a5a1290',1,'SdSpiCard::readCSD()']]], + ['readdata',['readData',['../class_sd_spi_card.html#a3a1d1b4b4ceb42fcd41aaf6649482770',1,'SdSpiCard']]], + ['readdir',['readDir',['../class_fat_file.html#a1325afe074c3efecff666678cd9f116a',1,'FatFile']]], + ['readline',['readline',['../class_arduino_in_stream.html#ad4c60f813b8df6dd1d6696a3458de09c',1,'ArduinoInStream']]], + ['readocr',['readOCR',['../class_sdio_card.html#adc583f7a27f57ce55ce474b1379b9303',1,'SdioCard::readOCR()'],['../class_sd_spi_card.html#ab446e49338b3ce834a750ac6dae35f61',1,'SdSpiCard::readOCR()']]], + ['readstart',['readStart',['../class_sd_spi_card.html#a3b1710d11496c32ba4323831e00ac6d1',1,'SdSpiCard']]], + ['readstatus',['readStatus',['../class_sd_spi_card.html#a91d0413599efe0d63c8c2dfe4a12d9ae',1,'SdSpiCard']]], + ['readstop',['readStop',['../class_sd_spi_card.html#afdac7c399fa1ba3f904cf503526e007e',1,'SdSpiCard']]], + ['remove',['remove',['../class_fat_file.html#ac837a537fbcca14c7aa390c5fc9f4e7c',1,'FatFile::remove()'],['../class_fat_file.html#afe820bbb056863e91ec482961c8dc695',1,'FatFile::remove(FatFile *dirFile, const char *path)'],['../class_fat_file_system.html#abf7d7d0dab43083d5be10d70ff4669e4',1,'FatFileSystem::remove()']]], + ['rename',['rename',['../class_fat_file.html#a4b42f2454ff462555c07ea094a92a1e0',1,'FatFile::rename()'],['../class_fat_file_system.html#a0187891a24017b41bd7c5ba63e659e65',1,'FatFileSystem::rename()']]], + ['reserved1',['reserved1',['../structfat__boot.html#affa7e6efb3ccea19ba7ea0ddadce7463',1,'fat_boot::reserved1()'],['../structfat32__boot.html#a7075c3c00aae071110fd1acb2e6fd599',1,'fat32_boot::reserved1()'],['../structfat32__fsinfo.html#ac24bd4801a60a54e5133ed1bb71bcdaa',1,'fat32_fsinfo::reserved1()']]], + ['reserved2',['reserved2',['../structfat32__fsinfo.html#a9ec0e2756cd7e169268798a558df3814',1,'fat32_fsinfo']]], + ['reservednt',['reservedNT',['../structdirectory_entry.html#afe7d00be85f3b78549b21610050da52b',1,'directoryEntry']]], + ['reservedsectorcount',['reservedSectorCount',['../structbios_parm_block.html#adb4830c345b27293c7d7b97b77f52e01',1,'biosParmBlock::reservedSectorCount()'],['../structfat__boot.html#a13f272a8f780fb43a400f873a3fd7b73',1,'fat_boot::reservedSectorCount()'],['../structfat32__boot.html#a8e490f05ad3552dfbdf8f9332d287ba0',1,'fat32_boot::reservedSectorCount()']]], + ['rewind',['rewind',['../class_fat_file.html#a5aac6e0b3cb08fc8b8668e916a8b0ca5',1,'FatFile::rewind()'],['../class_stdio_stream.html#ad985866675193d2ee1dde9e27b0d08da',1,'StdioStream::rewind()']]], + ['rewinddirectory',['rewindDirectory',['../class_file.html#ae1419603dea25a6c8480b941d7ac63a3',1,'File']]], + ['right',['right',['../classios__base.html#aec064a12730b5d87e718c1864e29ac64',1,'ios_base::right()'],['../ios_8h.html#aee80fd600c5c58a2bebbd48afdcf8280',1,'right(): ios.h']]], + ['rmdir',['rmdir',['../class_fat_file.html#a9515bac181d33e7f0125e88fa2ccd283',1,'FatFile::rmdir()'],['../class_fat_file_system.html#aaed2edc7ff7fedb163458c870bb41b33',1,'FatFileSystem::rmdir()']]], + ['rmrfstar',['rmRfStar',['../class_fat_file.html#ac780a80526f86d3def701ecdc99d8bfe',1,'FatFile']]], + ['rootdirentrycount',['rootDirEntryCount',['../structbios_parm_block.html#a9a1b24bb2dbb3a123c4ffc703954d71d',1,'biosParmBlock::rootDirEntryCount()'],['../structfat__boot.html#a2124f89e12307df944f08e6657dbf4af',1,'fat_boot::rootDirEntryCount()'],['../structfat32__boot.html#a94185496fb56c6e0e8078fc3803e9142',1,'fat32_boot::rootDirEntryCount()'],['../class_fat_volume.html#ab2d483670a0a6a6a4754b23614fe11bc',1,'FatVolume::rootDirEntryCount()']]], + ['rootdirstart',['rootDirStart',['../class_fat_volume.html#ae9363ebbbae90e895ea56e8fa3f60c13',1,'FatVolume']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_11.html b/libraries/SdFat/extras/html/search/all_11.html new file mode 100644 index 0000000..bb6241b --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_11.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_11.js b/libraries/SdFat/extras/html/search/all_11.js new file mode 100644 index 0000000..832aef4 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_11.js @@ -0,0 +1,64 @@ +var searchData= +[ + ['sd2card',['Sd2Card',['../class_sd2_card.html',1,'']]], + ['sd_5ffat_5fversion',['SD_FAT_VERSION',['../_sd_fat_8h.html#aca25ecce379f446043bdee2c55304210',1,'SdFat.h']]], + ['sd_5fhas_5fcustom_5fspi',['SD_HAS_CUSTOM_SPI',['../_sd_fat_config_8h.html#a838861a01379e94361148d22e62b1977',1,'SdFatConfig.h']]], + ['sdbasefile',['SdBaseFile',['../class_sd_base_file.html',1,'SdBaseFile'],['../class_sd_base_file.html#a94d44fc448dc8a06867d490100a57781',1,'SdBaseFile::SdBaseFile()']]], + ['sdfat',['SdFat',['../class_sd_fat.html',1,'SdFat'],['../class_sd_fat.html#a232871b6bbd0f40d6a2883b3c7b0425f',1,'SdFat::SdFat()']]], + ['sdfat_2eh',['SdFat.h',['../_sd_fat_8h.html',1,'']]], + ['sdfatconfig_2eh',['SdFatConfig.h',['../_sd_fat_config_8h.html',1,'']]], + ['sdfatex',['SdFatEX',['../class_sd_fat_e_x.html',1,'SdFatEX'],['../class_sd_fat_e_x.html#a86b1fdf8b81dff2fced176d39b851474',1,'SdFatEX::SdFatEX()']]], + ['sdfatsdio',['SdFatSdio',['../class_sd_fat_sdio.html',1,'']]], + ['sdfatsoftspi',['SdFatSoftSpi',['../class_sd_fat_soft_spi.html',1,'']]], + ['sdfatsoftspiex',['SdFatSoftSpiEX',['../class_sd_fat_soft_spi_e_x.html',1,'']]], + ['sdfile',['SdFile',['../class_sd_file.html',1,'SdFile'],['../class_sd_file.html#aca7da9858a5e53e10f3c2fa9aeca8485',1,'SdFile::SdFile()']]], + ['sdfilesystem',['SdFileSystem',['../class_sd_file_system.html',1,'']]], + ['sdfilesystem_3c_20sdiocard_20_3e',['SdFileSystem< SdioCard >',['../class_sd_file_system.html',1,'']]], + ['sdfilesystem_3c_20sdspicard_20_3e',['SdFileSystem< SdSpiCard >',['../class_sd_file_system.html',1,'']]], + ['sdfilesystem_3c_20sdspicardex_20_3e',['SdFileSystem< SdSpiCardEX >',['../class_sd_file_system.html',1,'']]], + ['sdiocard',['SdioCard',['../class_sdio_card.html',1,'']]], + ['sdspicard',['SdSpiCard',['../class_sd_spi_card.html',1,'SdSpiCard'],['../class_sd_spi_card.html#a0441c5da53bd3bd72fb833fc940f25e8',1,'SdSpiCard::SdSpiCard()']]], + ['sdspicard_2eh',['SdSpiCard.h',['../_sd_spi_card_8h.html',1,'']]], + ['sdspicardex',['SdSpiCardEX',['../class_sd_spi_card_e_x.html',1,'']]], + ['sectorspercluster',['sectorsPerCluster',['../structbios_parm_block.html#a45d5e2d8c93a028a074e8ce3dc751ab5',1,'biosParmBlock::sectorsPerCluster()'],['../structfat__boot.html#ab3063726125b16a2ccad719548d79abd',1,'fat_boot::sectorsPerCluster()'],['../structfat32__boot.html#a63ded2780732f166f7b7d36bc6aed702',1,'fat32_boot::sectorsPerCluster()']]], + ['sectorsperfat16',['sectorsPerFat16',['../structbios_parm_block.html#a24d6e5a9069491d5db6dbe747336985b',1,'biosParmBlock::sectorsPerFat16()'],['../structfat__boot.html#a0d5ab13399759acfa571e49b85600db1',1,'fat_boot::sectorsPerFat16()'],['../structfat32__boot.html#aeaa78272cd42b162ea448e1642f75cab',1,'fat32_boot::sectorsPerFat16()']]], + ['sectorsperfat32',['sectorsPerFat32',['../structbios_parm_block.html#ad80429df03a6b80f79b18cb6e1008d64',1,'biosParmBlock::sectorsPerFat32()'],['../structfat32__boot.html#aa00db084ff2f7e25febef321469adeb9',1,'fat32_boot::sectorsPerFat32()']]], + ['sectorspertrack',['sectorsPerTrack',['../structfat__boot.html#a6d5ceaf374e0607be8b8162bf657f282',1,'fat_boot::sectorsPerTrack()'],['../structfat32__boot.html#a9525b2e63f84a5cf62ea20199cedf5de',1,'fat32_boot::sectorsPerTrack()']]], + ['sectorspertrtack',['sectorsPerTrtack',['../structbios_parm_block.html#a7c27cb7f66c2c9d5266d896e8df227c7',1,'biosParmBlock']]], + ['seek',['seek',['../class_file.html#a2d41ea52356b769e05e1242685758c08',1,'File']]], + ['seek_5fcur',['SEEK_CUR',['../_stdio_stream_8h.html#a4c8d0b76b470ba65a43ca46a88320f39',1,'StdioStream.h']]], + ['seek_5fend',['SEEK_END',['../_stdio_stream_8h.html#ad2a2e6c114780c3071efd24f16c7f7d8',1,'StdioStream.h']]], + ['seek_5fset',['SEEK_SET',['../_stdio_stream_8h.html#a0d112bae8fd35be772185b6ec6bcbe64',1,'StdioStream.h']]], + ['seekcur',['seekCur',['../class_fat_file.html#a5812037ea30777cc350698ad26f2c73f',1,'FatFile']]], + ['seekdir',['seekdir',['../classios__base.html#ab01103ba35f6ba93a704b3ec0c86191e',1,'ios_base']]], + ['seekend',['seekEnd',['../class_fat_file.html#a84f677f4e75ef6fa2eb632f4cdf6b486',1,'FatFile']]], + ['seekg',['seekg',['../classistream.html#a52d637b1aeca9946085a4a72e0208aec',1,'istream::seekg(pos_type pos)'],['../classistream.html#a60dd48a3b374fb9cbdc59e1f930dea95',1,'istream::seekg(off_type off, seekdir way)']]], + ['seekp',['seekp',['../classostream.html#a18b453d2770a8852c312cbda919c4687',1,'ostream::seekp(pos_type pos)'],['../classostream.html#af6265a5be29237517b30673667ba4213',1,'ostream::seekp(off_type off, seekdir way)']]], + ['seekset',['seekSet',['../class_fat_file.html#ab067190d25733ed7e697d9890f61fd7a',1,'FatFile']]], + ['seqpos',['seqPos',['../structfname__t.html#a96b7c779dec8dd568be3290451078a4e',1,'fname_t']]], + ['setcwd',['setCwd',['../class_fat_file.html#a360ef9c05e677271bed6c0a4d663634c',1,'FatFile']]], + ['setf',['setf',['../classios__base.html#ab5db835cb45bba7684ebf72d9a3cccb4',1,'ios_base::setf(fmtflags fl)'],['../classios__base.html#a74dbc93607ab7d68a87ec326b92b6c81',1,'ios_base::setf(fmtflags fl, fmtflags mask)']]], + ['setfill',['setfill',['../structsetfill.html',1,'setfill'],['../structsetfill.html#abcd87f0632678d277df55406d25c8325',1,'setfill::setfill()']]], + ['setpos',['setpos',['../class_fat_file.html#acf264de4e3ca36c5e8a39e56173c9044',1,'FatFile']]], + ['setprecision',['setprecision',['../structsetprecision.html',1,'setprecision'],['../structsetprecision.html#a73fce143591989f56ef887a2ea86ac45',1,'setprecision::setprecision()']]], + ['setstate',['setstate',['../classios.html#aee5d194656bdfb0c8621b23ea2f51afb',1,'ios']]], + ['setw',['setw',['../structsetw.html',1,'setw'],['../structsetw.html#afd8bfd075474f63df3c8b44ad47517d2',1,'setw::setw()']]], + ['sfn',['sfn',['../structfname__t.html#a37ed0c108b1feb81be4f8c041a4336bd',1,'fname_t']]], + ['showbase',['showbase',['../classios__base.html#a7e3373ab307feecfc228bc9bdb29cd01',1,'ios_base::showbase()'],['../ios_8h.html#a73159e1398939807aeae6015dd86f2f4',1,'showbase(): ios.h']]], + ['showpoint',['showpoint',['../classios__base.html#ac9bb172682e157f037bd7fb82a236ee6',1,'ios_base::showpoint()'],['../ios_8h.html#a322f5897ace09768cd782f0c8f222770',1,'showpoint(): ios.h']]], + ['showpos',['showpos',['../classios__base.html#a7bfa4a883933105d10f8ce2693cb9f21',1,'ios_base::showpos()'],['../ios_8h.html#a80798554dbfece679adb0e05eb855943',1,'showpos(): ios.h']]], + ['size',['size',['../class_file.html#a603d3cd3319142d00a7ebd434970b017',1,'File']]], + ['skipwhite',['skipWhite',['../classistream.html#a0f7468be86d93de5d33fa99095898279',1,'istream']]], + ['skipws',['skipws',['../classios__base.html#a64977c777d6e45826d1be9763f17f824',1,'ios_base::skipws()'],['../ios_8h.html#a972282e5d9d894f61c8a54423858c0a4',1,'skipws(): ios.h']]], + ['spistart',['spiStart',['../class_sd_spi_card.html#aa39feb6ebb269071ac6843a424ac311c',1,'SdSpiCard']]], + ['spistop',['spiStop',['../class_sd_spi_card.html#a1033a4a68d38f52dddf6a1764fcca3e1',1,'SdSpiCard']]], + ['stdiostream',['StdioStream',['../class_stdio_stream.html',1,'StdioStream'],['../class_stdio_stream.html#a96b2c027e76bfca6d6835c9ae1be2ad2',1,'StdioStream::StdioStream()']]], + ['stdiostream_2eh',['StdioStream.h',['../_stdio_stream_8h.html',1,'']]], + ['stream_5fbuf_5fsize',['STREAM_BUF_SIZE',['../_stdio_stream_8h.html#ad9a6150ef11e2616c1a99bc777df17d3',1,'StdioStream.h']]], + ['streamsize',['streamsize',['../classios__base.html#a82836e1d3cc603fba8f0b54d323a2dff',1,'ios_base']]], + ['structsignature',['structSignature',['../structfat32__fsinfo.html#aa4a9ed657a0f58a7a1c75760c3a79fd4',1,'fat32_fsinfo']]], + ['sync',['sync',['../class_fat_file.html#a67f3dc4896c542d695e11aac927f585e',1,'FatFile::sync()'],['../class_fat_cache.html#a4d76d4f46ce5994f6fc4678a7b4f8cf1',1,'FatCache::sync()']]], + ['syncblocks',['syncBlocks',['../class_base_block_driver.html#a5361ff2658d7654bf00b97c54c6aa2aa',1,'BaseBlockDriver::syncBlocks()'],['../class_sdio_card.html#affcd36a5c3a42042fe24716671f06632',1,'SdioCard::syncBlocks()'],['../class_sd_spi_card.html#a1b6d5f412c4ad75c2f575ca75c56c095',1,'SdSpiCard::syncBlocks()'],['../class_sd_spi_card_e_x.html#af4a7c15bae6add50d66d066c0927a021',1,'SdSpiCardEX::syncBlocks()']]], + ['syscall',['SysCall',['../class_sys_call.html',1,'']]], + ['syscall_2eh',['SysCall.h',['../_sys_call_8h.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_12.html b/libraries/SdFat/extras/html/search/all_12.html new file mode 100644 index 0000000..fe93a5b --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_12.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_12.js b/libraries/SdFat/extras/html/search/all_12.js new file mode 100644 index 0000000..63a7c68 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_12.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['tailsignature',['tailSignature',['../structfat32__fsinfo.html#a484dd16425e4e687dc914d12309470e0',1,'fat32_fsinfo']]], + ['tellg',['tellg',['../classistream.html#a18332bdcb7fbe33ca06045c786cac4c3',1,'istream']]], + ['tellp',['tellp',['../classostream.html#a92dec0e2bc8352df1419d1cdc434e619',1,'ostream']]], + ['timestamp',['timestamp',['../class_fat_file.html#aa53a8d1d2467ad9af7d61cbf8ee85243',1,'FatFile::timestamp(FatFile *file)'],['../class_fat_file.html#a56dabdf73833b7e961c4530eb8e16d23',1,'FatFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)']]], + ['totalsectors',['totalSectors',['../structpartition_table.html#acf96e59ce648a9a0cf35751c3b6d7730',1,'partitionTable']]], + ['totalsectors16',['totalSectors16',['../structbios_parm_block.html#a686c686fde2fb109bea120f2f434db87',1,'biosParmBlock::totalSectors16()'],['../structfat__boot.html#ac8bd40dd9186882e423e10b0c83e89b7',1,'fat_boot::totalSectors16()'],['../structfat32__boot.html#acbcae2f15475a886f674f932da1deb3f',1,'fat32_boot::totalSectors16()']]], + ['totalsectors32',['totalSectors32',['../structbios_parm_block.html#abead42e130c40e2aa535202e7cb07578',1,'biosParmBlock::totalSectors32()'],['../structfat__boot.html#addeb2dd8f78418edbf544303d44133e2',1,'fat_boot::totalSectors32()'],['../structfat32__boot.html#ab79466016103c2762c6b057dd458d434',1,'fat32_boot::totalSectors32()']]], + ['trunc',['trunc',['../classios__base.html#ae62b8972f37509819e1384214071194b',1,'ios_base']]], + ['truncate',['truncate',['../class_fat_file.html#aa6e663098a578635d37d92e82d18d616',1,'FatFile::truncate()'],['../class_fat_file_system.html#ad60cb13557f35578f868e03e9ccb8be1',1,'FatFileSystem::truncate()']]], + ['type',['type',['../structpartition_table.html#a3861cf276c728c4dd30ca04e74197ee8',1,'partitionTable::type()'],['../structlong_directory_entry.html#a9adb019dbf24cce65c8d1419cd000f91',1,'longDirectoryEntry::type()'],['../class_sdio_card.html#a2151106a93280ae41bab654428214661',1,'SdioCard::type()'],['../class_sd_spi_card.html#a061d92bf154a1863a6321385b7505f6e',1,'SdSpiCard::type()']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_13.html b/libraries/SdFat/extras/html/search/all_13.html new file mode 100644 index 0000000..cb938b9 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_13.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_13.js b/libraries/SdFat/extras/html/search/all_13.js new file mode 100644 index 0000000..a2e23a1 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_13.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['ungetc',['ungetc',['../class_stdio_stream.html#ac00e0dd906c2e857ece53794c6c92786',1,'StdioStream']]], + ['ungetc_5fbuf_5fsize',['UNGETC_BUF_SIZE',['../_stdio_stream_8h.html#a785dd413c0d7b05f95df82d3453ecacd',1,'StdioStream.h']]], + ['unsetf',['unsetf',['../classios__base.html#a3bf7d054a433ed15e8b984e16f630fa4',1,'ios_base']]], + ['uppercase',['uppercase',['../classios__base.html#ade3db1fe3249e87f4c47a9a8916793d9',1,'ios_base::uppercase()'],['../ios_8h.html#af5d5e1a0effa1b500bb882feed5a2061',1,'uppercase(): ios.h']]], + ['use_5flong_5ffile_5fnames',['USE_LONG_FILE_NAMES',['../_sd_fat_config_8h.html#a2536b194b3b007604a39e8526e108b52',1,'USE_LONG_FILE_NAMES(): SdFatConfig.h'],['../_fat_lib_config_8h.html#a2536b194b3b007604a39e8526e108b52',1,'USE_LONG_FILE_NAMES(): FatLibConfig.h']]], + ['use_5fmulti_5fblock_5fio',['USE_MULTI_BLOCK_IO',['../_sd_fat_config_8h.html#afc3ef382d3ab8d7e6f8fc134ef21d487',1,'USE_MULTI_BLOCK_IO(): SdFatConfig.h'],['../_fat_lib_config_8h.html#afc3ef382d3ab8d7e6f8fc134ef21d487',1,'USE_MULTI_BLOCK_IO(): FatLibConfig.h']]], + ['use_5fsd_5fcrc',['USE_SD_CRC',['../_sd_fat_config_8h.html#af2e76ffb2fdb830175abf513dd640fdd',1,'SdFatConfig.h']]], + ['use_5fseparate_5ffat_5fcache',['USE_SEPARATE_FAT_CACHE',['../_sd_fat_config_8h.html#a23f662882413dcb017ebd8107473b8c3',1,'USE_SEPARATE_FAT_CACHE(): SdFatConfig.h'],['../_fat_lib_config_8h.html#a23f662882413dcb017ebd8107473b8c3',1,'USE_SEPARATE_FAT_CACHE(): FatLibConfig.h']]], + ['use_5fstandard_5fspi_5flibrary',['USE_STANDARD_SPI_LIBRARY',['../_sd_fat_config_8h.html#a3dc42547ca4567cb789bec55759afeb2',1,'SdFatConfig.h']]], + ['usuallyzero',['usuallyZero',['../structmaster_boot_record.html#afacfc863e98f64053cd9459c6dec948f',1,'masterBootRecord']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_14.html b/libraries/SdFat/extras/html/search/all_14.html new file mode 100644 index 0000000..2fcfb13 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_14.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_14.js b/libraries/SdFat/extras/html/search/all_14.js new file mode 100644 index 0000000..2983655 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_14.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['vol',['vol',['../class_fat_file_system.html#a4ca68fe47bb675df0a80df1ed7a53698',1,'FatFileSystem']]], + ['volume',['volume',['../class_fat_file.html#a3c64bd8a9abb9a6461d4addb405614df',1,'FatFile']]], + ['volumeblockcount',['volumeBlockCount',['../class_fat_volume.html#a07bc98088ce4a9c725700899c184f7fc',1,'FatVolume']]], + ['volumelabel',['volumeLabel',['../structfat__boot.html#a9ee733f1b1abc0210ec8f9676bba2218',1,'fat_boot::volumeLabel()'],['../structfat32__boot.html#a8e6349f46344145a7320637a58107b3b',1,'fat32_boot::volumeLabel()']]], + ['volumeserialnumber',['volumeSerialNumber',['../structfat__boot.html#ac05e88a0d27f0340ba008834361d2b20',1,'fat_boot::volumeSerialNumber()'],['../structfat32__boot.html#a20768678da224faefd8acf12cabdbfb8',1,'fat32_boot::volumeSerialNumber()']]], + ['vwd',['vwd',['../class_fat_file_system.html#acf257d02b7166683bda2abc5058004bf',1,'FatFileSystem']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_15.html b/libraries/SdFat/extras/html/search/all_15.html new file mode 100644 index 0000000..a31c6e8 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_15.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_15.js b/libraries/SdFat/extras/html/search/all_15.js new file mode 100644 index 0000000..a92f3a2 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_15.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['w',['w',['../structsetw.html#ab48d915a24d3f3365c9eb76e138a6f4e',1,'setw']]], + ['wdt_5fyield_5ftime_5fmicros',['WDT_YIELD_TIME_MICROS',['../_sd_fat_config_8h.html#a4e8a928d86c50c91c0bfc9a442373e14',1,'SdFatConfig.h']]], + ['width',['width',['../classios__base.html#afa30e7644b4eae5928ad9c487ad387de',1,'ios_base::width()'],['../classios__base.html#ab2ba0f005bbf3d8ebed93b64068492e0',1,'ios_base::width(unsigned n)']]], + ['wipe',['wipe',['../class_fat_file_system.html#a36d7831f92acfbfef1c4a24dd7103dc4',1,'FatFileSystem::wipe()'],['../class_fat_volume.html#a8088aa74cf601996905dadd2eea6966c',1,'FatVolume::wipe()']]], + ['write',['write',['../class_minimum_serial.html#a0ca1d9631fe5f2f00878bd481dbbd3aa',1,'MinimumSerial::write()'],['../class_print_file.html#a460b033ff85e85f684f8d9b615645db1',1,'PrintFile::write(uint8_t b)'],['../class_print_file.html#a29c1d534d21c3a82ad04232d37119a57',1,'PrintFile::write(const uint8_t *buf, size_t size)'],['../class_file.html#a618a6b2b7e81bfb93e0d3c158f614f90',1,'File::write(uint8_t b)'],['../class_file.html#aa531c1641a2363e1f6b9d103f37433da',1,'File::write(const uint8_t *buf, size_t size)'],['../class_fat_file.html#aa4a5b81161994cea07938702cdfce49f',1,'FatFile::write(const char *str)'],['../class_fat_file.html#a5524bd9f3b8f54ee163e391cba618186',1,'FatFile::write(uint8_t b)'],['../class_fat_file.html#a0ab9df44a9ee4b6eb0a78f15f1e30004',1,'FatFile::write(const void *buf, size_t nbyte)']]], + ['writeblock',['writeBlock',['../class_base_block_driver.html#a87df3db1b400286883661525441d39fa',1,'BaseBlockDriver::writeBlock()'],['../class_sdio_card.html#ae53e5f72ddf9ace3f47774d968e064ed',1,'SdioCard::writeBlock()'],['../class_sd_spi_card.html#a03a0bdb0f37a88076f24a2133cf5b4ed',1,'SdSpiCard::writeBlock()'],['../class_sd_spi_card_e_x.html#a6bd5e6bcfc2ab9574daa11bdd342be7b',1,'SdSpiCardEX::writeBlock()']]], + ['writeblocks',['writeBlocks',['../class_base_block_driver.html#a3d6520b21252ebfb17b0cac0b87689b1',1,'BaseBlockDriver::writeBlocks()'],['../class_sdio_card.html#a8b811f875497e90e75fbe6c2d41d89cb',1,'SdioCard::writeBlocks()'],['../class_sd_spi_card.html#a181d96fe44891b7caabcd47dd29ac913',1,'SdSpiCard::writeBlocks()'],['../class_sd_spi_card_e_x.html#a9a7a5815b56c2cc77590a72635593762',1,'SdSpiCardEX::writeBlocks()']]], + ['writedata',['writeData',['../class_sd_spi_card.html#a9495c0b148eb380358bb4a9721c0dffa',1,'SdSpiCard']]], + ['writestart',['writeStart',['../class_sd_spi_card.html#a56d4750a5d2f693943eec985cb61ffe2',1,'SdSpiCard::writeStart(uint32_t blockNumber)'],['../class_sd_spi_card.html#a8bf0dc991308dcd2a7427bad89a9e2ba',1,'SdSpiCard::writeStart(uint32_t blockNumber, uint32_t eraseCount)']]], + ['writestop',['writeStop',['../class_sd_spi_card.html#aef9154785a4de5560fb807e4f9316fb0',1,'SdSpiCard']]], + ['ws',['ws',['../iostream_8h.html#a8adf4c714b8c8f201dedc83ee04556b1',1,'iostream.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_16.html b/libraries/SdFat/extras/html/search/all_16.html new file mode 100644 index 0000000..6343dec --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_16.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_16.js b/libraries/SdFat/extras/html/search/all_16.js new file mode 100644 index 0000000..685c4a7 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_16.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['yield',['yield',['../class_sys_call.html#a2219ba5ea8e411b022a3a00df5f380e0',1,'SysCall']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_2.html b/libraries/SdFat/extras/html/search/all_2.html new file mode 100644 index 0000000..93962b7 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_2.js b/libraries/SdFat/extras/html/search/all_2.js new file mode 100644 index 0000000..2cabb23 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_2.js @@ -0,0 +1,32 @@ +var searchData= +[ + ['bad',['bad',['../classios.html#a7daa417c60277a4a4a452df4ad0af8e6',1,'ios']]], + ['badbit',['badbit',['../classios__base.html#ac8c2c8f2f6bc9e6ce101c20e88ebce35',1,'ios_base']]], + ['baseblockdriver',['BaseBlockDriver',['../class_base_block_driver.html',1,'']]], + ['basefield',['basefield',['../classios__base.html#a75ce5482aa207d7aa0265d138b50a102',1,'ios_base']]], + ['beg',['beg',['../classios__base.html#ab01103ba35f6ba93a704b3ec0c86191ea6639b4dd9e9b57ffef4a176cd1a1e7bb',1,'ios_base']]], + ['begin',['begin',['../class_minimum_serial.html#a5c56beb3472bb97f949defeecacda52c',1,'MinimumSerial::begin()'],['../class_sd_file_system.html#ad94237ef45c52698e97b04e8c131f21e',1,'SdFileSystem::begin()'],['../class_sd_fat.html#abfafe10a64b28e6c1698ed82d340f624',1,'SdFat::begin()'],['../class_sd_fat_sdio.html#ac742b37bd8f2f4eb4df44b37c98398e0',1,'SdFatSdio::begin()'],['../class_sd_fat_soft_spi.html#a061019e4b5e17fad3cf8b0e3a08532e4',1,'SdFatSoftSpi::begin()'],['../class_sd_fat_e_x.html#a25acc97272c6004a6a4118bacef07467',1,'SdFatEX::begin()'],['../class_sd_fat_soft_spi_e_x.html#af84b3a6a61dd4c7f3c2c4bb17a8a6609',1,'SdFatSoftSpiEX::begin()'],['../class_sd2_card.html#a8506e1a2d7c4d8ec3f26e8b62ea81cd7',1,'Sd2Card::begin()'],['../class_fat_file_system.html#a5dda20d3dcbfc8c641babbb2c9aac382',1,'FatFileSystem::begin()'],['../class_sdio_card.html#ac749bdad92a4465d062f5d21a7f4faf5',1,'SdioCard::begin()'],['../class_sd_spi_card.html#a824cd60ef8ac2b06262597d6f30a4ea7',1,'SdSpiCard::begin()'],['../class_sd_spi_card_e_x.html#a4fd0b23d230c6ad7dc406e798bbd5470',1,'SdSpiCardEX::begin()']]], + ['begincylinderhigh',['beginCylinderHigh',['../structpartition_table.html#a744f0c7f9ad4c426b10de085b4f52392',1,'partitionTable']]], + ['begincylinderlow',['beginCylinderLow',['../structpartition_table.html#a941fcb4df298f5f73ccca011bf40787a',1,'partitionTable']]], + ['beginhead',['beginHead',['../structpartition_table.html#a7d426694b8cf2151ae38568670a8c845',1,'partitionTable']]], + ['beginsector',['beginSector',['../structpartition_table.html#ae201c11d9671c9efc307c654a2b6c026',1,'partitionTable']]], + ['binary',['binary',['../classios__base.html#ac99947c17c2936d15243671366605602',1,'ios_base']]], + ['biosparmblock',['biosParmBlock',['../structbios_parm_block.html',1,'']]], + ['block',['block',['../class_fat_cache.html#ab3d9c4f94af61065b6d6d0892827fd8a',1,'FatCache']]], + ['blockdriver',['BlockDriver',['../_block_driver_8h.html#ace97f2377acdc471a01f9f7ec1fd6bbb',1,'BlockDriver.h']]], + ['blockdriver_2eh',['BlockDriver.h',['../_block_driver_8h.html',1,'']]], + ['blockspercluster',['blocksPerCluster',['../class_fat_volume.html#a06beed4cea5e38116b58254a57125442',1,'FatVolume']]], + ['blocksperfat',['blocksPerFat',['../class_fat_volume.html#abc66d856d05198d9ebe7104c8c4155d7',1,'FatVolume']]], + ['boolalpha',['boolalpha',['../classios__base.html#afa74acd95d4bbc7cc3551251aac2bf00',1,'ios_base::boolalpha()'],['../ios_8h.html#a0016daaaf730481e2ad36972fa7abb17',1,'boolalpha(): ios.h']]], + ['boot',['boot',['../structpartition_table.html#adf386afb1f33046d8b6a1a0afa780ec9',1,'partitionTable']]], + ['bootcode',['bootCode',['../structfat__boot.html#acf9f5d9f61a6e680e11849f957ecf782',1,'fat_boot::bootCode()'],['../structfat32__boot.html#a7a74880066860140386edf3d9278b9f7',1,'fat32_boot::bootCode()']]], + ['bootsectorsig0',['bootSectorSig0',['../structfat__boot.html#a7951b888af4f357b84dd40af2ef7f29d',1,'fat_boot::bootSectorSig0()'],['../structfat32__boot.html#a1cb46a5427b641a6017a082bc56df1be',1,'fat32_boot::bootSectorSig0()']]], + ['bootsectorsig1',['bootSectorSig1',['../structfat__boot.html#afe8f58668ff594bb2022ce7c06b7726c',1,'fat_boot::bootSectorSig1()'],['../structfat32__boot.html#a53bc302a398f02a86d3b28f25a5ec8e2',1,'fat32_boot::bootSectorSig1()']]], + ['bootsig0',['BOOTSIG0',['../_fat_structs_8h.html#acb7f0c892eb84c121c5698b2605e95e3',1,'FatStructs.h']]], + ['bootsig1',['BOOTSIG1',['../_fat_structs_8h.html#a52f90172e11e828b411c803f29853753',1,'FatStructs.h']]], + ['bootsignature',['bootSignature',['../structfat__boot.html#a712dc388c530e91e4a692e7102d6bdc8',1,'fat_boot::bootSignature()'],['../structfat32__boot.html#ab79a1205277ecab05526fb0bac6e42f6',1,'fat32_boot::bootSignature()']]], + ['bpb_5ft',['bpb_t',['../_fat_structs_8h.html#a5c8af240713e05e7e6c959006ced35fb',1,'FatStructs.h']]], + ['buf',['buf',['../classobufstream.html#a4f699181bd3727f4288f4f95a5ce207f',1,'obufstream']]], + ['bufstream_2eh',['bufstream.h',['../bufstream_8h.html',1,'']]], + ['bytespersector',['bytesPerSector',['../structbios_parm_block.html#aec24d316af486445d55da14cbbfa6bf4',1,'biosParmBlock::bytesPerSector()'],['../structfat__boot.html#a60b2461f8ebf0ad295a95094e1bd7d65',1,'fat_boot::bytesPerSector()'],['../structfat32__boot.html#a03c7086a8c988257a6678179a67a3fee',1,'fat32_boot::bytesPerSector()']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_3.html b/libraries/SdFat/extras/html/search/all_3.html new file mode 100644 index 0000000..679f93c --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_3.js b/libraries/SdFat/extras/html/search/all_3.js new file mode 100644 index 0000000..fb88ee5 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_3.js @@ -0,0 +1,40 @@ +var searchData= +[ + ['c',['c',['../structsetfill.html#a42ffb4e6135c1274ae827cfed7793a82',1,'setfill']]], + ['cache_5ffor_5fread',['CACHE_FOR_READ',['../class_fat_cache.html#ab4b446515ff9a0cebc747630ddd10c93',1,'FatCache']]], + ['cache_5ffor_5fwrite',['CACHE_FOR_WRITE',['../class_fat_cache.html#a81cb572f33443bd6aee9aa33ec395d0f',1,'FatCache']]], + ['cache_5foption_5fno_5fread',['CACHE_OPTION_NO_READ',['../class_fat_cache.html#adf974f55e53ee0aaa85abb0d7d67181c',1,'FatCache']]], + ['cache_5freserve_5ffor_5fwrite',['CACHE_RESERVE_FOR_WRITE',['../class_fat_cache.html#a49d2896ff525ab77852f76df5c2a09c2',1,'FatCache']]], + ['cache_5fstatus_5fdirty',['CACHE_STATUS_DIRTY',['../class_fat_cache.html#aac8c38e5c545d0f80b13d816117f626e',1,'FatCache']]], + ['cache_5fstatus_5fmask',['CACHE_STATUS_MASK',['../class_fat_cache.html#ab70dc4a2e387f0e9bf392044c702ae32',1,'FatCache']]], + ['cache_5fstatus_5fmirror_5ffat',['CACHE_STATUS_MIRROR_FAT',['../class_fat_cache.html#a45236e1c0a2a098f08d3add0e4b1467a',1,'FatCache']]], + ['cache_5ft',['cache_t',['../unioncache__t.html',1,'']]], + ['cacheclear',['cacheClear',['../class_fat_volume.html#aa1e3b1d0c21d202deb82668068ab00e8',1,'FatVolume']]], + ['card',['card',['../class_sd_file_system.html#ab5dcfbeeb7caa38a38db86003341eb07',1,'SdFileSystem']]], + ['cardbegin',['cardBegin',['../class_sd_fat.html#ae380e4572776db851b2f80a3ed143fca',1,'SdFat::cardBegin()'],['../class_sd_fat_sdio.html#ac49062cc8fb2a42564d0ff05b4c0be8b',1,'SdFatSdio::cardBegin()']]], + ['carderrorcode',['cardErrorCode',['../class_sd_file_system.html#aedfd5a0830c955bc5514e52f2f2dd066',1,'SdFileSystem']]], + ['carderrordata',['cardErrorData',['../class_sd_file_system.html#a0602ab3c04ea33293649f0a15fc81e05',1,'SdFileSystem']]], + ['cardsize',['cardSize',['../class_sdio_card.html#a3d8f9a92f7faec77094ec65e6c41dd45',1,'SdioCard::cardSize()'],['../class_sd_spi_card.html#afca8bd6b7e465bf9c475ba375c4deec8',1,'SdSpiCard::cardSize()']]], + ['chdir',['chdir',['../class_fat_file_system.html#a5667915e63187a43a71dfada63800865',1,'FatFileSystem::chdir(bool set_cwd=false)'],['../class_fat_file_system.html#a44af1b98e8d986d12107b654453acbc4',1,'FatFileSystem::chdir(const char *path, bool set_cwd=false)']]], + ['chksum',['chksum',['../structlong_directory_entry.html#a60c35531bc0e12f2d764d290244f8cc9',1,'longDirectoryEntry']]], + ['chvol',['chvol',['../class_fat_file_system.html#af24917d6e00c8766dab168eb834047ec',1,'FatFileSystem']]], + ['clear',['clear',['../classfstream.html#a682b278a6a299ffb21b8737717ff12bf',1,'fstream::clear()'],['../classofstream.html#a09edfdb3dbda20aff105e751001313f0',1,'ofstream::clear()'],['../classios.html#aa49ed6670d1743e7a373b2d915ec739a',1,'ios::clear()']]], + ['clearerr',['clearerr',['../class_stdio_stream.html#aa737e5680fc2808a03a603ea8559d82b',1,'StdioStream']]], + ['clearerror',['clearError',['../class_fat_file.html#a052e2c15a39b322a5307b693b8835b22',1,'FatFile']]], + ['clearwriteerror',['clearWriteError',['../class_fat_file.html#aeca2a2eff91e6aa55fe1b0e3860c9a05',1,'FatFile']]], + ['close',['close',['../class_fat_file.html#afd16af325e0642e4bff6430b7d8bb18b',1,'FatFile::close()'],['../classfstream.html#ac5720ee620c09d63dd186823e688ea9a',1,'fstream::close()'],['../classifstream.html#ac5892f472afdef6160f5fe2401b16dce',1,'ifstream::close()'],['../classofstream.html#a240f3752c7ff7a78d10c143d2083715f',1,'ofstream::close()']]], + ['cluster',['cluster',['../struct_fat_pos__t.html#a7b50657b0debaf0e6231af2c74a655fe',1,'FatPos_t']]], + ['clustercount',['clusterCount',['../class_fat_volume.html#a18446a9c5924304fa7a87d5f03ccaf21',1,'FatVolume']]], + ['clustersizeshift',['clusterSizeShift',['../class_fat_volume.html#ac0e63f33d71d5dc95a602834274def6a',1,'FatVolume']]], + ['codearea',['codeArea',['../structmaster_boot_record.html#a26ca1fb4ebbff2cc1a54153b1dfcd688',1,'masterBootRecord']]], + ['contiguousrange',['contiguousRange',['../class_fat_file.html#aa367708bcc8bc0e0c45c0c2a812c65da',1,'FatFile']]], + ['createcontiguous',['createContiguous',['../class_fat_file.html#a0afc2a1cffa238d1cb2049bfa2d8d199',1,'FatFile::createContiguous(FatFile *dirFile, const char *path, uint32_t size)'],['../class_fat_file.html#a0853fbd44aee2798d14d8e3aed78f8bf',1,'FatFile::createContiguous(const char *path, uint32_t size)']]], + ['creationdate',['creationDate',['../structdirectory_entry.html#a7b43372794655fe6604d3c17c02302fe',1,'directoryEntry']]], + ['creationtime',['creationTime',['../structdirectory_entry.html#a622bfa70c2cd9006108d7473d737a953',1,'directoryEntry']]], + ['creationtimetenths',['creationTimeTenths',['../structdirectory_entry.html#aa5e1ce5b411b88f005b28a3e7c7c5af6',1,'directoryEntry']]], + ['cur',['cur',['../classios__base.html#ab01103ba35f6ba93a704b3ec0c86191ea53910041525b9e2f33bfc3bb4482134c',1,'ios_base']]], + ['curcluster',['curCluster',['../class_fat_file.html#a4c03e2f6729526786e6ab4a623e0339b',1,'FatFile']]], + ['curposition',['curPosition',['../class_fat_file.html#a20c55b134bfd1d287a00bf64eba9332e',1,'FatFile']]], + ['curtimems',['curTimeMS',['../_sys_call_8h.html#a7a1c5babdcf00c78d4d2e6a012bd9e68',1,'SysCall.h']]], + ['cwd',['cwd',['../class_fat_file.html#a3b68e603ad8e47bad915f0547e580adb',1,'FatFile']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_4.html b/libraries/SdFat/extras/html/search/all_4.html new file mode 100644 index 0000000..adc99fb --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_4.js b/libraries/SdFat/extras/html/search/all_4.js new file mode 100644 index 0000000..fb8b966 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_4.js @@ -0,0 +1,43 @@ +var searchData= +[ + ['data',['data',['../unioncache__t.html#ae675b7a3a87d809070de111d1d1f1d81',1,'cache_t']]], + ['datastartblock',['dataStartBlock',['../class_fat_volume.html#a443364af257c219f8e908d5b073d8fa3',1,'FatVolume']]], + ['datetimecallback',['dateTimeCallback',['../class_fat_file.html#a29a623f50df057e8b49045ba6611ec2b',1,'FatFile']]], + ['datetimecallbackcancel',['dateTimeCallbackCancel',['../class_fat_file.html#a5df02f1d037e6091375488af25244ebc',1,'FatFile']]], + ['dbgfat',['dbgFat',['../class_fat_volume.html#a25c6311b70fa274b3be94ff25fdebba7',1,'FatVolume']]], + ['dec',['dec',['../classios__base.html#a2826aed005e7c1f6858060cddae7971a',1,'ios_base::dec()'],['../ios_8h.html#ada38ab90e22f0ebb638cb864a35c562d',1,'dec(): ios.h']]], + ['destructor_5fcloses_5ffile',['DESTRUCTOR_CLOSES_FILE',['../_sd_fat_config_8h.html#a9a2b1ca4d91cff876f48deeaacbc33da',1,'DESTRUCTOR_CLOSES_FILE(): SdFatConfig.h'],['../_fat_lib_config_8h.html#a9a2b1ca4d91cff876f48deeaacbc33da',1,'DESTRUCTOR_CLOSES_FILE(): FatLibConfig.h']]], + ['dir',['dir',['../unioncache__t.html#a7396fdbdb7c52bd1d72c5329ff32acd1',1,'cache_t']]], + ['dir_5fatt_5farchive',['DIR_ATT_ARCHIVE',['../_fat_structs_8h.html#a0d0745a2bc191d12f6e3294a890c4b13',1,'FatStructs.h']]], + ['dir_5fatt_5fdefined_5fbits',['DIR_ATT_DEFINED_BITS',['../_fat_structs_8h.html#ad0c6ed5cf186a40f98cc3929b52cf8ee',1,'FatStructs.h']]], + ['dir_5fatt_5fdirectory',['DIR_ATT_DIRECTORY',['../_fat_structs_8h.html#a5fe039a9af7304fc97a0e903acd217f7',1,'FatStructs.h']]], + ['dir_5fatt_5ffile_5ftype_5fmask',['DIR_ATT_FILE_TYPE_MASK',['../_fat_structs_8h.html#af006ada1b85a9761dd9538273c1ee97f',1,'FatStructs.h']]], + ['dir_5fatt_5fhidden',['DIR_ATT_HIDDEN',['../_fat_structs_8h.html#aed394afe98ff4b7876a5815319b6ef94',1,'FatStructs.h']]], + ['dir_5fatt_5flong_5fname',['DIR_ATT_LONG_NAME',['../_fat_structs_8h.html#a0039e1903007eb7383a9fe4b80a3569e',1,'FatStructs.h']]], + ['dir_5fatt_5flong_5fname_5fmask',['DIR_ATT_LONG_NAME_MASK',['../_fat_structs_8h.html#a74ddbd24c315a682449a51a2a35adf39',1,'FatStructs.h']]], + ['dir_5fatt_5fread_5fonly',['DIR_ATT_READ_ONLY',['../_fat_structs_8h.html#ae5efa2fd21e8a563a3a45f8a52538cde',1,'FatStructs.h']]], + ['dir_5fatt_5fsystem',['DIR_ATT_SYSTEM',['../_fat_structs_8h.html#a31c7e5c119c9ebc1237746c985cf385d',1,'FatStructs.h']]], + ['dir_5fatt_5fvolume_5fid',['DIR_ATT_VOLUME_ID',['../_fat_structs_8h.html#a410501be78b30a75224dd4e81a4a1105',1,'FatStructs.h']]], + ['dir_5fis_5ffile',['DIR_IS_FILE',['../_fat_structs_8h.html#a5ce8bde4d6ff3950df951e84c7bb8d58',1,'FatStructs.h']]], + ['dir_5fis_5ffile_5for_5fsubdir',['DIR_IS_FILE_OR_SUBDIR',['../_fat_structs_8h.html#a9d99b04fa090825a9b9c2468fa81e627',1,'FatStructs.h']]], + ['dir_5fis_5fhidden',['DIR_IS_HIDDEN',['../_fat_structs_8h.html#a5137c8165addb9d32c6094d03a9d029d',1,'FatStructs.h']]], + ['dir_5fis_5flong_5fname',['DIR_IS_LONG_NAME',['../_fat_structs_8h.html#a504c3d996b412f386becc27a8c49cd2c',1,'FatStructs.h']]], + ['dir_5fis_5fsubdir',['DIR_IS_SUBDIR',['../_fat_structs_8h.html#ace8ed88fcb41afc4d2fe0eabf96e71c6',1,'FatStructs.h']]], + ['dir_5fis_5fsystem',['DIR_IS_SYSTEM',['../_fat_structs_8h.html#a46cad0d590c5e290c52ccf660b316dd9',1,'FatStructs.h']]], + ['dir_5fname_5f0xe5',['DIR_NAME_0XE5',['../_fat_structs_8h.html#a1696d3db9949d6e22d1c2c595fd14669',1,'FatStructs.h']]], + ['dir_5fname_5fdeleted',['DIR_NAME_DELETED',['../_fat_structs_8h.html#a8c08d4823047505f3231e86c5033d08c',1,'FatStructs.h']]], + ['dir_5fname_5ffree',['DIR_NAME_FREE',['../_fat_structs_8h.html#a0f1f0001102ae59b9e7c9e3b04cc06d8',1,'FatStructs.h']]], + ['dir_5fnt_5flc_5fbase',['DIR_NT_LC_BASE',['../_fat_structs_8h.html#a39f9b8960dba007b537e9b71c25384fe',1,'FatStructs.h']]], + ['dir_5fnt_5flc_5fext',['DIR_NT_LC_EXT',['../_fat_structs_8h.html#a8766a8bbab6ad3da38c1b308545d7572',1,'FatStructs.h']]], + ['dir_5ft',['dir_t',['../_fat_structs_8h.html#a803db59d4e16a0c54a647afc6a7954e3',1,'FatStructs.h']]], + ['directoryentry',['directoryEntry',['../structdirectory_entry.html',1,'']]], + ['direntry',['dirEntry',['../class_fat_file.html#a6858d18c807411a071fd6d1b39d50087',1,'FatFile']]], + ['dirindex',['dirIndex',['../class_fat_file.html#ae5ec24d4a94d3780384d3f2b731c7eb9',1,'FatFile']]], + ['dirname',['dirName',['../class_fat_file.html#a648461081fe07578780f4cd3f246cb66',1,'FatFile']]], + ['dirsize',['dirSize',['../class_fat_file.html#ae2ed15f05c9ccbce355e7a8d3ce8382d',1,'FatFile']]], + ['dirty',['dirty',['../class_fat_cache.html#ab4d3b0c16bb6a116c7d01afff2dcb307',1,'FatCache']]], + ['disksignature',['diskSignature',['../structmaster_boot_record.html#a77151c641444c0653ff71a253f0423ef',1,'masterBootRecord']]], + ['dmabusy',['dmaBusy',['../class_sdio_card.html#a9781b9b4f91366a69dd077ad8fb364c5',1,'SdioCard']]], + ['dmpfile',['dmpFile',['../class_fat_file.html#a4f01d27954ae49aeb6888ac7302f55d9',1,'FatFile']]], + ['drivenumber',['driveNumber',['../structfat__boot.html#aebd280b93563b75b9612d3db844b0d16',1,'fat_boot::driveNumber()'],['../structfat32__boot.html#aca415c1a6eb1c242d460a6d0ffa9ebec',1,'fat32_boot::driveNumber()']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_5.html b/libraries/SdFat/extras/html/search/all_5.html new file mode 100644 index 0000000..a9fcd17 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_5.js b/libraries/SdFat/extras/html/search/all_5.js new file mode 100644 index 0000000..c89df75 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_5.js @@ -0,0 +1,26 @@ +var searchData= +[ + ['enable_5farduino_5ffeatures',['ENABLE_ARDUINO_FEATURES',['../_fat_lib_config_8h.html#a9a8c1ea8596f35f7f33a24b642567206',1,'FatLibConfig.h']]], + ['enable_5fextended_5ftransfer_5fclass',['ENABLE_EXTENDED_TRANSFER_CLASS',['../_sd_fat_config_8h.html#aad4f0ecbc65cdc3a7be544225b44f86a',1,'SdFatConfig.h']]], + ['enable_5fsdio_5fclass',['ENABLE_SDIO_CLASS',['../_sd_fat_config_8h.html#a1d106f3a0ba8577abdcc9ce3961ef90b',1,'SdFatConfig.h']]], + ['enable_5fsoftware_5fspi_5fclass',['ENABLE_SOFTWARE_SPI_CLASS',['../_sd_fat_config_8h.html#acc3d779d87b785bb7236b9b3acf7e619',1,'SdFatConfig.h']]], + ['end',['end',['../classios__base.html#ab01103ba35f6ba93a704b3ec0c86191eaae47c0ae984e90b38907783a1a804811',1,'ios_base']]], + ['endcylinderhigh',['endCylinderHigh',['../structpartition_table.html#a32fea225b8ffd925ad919ffc56e9abda',1,'partitionTable']]], + ['endcylinderlow',['endCylinderLow',['../structpartition_table.html#ad7829e34be70084abe145227b0d18274',1,'partitionTable']]], + ['endhead',['endHead',['../structpartition_table.html#a4a3945bfd3a29f474984cb9f180dbd51',1,'partitionTable']]], + ['endl',['endl',['../iostream_8h.html#ab9868f8e151efc1705646437dbb59bb2',1,'iostream.h']]], + ['endl_5fcalls_5fflush',['ENDL_CALLS_FLUSH',['../_sd_fat_config_8h.html#a270eefdaec4778f2a491658f34f61b17',1,'ENDL_CALLS_FLUSH(): SdFatConfig.h'],['../_fat_lib_config_8h.html#a270eefdaec4778f2a491658f34f61b17',1,'ENDL_CALLS_FLUSH(): FatLibConfig.h']]], + ['endsector',['endSector',['../structpartition_table.html#a27cdc4320c418ed0d833ab163ed77ad7',1,'partitionTable']]], + ['eof',['eof',['../classios.html#ad2f091f3ed1a2e13f62557854c0885a7',1,'ios::eof()'],['../_stdio_stream_8h.html#a59adc4c82490d23754cd39c2fb99b0da',1,'EOF(): StdioStream.h']]], + ['eofbit',['eofbit',['../classios__base.html#af75072b7ef2a931c77a2cb8e7ccda460',1,'ios_base']]], + ['erase',['erase',['../class_sdio_card.html#a1ce82b035257790ed8e4a9be3d966b80',1,'SdioCard::erase()'],['../class_sd_spi_card.html#a1caa13d19df6596b2c0dd62365c75362',1,'SdSpiCard::erase()']]], + ['erasesingleblockenable',['eraseSingleBlockEnable',['../class_sd_spi_card.html#aed4591884254c9f58daa8738d7c1ccdd',1,'SdSpiCard']]], + ['error',['error',['../class_sd_spi_card.html#aa12ad53111abcb187d3c6119a3a77592',1,'SdSpiCard']]], + ['errorcode',['errorCode',['../class_sdio_card.html#a4ff272009a24fc4078ac87c2d87ccd16',1,'SdioCard::errorCode()'],['../class_sd_spi_card.html#a50bf5f92223222beacec2b203a6b7a95',1,'SdSpiCard::errorCode()']]], + ['errordata',['errorData',['../class_sdio_card.html#a8251b9aa0d623487e80cf908fc1625b5',1,'SdioCard::errorData()'],['../class_sd_spi_card.html#a7b1abdb8dd5254cd4af0df19ba59ce4a',1,'SdSpiCard::errorData()']]], + ['errorhalt',['errorHalt',['../class_sd_file_system.html#a855267374306bfee2df67642c99d4d18',1,'SdFileSystem::errorHalt()'],['../class_sd_file_system.html#ae1f79a2974ebe134e70f898c32d97e98',1,'SdFileSystem::errorHalt(Print *pr)'],['../class_sd_file_system.html#a32c20dfa6a8cb8af95f25847b19bdbca',1,'SdFileSystem::errorHalt(char const *msg)'],['../class_sd_file_system.html#a27fb329d6aee79a63c20386218ce7e9e',1,'SdFileSystem::errorHalt(Print *pr, char const *msg)'],['../class_sd_file_system.html#af856494745a9842d9728dfeabf19c51e',1,'SdFileSystem::errorHalt(const __FlashStringHelper *msg)'],['../class_sd_file_system.html#a746c80d048c30baf0b281e16932670a2',1,'SdFileSystem::errorHalt(Print *pr, const __FlashStringHelper *msg)']]], + ['errorline',['errorLine',['../class_sdio_card.html#aafa9feb1b5a90f3cf96456b6b286bfdf',1,'SdioCard']]], + ['errorprint',['errorPrint',['../class_sd_file_system.html#ab0b78154d6874c29279ba81f36ccb09c',1,'SdFileSystem::errorPrint()'],['../class_sd_file_system.html#a03736274debea71fef5e2ff34d7ec3dc',1,'SdFileSystem::errorPrint(Print *pr)'],['../class_sd_file_system.html#a2e2436b7b2666737cbaf4b22218bc69f',1,'SdFileSystem::errorPrint(const char *msg)'],['../class_sd_file_system.html#a0eb6b92a0700ba932f6127962981d153',1,'SdFileSystem::errorPrint(Print *pr, char const *msg)'],['../class_sd_file_system.html#a1ccb1f937f42e9c1331c942bc357f6da',1,'SdFileSystem::errorPrint(const __FlashStringHelper *msg)'],['../class_sd_file_system.html#a43344a079d9af92ea4b550914d0512f6',1,'SdFileSystem::errorPrint(Print *pr, const __FlashStringHelper *msg)']]], + ['exists',['exists',['../class_fat_file.html#a50242f98dea0d4488ce4039a279f2a57',1,'FatFile::exists()'],['../class_fat_file_system.html#aee58c6352652f216577196e32a594b67',1,'FatFileSystem::exists()']]], + ['extended_5fboot_5fsig',['EXTENDED_BOOT_SIG',['../_fat_structs_8h.html#aefadfae26e4cc8d57c1ff727a9d1cd20',1,'FatStructs.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_6.html b/libraries/SdFat/extras/html/search/all_6.html new file mode 100644 index 0000000..821c374 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_6.js b/libraries/SdFat/extras/html/search/all_6.js new file mode 100644 index 0000000..39257bc --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_6.js @@ -0,0 +1,98 @@ +var searchData= +[ + ['f',['F',['../_sys_call_8h.html#a0e3009529aac180ed5f48296d6670d6b',1,'SysCall.h']]], + ['fail',['fail',['../classios.html#a1c7b563046a50c5a0430405964998034',1,'ios']]], + ['failbit',['failbit',['../classios__base.html#a36157154001bcce17827db6786e35efd',1,'ios_base']]], + ['fat12_5fsupport',['FAT12_SUPPORT',['../_sd_fat_config_8h.html#a28998c5daf4bd038f4f93172698320b1',1,'FAT12_SUPPORT(): SdFatConfig.h'],['../_fat_lib_config_8h.html#a28998c5daf4bd038f4f93172698320b1',1,'FAT12_SUPPORT(): FatLibConfig.h']]], + ['fat12eoc',['FAT12EOC',['../_fat_structs_8h.html#af314c45d1d37d09c9e44847326232466',1,'FatStructs.h']]], + ['fat12eoc_5fmin',['FAT12EOC_MIN',['../_fat_structs_8h.html#a48951911b522ebf72bf5561c3402aa15',1,'FatStructs.h']]], + ['fat16',['fat16',['../unioncache__t.html#a8f3a4e9392a7d8ace954fc44c57df887',1,'cache_t']]], + ['fat16eoc',['FAT16EOC',['../_fat_structs_8h.html#afcd95ebc621a46c82b9997c8b9208550',1,'FatStructs.h']]], + ['fat16eoc_5fmin',['FAT16EOC_MIN',['../_fat_structs_8h.html#a2f549b850b74666ba7d922bcb373896e',1,'FatStructs.h']]], + ['fat32',['fat32',['../unioncache__t.html#a57e16421bf460d1ba6cb9ce9a23a4a83',1,'cache_t']]], + ['fat32_5fboot',['fat32_boot',['../structfat32__boot.html',1,'']]], + ['fat32_5fboot_5ft',['fat32_boot_t',['../_fat_structs_8h.html#a38fa081d004647a828095d31b07ec491',1,'FatStructs.h']]], + ['fat32_5ffsinfo',['fat32_fsinfo',['../structfat32__fsinfo.html',1,'']]], + ['fat32_5ffsinfo_5ft',['fat32_fsinfo_t',['../_fat_structs_8h.html#a6030ed0fce3a819326a2548407fc8556',1,'FatStructs.h']]], + ['fat32backbootblock',['fat32BackBootBlock',['../structbios_parm_block.html#a7a4e93790b6e66f090c1551020b099bd',1,'biosParmBlock::fat32BackBootBlock()'],['../structfat32__boot.html#ac93acdae62dab5cd1f7a35187992dbf2',1,'fat32_boot::fat32BackBootBlock()']]], + ['fat32eoc',['FAT32EOC',['../_fat_structs_8h.html#a67a9dbf970f43fadd41a6a9fede60c47',1,'FatStructs.h']]], + ['fat32eoc_5fmin',['FAT32EOC_MIN',['../_fat_structs_8h.html#a8f97a312e990c3f4faf7e98c3256aae5',1,'FatStructs.h']]], + ['fat32flags',['fat32Flags',['../structbios_parm_block.html#a626ac3dc473d764688b8171916eecf44',1,'biosParmBlock::fat32Flags()'],['../structfat32__boot.html#aaa31a140202021bf33aed72765531b3f',1,'fat32_boot::fat32Flags()']]], + ['fat32fsinfo',['fat32FSInfo',['../structbios_parm_block.html#a25ea392d8284e6c1d007cb8fcad4b86c',1,'biosParmBlock::fat32FSInfo()'],['../structfat32__boot.html#a03ff6d1197c08688f20c7aad40206bc4',1,'fat32_boot::fat32FSInfo()']]], + ['fat32mask',['FAT32MASK',['../_fat_structs_8h.html#a7491c79fff0bda3b026ffa098a28d6df',1,'FatStructs.h']]], + ['fat32reserved',['fat32Reserved',['../structbios_parm_block.html#a351f87fe3446b1a71963a30bbdc23218',1,'biosParmBlock::fat32Reserved()'],['../structfat32__boot.html#a3343ad07c664fb7564d68c5194ea7da9',1,'fat32_boot::fat32Reserved()']]], + ['fat32rootcluster',['fat32RootCluster',['../structbios_parm_block.html#a77ca01bd99f746e05dd872cbd2979937',1,'biosParmBlock::fat32RootCluster()'],['../structfat32__boot.html#aa216677f22a95dd86ed2e61604883a13',1,'fat32_boot::fat32RootCluster()']]], + ['fat32version',['fat32Version',['../structbios_parm_block.html#abad4f6f0c14dad9f5b7d43de94e685e8',1,'biosParmBlock::fat32Version()'],['../structfat32__boot.html#a29c37e1163772493efb524c5ca0e1aa8',1,'fat32_boot::fat32Version()']]], + ['fat_5fboot',['fat_boot',['../structfat__boot.html',1,'']]], + ['fat_5fboot_5ft',['fat_boot_t',['../_fat_structs_8h.html#aedac4595ee08198da26c14b9891a07d5',1,'FatStructs.h']]], + ['fat_5fdate',['FAT_DATE',['../_fat_structs_8h.html#a44899ad42ddf32ff1c1a73b5251b304a',1,'FatStructs.h']]], + ['fat_5fday',['FAT_DAY',['../_fat_structs_8h.html#a4cc8bc105529bf9e9c11e8ef099d68b0',1,'FatStructs.h']]], + ['fat_5fdefault_5fdate',['FAT_DEFAULT_DATE',['../_fat_structs_8h.html#a42eeb0322bced1f7b527c707f8bd54a4',1,'FatStructs.h']]], + ['fat_5fdefault_5ftime',['FAT_DEFAULT_TIME',['../_fat_structs_8h.html#a23c2510407ec3be457e0e4807644deb2',1,'FatStructs.h']]], + ['fat_5fhour',['FAT_HOUR',['../_fat_structs_8h.html#ae7c733d49a5570054f6db3bd53332ba1',1,'FatStructs.h']]], + ['fat_5fminute',['FAT_MINUTE',['../_fat_structs_8h.html#a1b09676a41ae6c9e19664bdcd5b1d34e',1,'FatStructs.h']]], + ['fat_5fmonth',['FAT_MONTH',['../_fat_structs_8h.html#a429bc2d96f5bc26dc3bd6cc2bd535b84',1,'FatStructs.h']]], + ['fat_5fsecond',['FAT_SECOND',['../_fat_structs_8h.html#a4d553e2088d42e01d6c08ee84e611b00',1,'FatStructs.h']]], + ['fat_5ftime',['FAT_TIME',['../_fat_structs_8h.html#a375720927be5a39475d48b2d75dae29a',1,'FatStructs.h']]], + ['fat_5fyear',['FAT_YEAR',['../_fat_structs_8h.html#a279a75f907dd2603543c7bdad00ff603',1,'FatStructs.h']]], + ['fatcache',['FatCache',['../class_fat_cache.html',1,'']]], + ['fatcount',['fatCount',['../structbios_parm_block.html#a7c03f147c3fb18f0df03d346050af13b',1,'biosParmBlock::fatCount()'],['../structfat__boot.html#a04d3b6a45acf28a80ff909dc1b33da2f',1,'fat_boot::fatCount()'],['../structfat32__boot.html#a7882fa8744bd171bfa1512bd442574bc',1,'fat32_boot::fatCount()'],['../class_fat_volume.html#acdedc6a200b01e401c9cd9b511eae6ec',1,'FatVolume::fatCount()']]], + ['fatfile',['FatFile',['../class_fat_file.html',1,'FatFile'],['../class_fat_file.html#a7b591c9b92165fa8e4eae8c30c30e533',1,'FatFile::FatFile()'],['../class_fat_file.html#a29d31067d0aa3a9a74b1a660c38775cc',1,'FatFile::FatFile(const char *path, uint8_t oflag)']]], + ['fatfile_2eh',['FatFile.h',['../_fat_file_8h.html',1,'']]], + ['fatfilesystem',['FatFileSystem',['../class_fat_file_system.html',1,'']]], + ['fatfilesystem_2eh',['FatFileSystem.h',['../_fat_file_system_8h.html',1,'']]], + ['fatlibconfig_2eh',['FatLibConfig.h',['../_fat_lib_config_8h.html',1,'']]], + ['fatpos_5ft',['FatPos_t',['../struct_fat_pos__t.html',1,'']]], + ['fatstartblock',['fatStartBlock',['../class_fat_volume.html#a0dd0cc689b63ef0702aed1cf36b1722d',1,'FatVolume']]], + ['fatstreambase',['FatStreamBase',['../class_fat_stream_base.html',1,'']]], + ['fatstructs_2eh',['FatStructs.h',['../_fat_structs_8h.html',1,'']]], + ['fattype',['fatType',['../class_fat_volume.html#a1364f11fe9bb4717ce0685e2b7b86027',1,'FatVolume']]], + ['fatvolume',['FatVolume',['../class_fat_volume.html',1,'FatVolume'],['../class_fat_volume.html#a026de2bb58026e4edea130db2949b84c',1,'FatVolume::FatVolume()']]], + ['fatvolume_2eh',['FatVolume.h',['../_fat_volume_8h.html',1,'']]], + ['fbs',['fbs',['../unioncache__t.html#ad1a4f1c0e8b8ca4d530427dbc920c764',1,'cache_t']]], + ['fbs32',['fbs32',['../unioncache__t.html#ad0613173ed4e83920eedfeb33102848a',1,'cache_t']]], + ['fclose',['fclose',['../class_stdio_stream.html#a4ddd4658d49182013d2fa2a181e96c5a',1,'StdioStream']]], + ['feof',['feof',['../class_stdio_stream.html#acb38c3211feedbf2206eb1d9a3a9d24f',1,'StdioStream']]], + ['ferror',['ferror',['../class_stdio_stream.html#afd64cec6440b923660b444f6d5f0586e',1,'StdioStream']]], + ['fflush',['fflush',['../class_stdio_stream.html#a7ce32ec7ea3f2fd8ea42b9633890f1c0',1,'StdioStream']]], + ['fgetc',['fgetc',['../class_stdio_stream.html#a160bd2828cb7e7370cffe1046eff8899',1,'StdioStream']]], + ['fgets',['fgets',['../class_fat_file.html#a31ef26b3ee37cf5f5f4c6024c0ddab69',1,'FatFile::fgets()'],['../class_stdio_stream.html#aa240c1021a1aad1cc57f63a483541dc7',1,'StdioStream::fgets()']]], + ['file',['File',['../class_file.html',1,'File'],['../class_file.html#a9ecb14efb960d1369926182479f56213',1,'File::File()']]], + ['file_5fread',['FILE_READ',['../_arduino_files_8h.html#ad52d51659a75e25d96fb04d22ff718cb',1,'ArduinoFiles.h']]], + ['file_5fwrite',['FILE_WRITE',['../_arduino_files_8h.html#ace34e503254fa9004599ddf122264c8f',1,'ArduinoFiles.h']]], + ['fileattr',['fileAttr',['../class_fat_file.html#a7e043dfb89d268bfd620bbbadacf1002',1,'FatFile']]], + ['filesize',['fileSize',['../structdirectory_entry.html#ac2445d99b50f925f662952e0ccd26a02',1,'directoryEntry::fileSize()'],['../class_fat_file.html#a02fc3b3ca36b4745f695f3de8c8ec36d',1,'FatFile::fileSize()']]], + ['filesystemtype',['fileSystemType',['../structfat__boot.html#aee529e32908406866f3ec3c17c4632fa',1,'fat_boot::fileSystemType()'],['../structfat32__boot.html#a13ee6c63e17d634b6826bfdfa94cbd78',1,'fat32_boot::fileSystemType()']]], + ['fill',['fill',['../classios__base.html#ade5bd46462e075999c3a5c2cff2015f1',1,'ios_base::fill()'],['../classios__base.html#aa5683f9bdf295311bd5a6d3cdc2fedd5',1,'ios_base::fill(char c)']]], + ['firstblock',['firstBlock',['../class_fat_file.html#ac87b753811e540c7b799da56fa89724b',1,'FatFile']]], + ['firstcluster',['firstCluster',['../class_fat_file.html#a1057bc23b92a074539f661e896e79a09',1,'FatFile']]], + ['firstclusterhigh',['firstClusterHigh',['../structdirectory_entry.html#a3b492598b2b05e8425d2a500443613bd',1,'directoryEntry']]], + ['firstclusterlow',['firstClusterLow',['../structdirectory_entry.html#a74bd660417a9c3501eae353326c14bb9',1,'directoryEntry']]], + ['firstsector',['firstSector',['../structpartition_table.html#a02bbdff840c854dc96fa0b6da8589d86',1,'partitionTable']]], + ['flags',['flags',['../structfname__t.html#a39c69edff13165c6e03b308104e7286d',1,'fname_t::flags()'],['../classios__base.html#ab5e9c7dbcbc33b7de9dcb70525ec7384',1,'ios_base::flags() const '],['../classios__base.html#ae67e900dc12e4c7cbc0741ad1c70d6c2',1,'ios_base::flags(fmtflags fl)']]], + ['flush',['flush',['../class_minimum_serial.html#a872f0ff70f0e256352004f83d13fff28',1,'MinimumSerial::flush()'],['../class_print_file.html#a53c4cb94af030fdf83a9160ec9a96949',1,'PrintFile::flush()'],['../class_file.html#af87fa862de707575b8badd044a5af80e',1,'File::flush()'],['../classostream.html#af6be1f30d824f5a65d27d5b5d20b8c6c',1,'ostream::flush()'],['../iostream_8h.html#a2f6f5344fca38fd4fe7b6231fd992a0d',1,'flush(): iostream.h']]], + ['fmtflags',['fmtflags',['../classios__base.html#ac9a54e52cef4f01ac0afd8ae896a3413',1,'ios_base']]], + ['fname_5fflag_5flc_5fbase',['FNAME_FLAG_LC_BASE',['../_fat_file_8h.html#a79e43960e1b4eecf274f5faea9c3168c',1,'FatFile.h']]], + ['fname_5fflag_5flc_5fext',['FNAME_FLAG_LC_EXT',['../_fat_file_8h.html#a135b7572768b09661aa38afaceec7296',1,'FatFile.h']]], + ['fname_5fflag_5flost_5fchars',['FNAME_FLAG_LOST_CHARS',['../_fat_file_8h.html#acd45286b7dfc5ba68be18c8c3a9d298d',1,'FatFile.h']]], + ['fname_5fflag_5fmixed_5fcase',['FNAME_FLAG_MIXED_CASE',['../_fat_file_8h.html#a63994c21f3b723a55247f063a1b01c9c',1,'FatFile.h']]], + ['fname_5fflag_5fneed_5flfn',['FNAME_FLAG_NEED_LFN',['../_fat_file_8h.html#a1a041207a19d2fd9a1e2739343ccb29b',1,'FatFile.h']]], + ['fname_5ft',['fname_t',['../structfname__t.html',1,'']]], + ['fopen',['fopen',['../class_stdio_stream.html#a4ffc37225fb6deed98905aa71d1f9c4b',1,'StdioStream']]], + ['fputc',['fputc',['../class_stdio_stream.html#a9f23cfa6b112a5da6ae08340af23c57b',1,'StdioStream']]], + ['fputs',['fputs',['../class_stdio_stream.html#a6adea52f55ef7d97cdb54e9e11fc2daa',1,'StdioStream']]], + ['fread',['fread',['../class_stdio_stream.html#a2d363b02abcef82b25ff025d50375bce',1,'StdioStream']]], + ['freeclustercount',['freeClusterCount',['../class_fat_volume.html#a1683b063fc6202ab85470b9610f16f93',1,'FatVolume']]], + ['freecount',['freeCount',['../structfat32__fsinfo.html#a6c2d84388c0a38a74f7682fd602492c7',1,'fat32_fsinfo']]], + ['freestack',['FreeStack',['../_free_stack_8h.html#a2c0121d5649d35329a8d0a71e4ffb89b',1,'FreeStack.h']]], + ['freestack_2eh',['FreeStack.h',['../_free_stack_8h.html',1,'']]], + ['fsbegin',['fsBegin',['../class_sd_fat.html#add6a9a3ad07585f6e0e5c35e35cacb9a',1,'SdFat::fsBegin()'],['../class_sd_fat_sdio.html#aac0e8d86182a0e0566c4671c15f3df61',1,'SdFatSdio::fsBegin()']]], + ['fseek',['fseek',['../class_stdio_stream.html#a71584fd5c5cda3c31ce6cdbcc56f104d',1,'StdioStream']]], + ['fsinfo',['fsinfo',['../unioncache__t.html#a46c7b14586a6248824a97101111cbae1',1,'cache_t']]], + ['fsinfo_5flead_5fsig',['FSINFO_LEAD_SIG',['../_fat_structs_8h.html#a7a7a74a7315ad523e3b0c9dbd44d9a32',1,'FatStructs.h']]], + ['fsinfo_5fstruct_5fsig',['FSINFO_STRUCT_SIG',['../_fat_structs_8h.html#a9bf6b77df7bec6c49d81562c54371e81',1,'FatStructs.h']]], + ['fstream',['fstream',['../classfstream.html',1,'fstream'],['../classfstream.html#aed23877c52f828cab8de7a23603b3b6c',1,'fstream::fstream()']]], + ['fstream_2eh',['fstream.h',['../fstream_8h.html',1,'']]], + ['ftell',['ftell',['../class_stdio_stream.html#a809639fc5fb4fa5b6789dc121659f386',1,'StdioStream']]], + ['fwrite',['fwrite',['../class_stdio_stream.html#ad79465afb52579cbc801f4585c3f9c25',1,'StdioStream']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_7.html b/libraries/SdFat/extras/html/search/all_7.html new file mode 100644 index 0000000..38c6c00 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_7.js b/libraries/SdFat/extras/html/search/all_7.js new file mode 100644 index 0000000..6f50794 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_7.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['gcount',['gcount',['../classistream.html#ad2b705d2f363ed59db6ac4046f78b4bb',1,'istream']]], + ['get',['get',['../classistream.html#a36573c9b7fc522e6c85a73221019fd11',1,'istream::get()'],['../classistream.html#a9c7313d6f21f1f7ac9b0e759e74b4db2',1,'istream::get(char &ch)'],['../classistream.html#a4247f47e388598c69ef3bd39ea4c056f',1,'istream::get(char *str, streamsize n, char delim= '\n')']]], + ['getc',['getc',['../class_stdio_stream.html#a28ba31e7b526607744bfa41844ffce31',1,'StdioStream']]], + ['geterror',['getError',['../class_fat_file.html#ad0dbbd083180f44c7a3ce7124d4ce19c',1,'FatFile']]], + ['getline',['getline',['../classistream.html#a7d86035d178e526283e5c7555ab7b243',1,'istream']]], + ['getname',['getName',['../class_fat_file.html#aafa565e286440aab612cdb430fc01da5',1,'FatFile']]], + ['getpos',['getpos',['../class_fat_file.html#aaa4f9886887947815a61eaf015996932',1,'FatFile']]], + ['getsfn',['getSFN',['../class_fat_file.html#aba30e92a66f8e0d2f815c85662772a58',1,'FatFile']]], + ['getwriteerror',['getWriteError',['../class_fat_file.html#a8062c0d3a118e8d77d0310418703d5f5',1,'FatFile']]], + ['good',['good',['../classios.html#a5fdf9247f642a7a5c5a21323ffd45366',1,'ios']]], + ['goodbit',['goodbit',['../classios__base.html#a07a00996a6e525b88bdfe7935d5ead05',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_8.html b/libraries/SdFat/extras/html/search/all_8.html new file mode 100644 index 0000000..2a22cd5 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_8.js b/libraries/SdFat/extras/html/search/all_8.js new file mode 100644 index 0000000..035f01b --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_8.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['halt',['halt',['../class_sys_call.html#a9b1ef8900e97f572ca561760b4dd4191',1,'SysCall']]], + ['headcount',['headCount',['../structbios_parm_block.html#a2324ca82e2a7da4d91f458fa32a6e239',1,'biosParmBlock::headCount()'],['../structfat__boot.html#ae31da876cd9f48de5268a129218df2c2',1,'fat_boot::headCount()'],['../structfat32__boot.html#a1a5298db692526bc64243766d6b54181',1,'fat32_boot::headCount()']]], + ['hex',['hex',['../classios__base.html#a3608e51eb0a80ea94ddadd5b713a3750',1,'ios_base::hex()'],['../ios_8h.html#ace2036d970905192360d622140bfe336',1,'hex(): ios.h']]], + ['hidddensectors',['hidddenSectors',['../structbios_parm_block.html#a9413199be8525190d40589f60c22bcab',1,'biosParmBlock::hidddenSectors()'],['../structfat__boot.html#a18f1b4c245fe7bd09f5a9430c005e23a',1,'fat_boot::hidddenSectors()'],['../structfat32__boot.html#ab10224aa4bba42b262fcd3479e279e1f',1,'fat32_boot::hidddenSectors()']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_9.html b/libraries/SdFat/extras/html/search/all_9.html new file mode 100644 index 0000000..bd9b05c --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_9.js b/libraries/SdFat/extras/html/search/all_9.js new file mode 100644 index 0000000..1bd0687 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_9.js @@ -0,0 +1,36 @@ +var searchData= +[ + ['ibufstream',['ibufstream',['../classibufstream.html',1,'ibufstream'],['../classibufstream.html#afe28f27d24a62a21428b60fe8834dd05',1,'ibufstream::ibufstream()'],['../classibufstream.html#a819561105ef7dc3828e0cfedfed708d8',1,'ibufstream::ibufstream(const char *str)']]], + ['ifstream',['ifstream',['../classifstream.html',1,'ifstream'],['../classifstream.html#a11f4bfaa5c37cfcf8878c367fd861a88',1,'ifstream::ifstream()']]], + ['ignore',['ignore',['../classistream.html#a12597b03d86b66047a5581bbd26eb032',1,'istream']]], + ['implement_5fspi_5fport_5fselection',['IMPLEMENT_SPI_PORT_SELECTION',['../_sd_fat_config_8h.html#aa13678c06fd801cb8f00b497a517d91e',1,'SdFatConfig.h']]], + ['in',['in',['../classios__base.html#ae5432e3c269064480652c4602f5f74ad',1,'ios_base']]], + ['init',['init',['../classibufstream.html#a1d7bae17d9d2c79218085251946f322a',1,'ibufstream::init()'],['../classobufstream.html#a8f75dbadab2fed7770d01a2cc2628258',1,'obufstream::init()'],['../class_fat_cache.html#ae1d8a2da1493b5ffca0520184daaddf1',1,'FatCache::init()'],['../class_fat_volume.html#acab819fa25a91dad1cc698a7e1e0eb32',1,'FatVolume::init()'],['../class_fat_volume.html#a034d997a1e7a0b2b664a4357bcccd256',1,'FatVolume::init(uint8_t part)']]], + ['initerrorhalt',['initErrorHalt',['../class_sd_file_system.html#a8e1f26486bb878a24fa9868e59dbbbc2',1,'SdFileSystem::initErrorHalt()'],['../class_sd_file_system.html#a24bd0f699cf0fe11fd2148b15c49251a',1,'SdFileSystem::initErrorHalt(Print *pr)'],['../class_sd_file_system.html#a893833a880e2a83757480ba4c1351041',1,'SdFileSystem::initErrorHalt(char const *msg)'],['../class_sd_file_system.html#a3077b1a53d789d0401b707963cb28f46',1,'SdFileSystem::initErrorHalt(Print *pr, char const *msg)'],['../class_sd_file_system.html#a2a1e4cc8056ba23b55dfa2c6486b8798',1,'SdFileSystem::initErrorHalt(const __FlashStringHelper *msg)'],['../class_sd_file_system.html#ab03d98012dea18733c3252f27832de69',1,'SdFileSystem::initErrorHalt(Print *pr, const __FlashStringHelper *msg)']]], + ['initerrorprint',['initErrorPrint',['../class_sd_file_system.html#ae31c9cbd7e1c03129d6c99b25f73cd50',1,'SdFileSystem::initErrorPrint()'],['../class_sd_file_system.html#a066707dce0667213b5f083d59f67448d',1,'SdFileSystem::initErrorPrint(Print *pr)'],['../class_sd_file_system.html#a538796f79fd9db9c5bbeefd9defe639a',1,'SdFileSystem::initErrorPrint(char const *msg)'],['../class_sd_file_system.html#ad9855d33ebd465715b706d0926291b13',1,'SdFileSystem::initErrorPrint(Print *pr, char const *msg)'],['../class_sd_file_system.html#ad6ffec5a7d82be46d46b8a4f82d0803b',1,'SdFileSystem::initErrorPrint(const __FlashStringHelper *msg)'],['../class_sd_file_system.html#a8a2018b6366145a9843d3d29a47d6560',1,'SdFileSystem::initErrorPrint(Print *pr, const __FlashStringHelper *msg)']]], + ['internal',['internal',['../classios__base.html#afc720b7f6f461ec8e9cf5505059e5d7c',1,'ios_base::internal()'],['../ios_8h.html#a8dd76c1ce8fced364a98428ca1eea7a6',1,'internal(): ios.h']]], + ['invalidate',['invalidate',['../class_fat_cache.html#a70071a128d647b49b523dbb2f5f944a5',1,'FatCache']]], + ['ios',['ios',['../classios.html',1,'ios'],['../classios.html#adc5dbd7b69da79493ebc84aa1e681aaa',1,'ios::ios()']]], + ['ios_2eh',['ios.h',['../ios_8h.html',1,'']]], + ['ios_5fbase',['ios_base',['../classios__base.html',1,'']]], + ['iostate',['iostate',['../classios__base.html#aef19291eeae0f072ac42c6ba1fe3033c',1,'ios_base']]], + ['iostream',['iostream',['../classiostream.html',1,'']]], + ['iostream_2eh',['iostream.h',['../iostream_8h.html',1,'']]], + ['is_5fopen',['is_open',['../classfstream.html#ae4a71c6f3da2f168ec222739d796fc8b',1,'fstream::is_open()'],['../classifstream.html#aaa16c6422ea371995d02159f2e6707b2',1,'ifstream::is_open()'],['../classofstream.html#a9c97eb2eb6e35ae87cf7f7453a67e70a',1,'ofstream::is_open()']]], + ['isbusy',['isBusy',['../class_sd_spi_card.html#aa3cb9139dbc1e6596c6717da2b486328',1,'SdSpiCard']]], + ['isdir',['isDir',['../class_fat_file.html#aef41d65e0f1ce753d18cc9ed691f7de4',1,'FatFile']]], + ['isdirectory',['isDirectory',['../class_file.html#a6ba5bdb943363cda56649238ccb18c27',1,'File']]], + ['isdirseparator',['isDirSeparator',['../_fat_file_8h.html#a9f85580ad6f1dfc86fff09a58ff0a1c0',1,'FatFile.h']]], + ['isfile',['isFile',['../class_fat_file.html#afcf6270ea8d4a3a5f8e89523bc684e22',1,'FatFile']]], + ['ishidden',['isHidden',['../class_fat_file.html#a7eefe7408f34b6326f0c6e78af7eb05f',1,'FatFile']]], + ['islfn',['isLFN',['../class_fat_file.html#aed36d17f8fde597b6ed9446faec1f7e3',1,'FatFile']]], + ['isopen',['isOpen',['../class_fat_file.html#a4c8a07b081f04aa25839c6f56c739bdc',1,'FatFile']]], + ['isreadonly',['isReadOnly',['../class_fat_file.html#a6872d3acb1e70f81c9c2be2495977583',1,'FatFile']]], + ['isroot',['isRoot',['../class_fat_file.html#aa4a206803a4bf8243be20244c1aef4d2',1,'FatFile']]], + ['isroot32',['isRoot32',['../class_fat_file.html#a1449b294e3a838396c62e47674ca8cf0',1,'FatFile']]], + ['isrootfixed',['isRootFixed',['../class_fat_file.html#a8215bd4b21e11ec83fa88ef226ceb06f',1,'FatFile']]], + ['issubdir',['isSubDir',['../class_fat_file.html#a95b503b17442c2b364a2f53de1b2aeba',1,'FatFile']]], + ['issystem',['isSystem',['../class_fat_file.html#add932e13e5bf32ad467af6ec34824e3c',1,'FatFile']]], + ['istream',['istream',['../classistream.html',1,'']]], + ['istream_2eh',['istream.h',['../istream_8h.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_a.html b/libraries/SdFat/extras/html/search/all_a.html new file mode 100644 index 0000000..4a25af1 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_a.js b/libraries/SdFat/extras/html/search/all_a.js new file mode 100644 index 0000000..e043c52 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['jump',['jump',['../structfat__boot.html#a83f9f2d1d0130f25f34c90dfc82e3751',1,'fat_boot::jump()'],['../structfat32__boot.html#a2d93fc193a64ecffbd71ead207fe4810',1,'fat32_boot::jump()']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_b.html b/libraries/SdFat/extras/html/search/all_b.html new file mode 100644 index 0000000..a92de48 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_b.js b/libraries/SdFat/extras/html/search/all_b.js new file mode 100644 index 0000000..aaf99c9 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_b.js @@ -0,0 +1,20 @@ +var searchData= +[ + ['lastaccessdate',['lastAccessDate',['../structdirectory_entry.html#abca70dc5c5fcbe199fd78df010111331',1,'directoryEntry']]], + ['lastwritedate',['lastWriteDate',['../structdirectory_entry.html#a12b2e7cf87482a942a0b5d3df6c51468',1,'directoryEntry']]], + ['lastwritetime',['lastWriteTime',['../structdirectory_entry.html#a7bab435322d1928f66fbce53ee1f402d',1,'directoryEntry']]], + ['lbn',['lbn',['../class_fat_cache.html#a9f981b53e212f79937e5f6381b169374',1,'FatCache']]], + ['ldir_5fname1_5fdim',['LDIR_NAME1_DIM',['../_fat_structs_8h.html#af843af29c67dd30ca7c5684806bf02fc',1,'FatStructs.h']]], + ['ldir_5fname2_5fdim',['LDIR_NAME2_DIM',['../_fat_structs_8h.html#a99cae591c59e261f54617617e173e7e0',1,'FatStructs.h']]], + ['ldir_5fname3_5fdim',['LDIR_NAME3_DIM',['../_fat_structs_8h.html#a99fbd27fa9e5003a8d77ca7fc14d2090',1,'FatStructs.h']]], + ['ldir_5ford_5flast_5flong_5fentry',['LDIR_ORD_LAST_LONG_ENTRY',['../_fat_structs_8h.html#a8cfb60b9eaf04dcdc6e4f5a466af5540',1,'FatStructs.h']]], + ['ldir_5ft',['ldir_t',['../_fat_structs_8h.html#aa1b540ee1eedd1aa9b267d11cba0d9e2',1,'FatStructs.h']]], + ['leadsignature',['leadSignature',['../structfat32__fsinfo.html#aa8ee056cc1beb1355e15610c1beba5e3',1,'fat32_fsinfo']]], + ['left',['left',['../classios__base.html#ad364df9af2cfde1f40bd8e10c62bb215',1,'ios_base::left()'],['../ios_8h.html#a24a80a73f0a0d2d72d1cb74f49ff4759',1,'left(): ios.h']]], + ['legal83char',['legal83Char',['../class_fat_file.html#a94df8090f16e9666cdc53ca20f6aff90',1,'FatFile']]], + ['len',['len',['../structfname__t.html#a471184cc4c2671526d7d6fb80b2fe20c',1,'fname_t']]], + ['length',['length',['../classobufstream.html#ac650708e968b0c0545a3badeb809cf15',1,'obufstream']]], + ['lfn',['lfn',['../structfname__t.html#a76ffd7abd5b7d3acf90b329c905770fd',1,'fname_t']]], + ['longdirectoryentry',['longDirectoryEntry',['../structlong_directory_entry.html',1,'']]], + ['ls',['ls',['../class_fat_file.html#ad49f688a494b351ccbb0102dcfafb925',1,'FatFile::ls(uint8_t flags=0)'],['../class_fat_file.html#acabf31ff85e696fbf384c49428012fea',1,'FatFile::ls(print_t *pr, uint8_t flags=0, uint8_t indent=0)'],['../class_fat_file_system.html#a2398fb37a7a9d5e0dc0ffde6a44a993d',1,'FatFileSystem::ls(uint8_t flags=0)'],['../class_fat_file_system.html#a122b61dbec5051304bcc81bc08b1b99d',1,'FatFileSystem::ls(const char *path, uint8_t flags=0)'],['../class_fat_file_system.html#ae12fb8bfad5c4a8e052dda70a5a0ed93',1,'FatFileSystem::ls(print_t *pr, uint8_t flags=0)'],['../class_fat_file_system.html#aa79695db8e910300507210b3067d39fd',1,'FatFileSystem::ls(print_t *pr, const char *path, uint8_t flags)']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_c.html b/libraries/SdFat/extras/html/search/all_c.html new file mode 100644 index 0000000..20cdfbc --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_c.js b/libraries/SdFat/extras/html/search/all_c.js new file mode 100644 index 0000000..30a4bf7 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_c.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['maintain_5ffree_5fcluster_5fcount',['MAINTAIN_FREE_CLUSTER_COUNT',['../_sd_fat_config_8h.html#ac2865dac8fdbb4fff47105db32ddf05b',1,'MAINTAIN_FREE_CLUSTER_COUNT(): SdFatConfig.h'],['../_fat_lib_config_8h.html#ac2865dac8fdbb4fff47105db32ddf05b',1,'MAINTAIN_FREE_CLUSTER_COUNT(): FatLibConfig.h']]], + ['masterbootrecord',['masterBootRecord',['../structmaster_boot_record.html',1,'']]], + ['mbr',['mbr',['../unioncache__t.html#a6ac10bfb1ebb1139c448456679663bb6',1,'cache_t']]], + ['mbr_5ft',['mbr_t',['../_fat_structs_8h.html#a7c429e5097f101c8c97663d6c4155bd9',1,'FatStructs.h']]], + ['mbrsig0',['mbrSig0',['../structmaster_boot_record.html#a42b0b413ecb21ac5314d4f6bca05308f',1,'masterBootRecord']]], + ['mbrsig1',['mbrSig1',['../structmaster_boot_record.html#aafbbcb4f6a2d1181c6458d4c9603df4f',1,'masterBootRecord']]], + ['mediatype',['mediaType',['../structbios_parm_block.html#a4237e7c3ba247516d546c149954e5042',1,'biosParmBlock::mediaType()'],['../structfat__boot.html#a63eaf7185663369af2527309634d3c90',1,'fat_boot::mediaType()'],['../structfat32__boot.html#a3b1ab5d2dc872c0d80cd4f34622de417',1,'fat32_boot::mediaType()']]], + ['minimumserial',['MinimumSerial',['../class_minimum_serial.html',1,'']]], + ['minimumserial_2eh',['MinimumSerial.h',['../_minimum_serial_8h.html',1,'']]], + ['mkdir',['mkdir',['../class_fat_file.html#abab5b9f72cc796388dd4eed01d13d90d',1,'FatFile::mkdir()'],['../class_fat_file_system.html#a231c62c98ba8ac3c2624dc5ad2053ebf',1,'FatFileSystem::mkdir()']]], + ['mustbezero',['mustBeZero',['../structlong_directory_entry.html#af3055930e869875e49b32ef0b49c3649',1,'longDirectoryEntry']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_d.html b/libraries/SdFat/extras/html/search/all_d.html new file mode 100644 index 0000000..00b28ed --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_d.js b/libraries/SdFat/extras/html/search/all_d.js new file mode 100644 index 0000000..8b100cc --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_d.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['name',['name',['../structdirectory_entry.html#a05dc993ea55a1a742de5970541a31ecb',1,'directoryEntry::name()'],['../class_file.html#a7ca23d8d3997c10c221977c64736f575',1,'File::name()']]], + ['name1',['name1',['../structlong_directory_entry.html#a629f1ca5ba2ccce6cac5295578b6e7b4',1,'longDirectoryEntry']]], + ['name2',['name2',['../structlong_directory_entry.html#ad763b5a3da4b8d326d9888493fbb819a',1,'longDirectoryEntry']]], + ['name3',['name3',['../structlong_directory_entry.html#a6f14c81b7d224dc4431217f92601257a',1,'longDirectoryEntry']]], + ['nextfree',['nextFree',['../structfat32__fsinfo.html#a539b3bb0a2ead9df417df9ac8b6b1606',1,'fat32_fsinfo']]], + ['noboolalpha',['noboolalpha',['../ios_8h.html#aa6a1ec04992fc8090ca775a39678be01',1,'ios.h']]], + ['noshowbase',['noshowbase',['../ios_8h.html#ab861ff5f863de0ae002b65390dde36b0',1,'ios.h']]], + ['noshowpoint',['noshowpoint',['../ios_8h.html#ad85399d1b75151cf9e2436f2a1ccfc13',1,'ios.h']]], + ['noshowpos',['noshowpos',['../ios_8h.html#a985805b22ffb4ce2f5298168662bd2d7',1,'ios.h']]], + ['noskipws',['noskipws',['../ios_8h.html#a773b847300db776fde08a0b562792131',1,'ios.h']]], + ['nouppercase',['nouppercase',['../ios_8h.html#a24b96fb317e056b34aa84c4bb965a79a',1,'ios.h']]], + ['null',['NULL',['../_stdio_stream_8h.html#a070d2ce7b6bb7e5c05602aa8c308d0c4',1,'StdioStream.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_e.html b/libraries/SdFat/extras/html/search/all_e.html new file mode 100644 index 0000000..07d5259 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_e.js b/libraries/SdFat/extras/html/search/all_e.js new file mode 100644 index 0000000..18ca515 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_e.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['obufstream',['obufstream',['../classobufstream.html',1,'obufstream'],['../classobufstream.html#a74f7dbcf1131b77d3665aa85d6629722',1,'obufstream::obufstream()'],['../classobufstream.html#a7af0555c5c08ebf9cbc70fc5e2f67db7',1,'obufstream::obufstream(char *buf, size_t size)']]], + ['oct',['oct',['../classios__base.html#a4155540f8d3ffdb8d25a2f50ee4df08f',1,'ios_base::oct()'],['../ios_8h.html#ae661b435df22f8e8e643817f4f915123',1,'oct(): ios.h']]], + ['oemid',['oemId',['../structfat__boot.html#adc034212201e879fea1eb44db43e55a5',1,'fat_boot::oemId()'],['../structfat32__boot.html#af623a473a960ea20904dce0edfb6bb9d',1,'fat32_boot::oemId()']]], + ['off_5ftype',['off_type',['../classios__base.html#a45de7cca0d01da781f4b886179c65c22',1,'ios_base']]], + ['ofstream',['ofstream',['../classofstream.html',1,'ofstream'],['../classofstream.html#ae8a8145adf2cfe1f948ad482ed504b75',1,'ofstream::ofstream()']]], + ['open',['open',['../class_fat_file.html#a5f64576d3d19177ab3cf3812b69abdfa',1,'FatFile::open(FatFileSystem *fs, const char *path, uint8_t oflag)'],['../class_fat_file.html#ad3fa9daaccb4e4179fb88a8ca037aa80',1,'FatFile::open(FatFile *dirFile, uint16_t index, uint8_t oflag)'],['../class_fat_file.html#a211be757679b18708f6b6a36464e4f61',1,'FatFile::open(FatFile *dirFile, const char *path, uint8_t oflag)'],['../class_fat_file.html#ab0e7075062c89f356441f80fc64d03e6',1,'FatFile::open(const char *path, uint8_t oflag=O_READ)'],['../class_fat_file_system.html#a947e4586077a922892b632edac33b67a',1,'FatFileSystem::open(const char *path, uint8_t mode=FILE_READ)'],['../class_fat_file_system.html#a0abfb1f754a8fb559cfa884ee040f56f',1,'FatFileSystem::open(const String &path, uint8_t mode=FILE_READ)'],['../classfstream.html#a85b24d94552991f33caf4c3a83420879',1,'fstream::open()'],['../classifstream.html#a169694d6535fd551fd6db48a2867590e',1,'ifstream::open()'],['../classofstream.html#a4b9d30c742fbe01baa336406c7afdcb2',1,'ofstream::open()']]], + ['openmode',['openmode',['../classios__base.html#aaa192ec0dccc43050715553a34644523',1,'ios_base']]], + ['opennext',['openNext',['../class_fat_file.html#a8034c4649eb0d26715b1a8a69e73d9d0',1,'FatFile']]], + ['opennextfile',['openNextFile',['../class_file.html#acd72000ab1f6a1ce73ac8fbdc854ae0c',1,'File']]], + ['openroot',['openRoot',['../class_fat_file.html#a7e0c0548fed3a69e7284b91b694439d4',1,'FatFile']]], + ['operator_20bool',['operator bool',['../class_minimum_serial.html#a73a1a2a92604ecb8507afde0022aedd8',1,'MinimumSerial::operator bool()'],['../class_file.html#af171fbf441c899cf71d88b8b0b83d38b',1,'File::operator bool()']]], + ['operator_20const_20void_20_2a',['operator const void *',['../classios.html#a8c2e7e42e31d3d7898a51c0bc837b2a3',1,'ios']]], + ['operator_21',['operator!',['../classios.html#a1ae2d4f1ccdfcaaef6a3a8ac9e28c267',1,'ios']]], + ['operator_3c_3c',['operator<<',['../classostream.html#a4dfc0cdb38bced959ba7cf963db38c30',1,'ostream::operator<<(ostream &(*pf)(ostream &str))'],['../classostream.html#af52c607ea168aff1025222c62cad392f',1,'ostream::operator<<(ios_base &(*pf)(ios_base &str))'],['../classostream.html#a63e3999be154253cf92a45c22e548f51',1,'ostream::operator<<(bool arg)'],['../classostream.html#a618b5d6861dde2347847102b89e0ccfa',1,'ostream::operator<<(const char *arg)'],['../classostream.html#aebe24ff723b806cbee19deb2165d0a5b',1,'ostream::operator<<(const signed char *arg)'],['../classostream.html#ac0cf68ffa4706994f47acb1fa37c601a',1,'ostream::operator<<(const unsigned char *arg)'],['../classostream.html#a1d1e11d2fadaf4c9e34194a1f28572e4',1,'ostream::operator<<(char arg)'],['../classostream.html#ad06f8c6c47667e9c7b14620882c09434',1,'ostream::operator<<(signed char arg)'],['../classostream.html#a69912ec4a8536f289b716e95953d09d7',1,'ostream::operator<<(unsigned char arg)'],['../classostream.html#a8065697d56d5e5d1a0ca50c1916b4955',1,'ostream::operator<<(double arg)'],['../classostream.html#a6c68e418e19d9dcdfe6b1790b2621666',1,'ostream::operator<<(float arg)'],['../classostream.html#a227c47e2b631f29d8873b00290bb4872',1,'ostream::operator<<(short arg)'],['../classostream.html#ace10a3a767dc55faff2cec71cd0a89b1',1,'ostream::operator<<(unsigned short arg)'],['../classostream.html#a62488f7ce7822c777ea27d15223b8e5f',1,'ostream::operator<<(int arg)'],['../classostream.html#ad31df6cd88c7248c01808e40889a7907',1,'ostream::operator<<(unsigned int arg)'],['../classostream.html#a15db9977ed82e503bd3cd1f585acf9e6',1,'ostream::operator<<(long arg)'],['../classostream.html#aaedd44fefa48cf3f0967fcd699a2909d',1,'ostream::operator<<(unsigned long arg)'],['../classostream.html#a2a8febd7c07f078120dd69bb71f25a94',1,'ostream::operator<<(const void *arg)'],['../classostream.html#a99ee8d9265d9354f197d02a3d17116be',1,'ostream::operator<<(const __FlashStringHelper *arg)'],['../iostream_8h.html#aa125ac928f3377cbc6e3cf288b9378fd',1,'operator<<(ostream &os, const setfill &arg): iostream.h'],['../iostream_8h.html#a23d4c29ef8ae37ec7d972d0b66187652',1,'operator<<(ostream &os, const setprecision &arg): iostream.h'],['../iostream_8h.html#a331649f2fdb01ed069dc18a5fad781b1',1,'operator<<(ostream &os, const setw &arg): iostream.h']]], + ['operator_3e_3e',['operator>>',['../classistream.html#aa67d3b8ac67e2097d876a66657ec6067',1,'istream::operator>>(istream &(*pf)(istream &str))'],['../classistream.html#ac6e2f17c80edd19deecdc20f804c424e',1,'istream::operator>>(ios_base &(*pf)(ios_base &str))'],['../classistream.html#a5a0a2c0e06abadb79951ebe34f36d62a',1,'istream::operator>>(ios &(*pf)(ios &str))'],['../classistream.html#a99db66d2e192f02deff0171ad098271f',1,'istream::operator>>(char *str)'],['../classistream.html#addaf5e0f39a15cc213117165dfef0d77',1,'istream::operator>>(char &ch)'],['../classistream.html#a390af4d28adbdc537e436f2121d1c862',1,'istream::operator>>(signed char *str)'],['../classistream.html#a49ab1a573fbf69809d19a52855a30072',1,'istream::operator>>(signed char &ch)'],['../classistream.html#a52e85d01198968330f20026a52cb9f72',1,'istream::operator>>(unsigned char *str)'],['../classistream.html#a74875fcf9ccdc0dca4b46a0b66821798',1,'istream::operator>>(unsigned char &ch)'],['../classistream.html#a3708636d095d360695e9c23335639317',1,'istream::operator>>(bool &arg)'],['../classistream.html#a662060e885a0551c390b7042b3b9e4a5',1,'istream::operator>>(short &arg)'],['../classistream.html#a31a706a374c5a594e400734b8992e2a0',1,'istream::operator>>(unsigned short &arg)'],['../classistream.html#ae8451bc86d83828892d9d67c67b7f02b',1,'istream::operator>>(int &arg)'],['../classistream.html#a35c9847ebf7b822c5ec9742e9de19345',1,'istream::operator>>(unsigned int &arg)'],['../classistream.html#aa26e7f35e74d96803bb0dfb3fb0dc154',1,'istream::operator>>(long &arg)'],['../classistream.html#a5aafa4c7f6615a7f1441962b61b8ef59',1,'istream::operator>>(unsigned long &arg)'],['../classistream.html#af9bf453725ce1d9ef62142a7ee38936e',1,'istream::operator>>(double &arg)'],['../classistream.html#aa8efce6fecab80cf7a17d5dfa31f5aa8',1,'istream::operator>>(float &arg)'],['../classistream.html#a62ef4762feacc64a8acdcbf8f1296936',1,'istream::operator>>(void *&arg)'],['../iostream_8h.html#a4a4079de901e0f3f10c743115bd345b2',1,'operator>>(istream &obj, const setfill &arg): iostream.h'],['../iostream_8h.html#a2f819cd0ccda31a8b648f20534469308',1,'operator>>(istream &is, const setprecision &arg): iostream.h'],['../iostream_8h.html#a8d1b3da6f1074322a6e9e11ff4ce8c33',1,'operator>>(istream &is, const setw &arg): iostream.h']]], + ['ord',['ord',['../structlong_directory_entry.html#a1b65e85dd63d0708cd1b875ce4e5e338',1,'longDirectoryEntry']]], + ['ostream',['ostream',['../classostream.html',1,'']]], + ['ostream_2eh',['ostream.h',['../ostream_8h.html',1,'']]], + ['out',['out',['../classios__base.html#a4c1d517774c0d11af3424e90395f26ae',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/all_f.html b/libraries/SdFat/extras/html/search/all_f.html new file mode 100644 index 0000000..2213eb2 --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/all_f.js b/libraries/SdFat/extras/html/search/all_f.js new file mode 100644 index 0000000..6392abf --- /dev/null +++ b/libraries/SdFat/extras/html/search/all_f.js @@ -0,0 +1,33 @@ +var searchData= +[ + ['p',['p',['../structsetprecision.html#a7cb7bb355a303fa39a8035615bde9348',1,'setprecision']]], + ['part',['part',['../structmaster_boot_record.html#aa4e294e50f311635c10c92f4c99227c5',1,'masterBootRecord']]], + ['part_5ft',['part_t',['../_fat_structs_8h.html#a37251e7d5c69a159be727a3fc8c9d0e6',1,'FatStructs.h']]], + ['partitiontable',['partitionTable',['../structpartition_table.html',1,'']]], + ['peek',['peek',['../class_print_file.html#a3a2a66f4a0cb69ab4edc66d39997fda7',1,'PrintFile::peek()'],['../class_file.html#a0e5025f39bd584563bfe4b05fc1db268',1,'File::peek()'],['../class_fat_file.html#ac05b7136b887539426856c623869aa3a',1,'FatFile::peek()'],['../classistream.html#a4022265e0ede3698454f1ff59348c14a',1,'istream::peek()']]], + ['pgm_5fread_5fbyte',['pgm_read_byte',['../_fat_file_8h.html#a48c60b057902adf805797f183286728d',1,'FatFile.h']]], + ['pgm_5fread_5fword',['pgm_read_word',['../_fat_file_8h.html#a910fb5f01313d339d3b835d45e1e5ad0',1,'FatFile.h']]], + ['pos_5ftype',['pos_type',['../classios__base.html#abe85cf1f181b8bce8022f05ab76aae7f',1,'ios_base']]], + ['position',['position',['../struct_fat_pos__t.html#a8e14c6f2705777502b543452743eaa26',1,'FatPos_t::position()'],['../class_file.html#aae991c597c0bc4c5eb44c1f3b06a21ec',1,'File::position()']]], + ['precision',['precision',['../classios__base.html#a9d36cb5a859b74e04f640d2f5e53b41d',1,'ios_base::precision() const '],['../classios__base.html#a5b70cc65fc2c276136fea99bddedb6f0',1,'ios_base::precision(unsigned int n)']]], + ['print',['print',['../class_stdio_stream.html#ad3f6ee8e8ca5dcf6dabfd88199b172e2',1,'StdioStream::print(char c)'],['../class_stdio_stream.html#a1158ea5f9bf041f21b1733b7811c9bb9',1,'StdioStream::print(const char *str)'],['../class_stdio_stream.html#aac4d7b3548d03b8fd70adf12c7ee315c',1,'StdioStream::print(const __FlashStringHelper *str)'],['../class_stdio_stream.html#a26f5b98560b6771225005b073166108b',1,'StdioStream::print(double val, uint8_t prec=2)'],['../class_stdio_stream.html#a06b6eb9f0a7000fdcc73cd6af8d40560',1,'StdioStream::print(float val, uint8_t prec=2)'],['../class_stdio_stream.html#a7129f85c7c5f16867f467731ef84dee9',1,'StdioStream::print(T val)']]], + ['print_5ft',['print_t',['../_fat_volume_8h.html#ac62f6449331cfe1a71f29be30efe7890',1,'FatVolume.h']]], + ['printcreatedatetime',['printCreateDateTime',['../class_fat_file.html#a558530f20314a8d8ee3d1a488fc7f46e',1,'FatFile']]], + ['printdec',['printDec',['../class_stdio_stream.html#ac0a907feb1e4b7e00de99857b4c0a470',1,'StdioStream::printDec(char n)'],['../class_stdio_stream.html#a2707ea97f6113c226781469f4f39ff62',1,'StdioStream::printDec(signed char n)'],['../class_stdio_stream.html#a6e6ac78caa6259a4c4934707bf497a2b',1,'StdioStream::printDec(unsigned char n)'],['../class_stdio_stream.html#a218af88db35f38babf01d6e0a9cdceeb',1,'StdioStream::printDec(int16_t n)'],['../class_stdio_stream.html#a90b2999af94a3578fff7579c2acf8e35',1,'StdioStream::printDec(uint16_t n)'],['../class_stdio_stream.html#ad4591f1234b57f63c1acf0f3392099ac',1,'StdioStream::printDec(int32_t n)'],['../class_stdio_stream.html#a8b6c2c80342abe45e6f564e9bd5bb7ea',1,'StdioStream::printDec(uint32_t n)'],['../class_stdio_stream.html#aaa8921947d4dbbae840d285cb633e8aa',1,'StdioStream::printDec(double value, uint8_t prec)'],['../class_stdio_stream.html#a6a09284b1c6d0769c27916a2e131e749',1,'StdioStream::printDec(float value, uint8_t prec)']]], + ['printfatdate',['printFatDate',['../class_fat_file.html#a8fdb038aafdf3a17ac80b53c063aa73b',1,'FatFile::printFatDate(uint16_t fatDate)'],['../class_fat_file.html#ada5364f66204b1a64afbf9d2e6cd2b0b',1,'FatFile::printFatDate(print_t *pr, uint16_t fatDate)']]], + ['printfattime',['printFatTime',['../class_fat_file.html#a7740731f08ef97de7dfbc9b075c4c7d1',1,'FatFile::printFatTime(uint16_t fatTime)'],['../class_fat_file.html#a4e7e56ba52ca17c602af1b85684b09a9',1,'FatFile::printFatTime(print_t *pr, uint16_t fatTime)']]], + ['printfield',['printField',['../class_fat_file.html#a7478cad0f9e5079311b9e1fa558016ff',1,'FatFile::printField(float value, char term, uint8_t prec=2)'],['../class_fat_file.html#abd3e1747511216462b3ef98167156cbb',1,'FatFile::printField(int16_t value, char term)'],['../class_fat_file.html#a9972c2419c293ef9c382bff666b9ae4d',1,'FatFile::printField(uint16_t value, char term)'],['../class_fat_file.html#a41b3b32dd8482429b74c7af3432d6cf8',1,'FatFile::printField(int32_t value, char term)'],['../class_fat_file.html#a097240f08baadeb1c64b63eab9afb088',1,'FatFile::printField(uint32_t value, char term)'],['../class_stdio_stream.html#a4988592ada39c4b4c603b061f84d183f',1,'StdioStream::printField(double value, char term, uint8_t prec=2)'],['../class_stdio_stream.html#a3b90b2317cc391f94784a847f5313c08',1,'StdioStream::printField(float value, char term, uint8_t prec=2)'],['../class_stdio_stream.html#a02c2ad1a2e71e82d238b8386cf3e6c41',1,'StdioStream::printField(T value, char term)']]], + ['printfile',['PrintFile',['../class_print_file.html',1,'PrintFile'],['../class_print_file.html#adc3bcb2a5c4207de7ff7e9be3ac54233',1,'PrintFile::PrintFile()']]], + ['printfilesize',['printFileSize',['../class_fat_file.html#a12a5d2de2737c201aa39ca1bd2ab9c47',1,'FatFile']]], + ['printhex',['printHex',['../class_stdio_stream.html#add39b2b4ec3daa7c8922e96ce5d368bc',1,'StdioStream']]], + ['printhexln',['printHexln',['../class_stdio_stream.html#aec6ebea511489b0ef6b61d9132d93af9',1,'StdioStream']]], + ['println',['println',['../class_stdio_stream.html#ad0cd3acc05a91456f505752377bd405a',1,'StdioStream::println()'],['../class_stdio_stream.html#a3793dd66cf347a1ca0b7b167e948cce9',1,'StdioStream::println(double val, uint8_t prec=2)'],['../class_stdio_stream.html#aac250d041a7844c8db1cbd2d97ecfdaa',1,'StdioStream::println(float val, uint8_t prec=2)'],['../class_stdio_stream.html#a3b14532768d07e6ed89c762d04792c12',1,'StdioStream::println(T val)']]], + ['printmodifydatetime',['printModifyDateTime',['../class_fat_file.html#a05cee5df46a370bf916d3ba597c82e39',1,'FatFile']]], + ['printname',['printName',['../class_fat_file.html#ad1cbc3aeb0f5193b7a26595966da9621',1,'FatFile::printName()'],['../class_fat_file.html#afe18a787fb8640e2d2483370c770f82f',1,'FatFile::printName(print_t *pr)']]], + ['printsfn',['printSFN',['../class_fat_file.html#a791cd7aade71f609aab62ec018aea3c0',1,'FatFile']]], + ['progmem',['PROGMEM',['../_fat_file_8h.html#a75acaba9e781937468d0911423bc0c35',1,'FatFile.h']]], + ['pstr',['PSTR',['../_fat_file_8h.html#a9c00057fd19e916cc1aa0a5949336beb',1,'FatFile.h']]], + ['put',['put',['../classostream.html#a11aad8a1efd284ccfa91cbfb78d089bd',1,'ostream']]], + ['putc',['putc',['../class_stdio_stream.html#adf9e552212aad6fc2284da0ee62d04dc',1,'StdioStream']]], + ['putcrlf',['putCRLF',['../class_stdio_stream.html#a09ccc4b6cabc3502c1052e85d94e84ef',1,'StdioStream']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_0.html b/libraries/SdFat/extras/html/search/classes_0.html new file mode 100644 index 0000000..523591f --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_0.js b/libraries/SdFat/extras/html/search/classes_0.js new file mode 100644 index 0000000..a9adadb --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['arduinoinstream',['ArduinoInStream',['../class_arduino_in_stream.html',1,'']]], + ['arduinooutstream',['ArduinoOutStream',['../class_arduino_out_stream.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_1.html b/libraries/SdFat/extras/html/search/classes_1.html new file mode 100644 index 0000000..f5a65ad --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_1.js b/libraries/SdFat/extras/html/search/classes_1.js new file mode 100644 index 0000000..db111f8 --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['baseblockdriver',['BaseBlockDriver',['../class_base_block_driver.html',1,'']]], + ['biosparmblock',['biosParmBlock',['../structbios_parm_block.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_2.html b/libraries/SdFat/extras/html/search/classes_2.html new file mode 100644 index 0000000..5b89b27 --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_2.js b/libraries/SdFat/extras/html/search/classes_2.js new file mode 100644 index 0000000..2cec96a --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['cache_5ft',['cache_t',['../unioncache__t.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_3.html b/libraries/SdFat/extras/html/search/classes_3.html new file mode 100644 index 0000000..63ffc5d --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_3.js b/libraries/SdFat/extras/html/search/classes_3.js new file mode 100644 index 0000000..6d9643b --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['directoryentry',['directoryEntry',['../structdirectory_entry.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_4.html b/libraries/SdFat/extras/html/search/classes_4.html new file mode 100644 index 0000000..4acce5b --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_4.js b/libraries/SdFat/extras/html/search/classes_4.js new file mode 100644 index 0000000..29dc35e --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_4.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['fat32_5fboot',['fat32_boot',['../structfat32__boot.html',1,'']]], + ['fat32_5ffsinfo',['fat32_fsinfo',['../structfat32__fsinfo.html',1,'']]], + ['fat_5fboot',['fat_boot',['../structfat__boot.html',1,'']]], + ['fatcache',['FatCache',['../class_fat_cache.html',1,'']]], + ['fatfile',['FatFile',['../class_fat_file.html',1,'']]], + ['fatfilesystem',['FatFileSystem',['../class_fat_file_system.html',1,'']]], + ['fatpos_5ft',['FatPos_t',['../struct_fat_pos__t.html',1,'']]], + ['fatstreambase',['FatStreamBase',['../class_fat_stream_base.html',1,'']]], + ['fatvolume',['FatVolume',['../class_fat_volume.html',1,'']]], + ['file',['File',['../class_file.html',1,'']]], + ['fname_5ft',['fname_t',['../structfname__t.html',1,'']]], + ['fstream',['fstream',['../classfstream.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_5.html b/libraries/SdFat/extras/html/search/classes_5.html new file mode 100644 index 0000000..67b3b9f --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_5.js b/libraries/SdFat/extras/html/search/classes_5.js new file mode 100644 index 0000000..356cc7b --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_5.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['ibufstream',['ibufstream',['../classibufstream.html',1,'']]], + ['ifstream',['ifstream',['../classifstream.html',1,'']]], + ['ios',['ios',['../classios.html',1,'']]], + ['ios_5fbase',['ios_base',['../classios__base.html',1,'']]], + ['iostream',['iostream',['../classiostream.html',1,'']]], + ['istream',['istream',['../classistream.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_6.html b/libraries/SdFat/extras/html/search/classes_6.html new file mode 100644 index 0000000..ab174b5 --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_6.js b/libraries/SdFat/extras/html/search/classes_6.js new file mode 100644 index 0000000..61b2f45 --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['longdirectoryentry',['longDirectoryEntry',['../structlong_directory_entry.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_7.html b/libraries/SdFat/extras/html/search/classes_7.html new file mode 100644 index 0000000..737ed8b --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_7.js b/libraries/SdFat/extras/html/search/classes_7.js new file mode 100644 index 0000000..5be458c --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['masterbootrecord',['masterBootRecord',['../structmaster_boot_record.html',1,'']]], + ['minimumserial',['MinimumSerial',['../class_minimum_serial.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_8.html b/libraries/SdFat/extras/html/search/classes_8.html new file mode 100644 index 0000000..b58c4b4 --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_8.js b/libraries/SdFat/extras/html/search/classes_8.js new file mode 100644 index 0000000..7979fbb --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_8.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['obufstream',['obufstream',['../classobufstream.html',1,'']]], + ['ofstream',['ofstream',['../classofstream.html',1,'']]], + ['ostream',['ostream',['../classostream.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_9.html b/libraries/SdFat/extras/html/search/classes_9.html new file mode 100644 index 0000000..83984ab --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_9.js b/libraries/SdFat/extras/html/search/classes_9.js new file mode 100644 index 0000000..fcf5b92 --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_9.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['partitiontable',['partitionTable',['../structpartition_table.html',1,'']]], + ['printfile',['PrintFile',['../class_print_file.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/classes_a.html b/libraries/SdFat/extras/html/search/classes_a.html new file mode 100644 index 0000000..8a0a656 --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/classes_a.js b/libraries/SdFat/extras/html/search/classes_a.js new file mode 100644 index 0000000..2ff10e5 --- /dev/null +++ b/libraries/SdFat/extras/html/search/classes_a.js @@ -0,0 +1,23 @@ +var searchData= +[ + ['sd2card',['Sd2Card',['../class_sd2_card.html',1,'']]], + ['sdbasefile',['SdBaseFile',['../class_sd_base_file.html',1,'']]], + ['sdfat',['SdFat',['../class_sd_fat.html',1,'']]], + ['sdfatex',['SdFatEX',['../class_sd_fat_e_x.html',1,'']]], + ['sdfatsdio',['SdFatSdio',['../class_sd_fat_sdio.html',1,'']]], + ['sdfatsoftspi',['SdFatSoftSpi',['../class_sd_fat_soft_spi.html',1,'']]], + ['sdfatsoftspiex',['SdFatSoftSpiEX',['../class_sd_fat_soft_spi_e_x.html',1,'']]], + ['sdfile',['SdFile',['../class_sd_file.html',1,'']]], + ['sdfilesystem',['SdFileSystem',['../class_sd_file_system.html',1,'']]], + ['sdfilesystem_3c_20sdiocard_20_3e',['SdFileSystem< SdioCard >',['../class_sd_file_system.html',1,'']]], + ['sdfilesystem_3c_20sdspicard_20_3e',['SdFileSystem< SdSpiCard >',['../class_sd_file_system.html',1,'']]], + ['sdfilesystem_3c_20sdspicardex_20_3e',['SdFileSystem< SdSpiCardEX >',['../class_sd_file_system.html',1,'']]], + ['sdiocard',['SdioCard',['../class_sdio_card.html',1,'']]], + ['sdspicard',['SdSpiCard',['../class_sd_spi_card.html',1,'']]], + ['sdspicardex',['SdSpiCardEX',['../class_sd_spi_card_e_x.html',1,'']]], + ['setfill',['setfill',['../structsetfill.html',1,'']]], + ['setprecision',['setprecision',['../structsetprecision.html',1,'']]], + ['setw',['setw',['../structsetw.html',1,'']]], + ['stdiostream',['StdioStream',['../class_stdio_stream.html',1,'']]], + ['syscall',['SysCall',['../class_sys_call.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/close.png b/libraries/SdFat/extras/html/search/close.png new file mode 100644 index 0000000..9342d3d Binary files /dev/null and b/libraries/SdFat/extras/html/search/close.png differ diff --git a/libraries/SdFat/extras/html/search/defines_0.html b/libraries/SdFat/extras/html/search/defines_0.html new file mode 100644 index 0000000..c3b3619 --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/defines_0.js b/libraries/SdFat/extras/html/search/defines_0.js new file mode 100644 index 0000000..567d919 --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['destructor_5fcloses_5ffile',['DESTRUCTOR_CLOSES_FILE',['../_sd_fat_config_8h.html#a9a2b1ca4d91cff876f48deeaacbc33da',1,'DESTRUCTOR_CLOSES_FILE(): SdFatConfig.h'],['../_fat_lib_config_8h.html#a9a2b1ca4d91cff876f48deeaacbc33da',1,'DESTRUCTOR_CLOSES_FILE(): FatLibConfig.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/defines_1.html b/libraries/SdFat/extras/html/search/defines_1.html new file mode 100644 index 0000000..09fcf9e --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/defines_1.js b/libraries/SdFat/extras/html/search/defines_1.js new file mode 100644 index 0000000..0ac9ddd --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_1.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['enable_5farduino_5ffeatures',['ENABLE_ARDUINO_FEATURES',['../_fat_lib_config_8h.html#a9a8c1ea8596f35f7f33a24b642567206',1,'FatLibConfig.h']]], + ['enable_5fextended_5ftransfer_5fclass',['ENABLE_EXTENDED_TRANSFER_CLASS',['../_sd_fat_config_8h.html#aad4f0ecbc65cdc3a7be544225b44f86a',1,'SdFatConfig.h']]], + ['enable_5fsdio_5fclass',['ENABLE_SDIO_CLASS',['../_sd_fat_config_8h.html#a1d106f3a0ba8577abdcc9ce3961ef90b',1,'SdFatConfig.h']]], + ['enable_5fsoftware_5fspi_5fclass',['ENABLE_SOFTWARE_SPI_CLASS',['../_sd_fat_config_8h.html#acc3d779d87b785bb7236b9b3acf7e619',1,'SdFatConfig.h']]], + ['endl_5fcalls_5fflush',['ENDL_CALLS_FLUSH',['../_sd_fat_config_8h.html#a270eefdaec4778f2a491658f34f61b17',1,'ENDL_CALLS_FLUSH(): SdFatConfig.h'],['../_fat_lib_config_8h.html#a270eefdaec4778f2a491658f34f61b17',1,'ENDL_CALLS_FLUSH(): FatLibConfig.h']]], + ['eof',['EOF',['../_stdio_stream_8h.html#a59adc4c82490d23754cd39c2fb99b0da',1,'StdioStream.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/defines_2.html b/libraries/SdFat/extras/html/search/defines_2.html new file mode 100644 index 0000000..6d6dc75 --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/defines_2.js b/libraries/SdFat/extras/html/search/defines_2.js new file mode 100644 index 0000000..a89012f --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_2.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['f',['F',['../_sys_call_8h.html#a0e3009529aac180ed5f48296d6670d6b',1,'SysCall.h']]], + ['fat12_5fsupport',['FAT12_SUPPORT',['../_sd_fat_config_8h.html#a28998c5daf4bd038f4f93172698320b1',1,'FAT12_SUPPORT(): SdFatConfig.h'],['../_fat_lib_config_8h.html#a28998c5daf4bd038f4f93172698320b1',1,'FAT12_SUPPORT(): FatLibConfig.h']]], + ['file_5fread',['FILE_READ',['../_arduino_files_8h.html#ad52d51659a75e25d96fb04d22ff718cb',1,'ArduinoFiles.h']]], + ['file_5fwrite',['FILE_WRITE',['../_arduino_files_8h.html#ace34e503254fa9004599ddf122264c8f',1,'ArduinoFiles.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/defines_3.html b/libraries/SdFat/extras/html/search/defines_3.html new file mode 100644 index 0000000..5aba72e --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/defines_3.js b/libraries/SdFat/extras/html/search/defines_3.js new file mode 100644 index 0000000..49f56af --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['implement_5fspi_5fport_5fselection',['IMPLEMENT_SPI_PORT_SELECTION',['../_sd_fat_config_8h.html#aa13678c06fd801cb8f00b497a517d91e',1,'SdFatConfig.h']]], + ['isdirseparator',['isDirSeparator',['../_fat_file_8h.html#a9f85580ad6f1dfc86fff09a58ff0a1c0',1,'FatFile.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/defines_4.html b/libraries/SdFat/extras/html/search/defines_4.html new file mode 100644 index 0000000..7486f56 --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/defines_4.js b/libraries/SdFat/extras/html/search/defines_4.js new file mode 100644 index 0000000..df3950f --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['maintain_5ffree_5fcluster_5fcount',['MAINTAIN_FREE_CLUSTER_COUNT',['../_sd_fat_config_8h.html#ac2865dac8fdbb4fff47105db32ddf05b',1,'MAINTAIN_FREE_CLUSTER_COUNT(): SdFatConfig.h'],['../_fat_lib_config_8h.html#ac2865dac8fdbb4fff47105db32ddf05b',1,'MAINTAIN_FREE_CLUSTER_COUNT(): FatLibConfig.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/defines_5.html b/libraries/SdFat/extras/html/search/defines_5.html new file mode 100644 index 0000000..3137e0a --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/defines_5.js b/libraries/SdFat/extras/html/search/defines_5.js new file mode 100644 index 0000000..b45fe3d --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['null',['NULL',['../_stdio_stream_8h.html#a070d2ce7b6bb7e5c05602aa8c308d0c4',1,'StdioStream.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/defines_6.html b/libraries/SdFat/extras/html/search/defines_6.html new file mode 100644 index 0000000..ae03e5c --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/defines_6.js b/libraries/SdFat/extras/html/search/defines_6.js new file mode 100644 index 0000000..9894a74 --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_6.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['pgm_5fread_5fbyte',['pgm_read_byte',['../_fat_file_8h.html#a48c60b057902adf805797f183286728d',1,'FatFile.h']]], + ['pgm_5fread_5fword',['pgm_read_word',['../_fat_file_8h.html#a910fb5f01313d339d3b835d45e1e5ad0',1,'FatFile.h']]], + ['progmem',['PROGMEM',['../_fat_file_8h.html#a75acaba9e781937468d0911423bc0c35',1,'FatFile.h']]], + ['pstr',['PSTR',['../_fat_file_8h.html#a9c00057fd19e916cc1aa0a5949336beb',1,'FatFile.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/defines_7.html b/libraries/SdFat/extras/html/search/defines_7.html new file mode 100644 index 0000000..cff9f02 --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/defines_7.js b/libraries/SdFat/extras/html/search/defines_7.js new file mode 100644 index 0000000..7c30917 --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_7.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['sd_5ffat_5fversion',['SD_FAT_VERSION',['../_sd_fat_8h.html#aca25ecce379f446043bdee2c55304210',1,'SdFat.h']]], + ['sd_5fhas_5fcustom_5fspi',['SD_HAS_CUSTOM_SPI',['../_sd_fat_config_8h.html#a838861a01379e94361148d22e62b1977',1,'SdFatConfig.h']]], + ['seek_5fcur',['SEEK_CUR',['../_stdio_stream_8h.html#a4c8d0b76b470ba65a43ca46a88320f39',1,'StdioStream.h']]], + ['seek_5fend',['SEEK_END',['../_stdio_stream_8h.html#ad2a2e6c114780c3071efd24f16c7f7d8',1,'StdioStream.h']]], + ['seek_5fset',['SEEK_SET',['../_stdio_stream_8h.html#a0d112bae8fd35be772185b6ec6bcbe64',1,'StdioStream.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/defines_8.html b/libraries/SdFat/extras/html/search/defines_8.html new file mode 100644 index 0000000..ed546ae --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/defines_8.js b/libraries/SdFat/extras/html/search/defines_8.js new file mode 100644 index 0000000..41661be --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_8.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['use_5flong_5ffile_5fnames',['USE_LONG_FILE_NAMES',['../_sd_fat_config_8h.html#a2536b194b3b007604a39e8526e108b52',1,'USE_LONG_FILE_NAMES(): SdFatConfig.h'],['../_fat_lib_config_8h.html#a2536b194b3b007604a39e8526e108b52',1,'USE_LONG_FILE_NAMES(): FatLibConfig.h']]], + ['use_5fmulti_5fblock_5fio',['USE_MULTI_BLOCK_IO',['../_sd_fat_config_8h.html#afc3ef382d3ab8d7e6f8fc134ef21d487',1,'USE_MULTI_BLOCK_IO(): SdFatConfig.h'],['../_fat_lib_config_8h.html#afc3ef382d3ab8d7e6f8fc134ef21d487',1,'USE_MULTI_BLOCK_IO(): FatLibConfig.h']]], + ['use_5fsd_5fcrc',['USE_SD_CRC',['../_sd_fat_config_8h.html#af2e76ffb2fdb830175abf513dd640fdd',1,'SdFatConfig.h']]], + ['use_5fseparate_5ffat_5fcache',['USE_SEPARATE_FAT_CACHE',['../_sd_fat_config_8h.html#a23f662882413dcb017ebd8107473b8c3',1,'USE_SEPARATE_FAT_CACHE(): SdFatConfig.h'],['../_fat_lib_config_8h.html#a23f662882413dcb017ebd8107473b8c3',1,'USE_SEPARATE_FAT_CACHE(): FatLibConfig.h']]], + ['use_5fstandard_5fspi_5flibrary',['USE_STANDARD_SPI_LIBRARY',['../_sd_fat_config_8h.html#a3dc42547ca4567cb789bec55759afeb2',1,'SdFatConfig.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/defines_9.html b/libraries/SdFat/extras/html/search/defines_9.html new file mode 100644 index 0000000..a16c035 --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/defines_9.js b/libraries/SdFat/extras/html/search/defines_9.js new file mode 100644 index 0000000..beb4463 --- /dev/null +++ b/libraries/SdFat/extras/html/search/defines_9.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['wdt_5fyield_5ftime_5fmicros',['WDT_YIELD_TIME_MICROS',['../_sd_fat_config_8h.html#a4e8a928d86c50c91c0bfc9a442373e14',1,'SdFatConfig.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/enums_0.html b/libraries/SdFat/extras/html/search/enums_0.html new file mode 100644 index 0000000..d8d79a3 --- /dev/null +++ b/libraries/SdFat/extras/html/search/enums_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/enums_0.js b/libraries/SdFat/extras/html/search/enums_0.js new file mode 100644 index 0000000..82b6107 --- /dev/null +++ b/libraries/SdFat/extras/html/search/enums_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['seekdir',['seekdir',['../classios__base.html#ab01103ba35f6ba93a704b3ec0c86191e',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/enumvalues_0.html b/libraries/SdFat/extras/html/search/enumvalues_0.html new file mode 100644 index 0000000..450f1ac --- /dev/null +++ b/libraries/SdFat/extras/html/search/enumvalues_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/enumvalues_0.js b/libraries/SdFat/extras/html/search/enumvalues_0.js new file mode 100644 index 0000000..1836d03 --- /dev/null +++ b/libraries/SdFat/extras/html/search/enumvalues_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['beg',['beg',['../classios__base.html#ab01103ba35f6ba93a704b3ec0c86191ea6639b4dd9e9b57ffef4a176cd1a1e7bb',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/enumvalues_1.html b/libraries/SdFat/extras/html/search/enumvalues_1.html new file mode 100644 index 0000000..ac8ff57 --- /dev/null +++ b/libraries/SdFat/extras/html/search/enumvalues_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/enumvalues_1.js b/libraries/SdFat/extras/html/search/enumvalues_1.js new file mode 100644 index 0000000..8d0da19 --- /dev/null +++ b/libraries/SdFat/extras/html/search/enumvalues_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['cur',['cur',['../classios__base.html#ab01103ba35f6ba93a704b3ec0c86191ea53910041525b9e2f33bfc3bb4482134c',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/enumvalues_2.html b/libraries/SdFat/extras/html/search/enumvalues_2.html new file mode 100644 index 0000000..71e42ad --- /dev/null +++ b/libraries/SdFat/extras/html/search/enumvalues_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/enumvalues_2.js b/libraries/SdFat/extras/html/search/enumvalues_2.js new file mode 100644 index 0000000..b1792d5 --- /dev/null +++ b/libraries/SdFat/extras/html/search/enumvalues_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['end',['end',['../classios__base.html#ab01103ba35f6ba93a704b3ec0c86191eaae47c0ae984e90b38907783a1a804811',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/files_0.html b/libraries/SdFat/extras/html/search/files_0.html new file mode 100644 index 0000000..a2ec540 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/files_0.js b/libraries/SdFat/extras/html/search/files_0.js new file mode 100644 index 0000000..ff5b52d --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['arduinofiles_2eh',['ArduinoFiles.h',['../_arduino_files_8h.html',1,'']]], + ['arduinostream_2eh',['ArduinoStream.h',['../_arduino_stream_8h.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/files_1.html b/libraries/SdFat/extras/html/search/files_1.html new file mode 100644 index 0000000..9e974da --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/files_1.js b/libraries/SdFat/extras/html/search/files_1.js new file mode 100644 index 0000000..22718b3 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['blockdriver_2eh',['BlockDriver.h',['../_block_driver_8h.html',1,'']]], + ['bufstream_2eh',['bufstream.h',['../bufstream_8h.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/files_2.html b/libraries/SdFat/extras/html/search/files_2.html new file mode 100644 index 0000000..04348f9 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/files_2.js b/libraries/SdFat/extras/html/search/files_2.js new file mode 100644 index 0000000..2aca7f9 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_2.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['fatfile_2eh',['FatFile.h',['../_fat_file_8h.html',1,'']]], + ['fatfilesystem_2eh',['FatFileSystem.h',['../_fat_file_system_8h.html',1,'']]], + ['fatlibconfig_2eh',['FatLibConfig.h',['../_fat_lib_config_8h.html',1,'']]], + ['fatstructs_2eh',['FatStructs.h',['../_fat_structs_8h.html',1,'']]], + ['fatvolume_2eh',['FatVolume.h',['../_fat_volume_8h.html',1,'']]], + ['freestack_2eh',['FreeStack.h',['../_free_stack_8h.html',1,'']]], + ['fstream_2eh',['fstream.h',['../fstream_8h.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/files_3.html b/libraries/SdFat/extras/html/search/files_3.html new file mode 100644 index 0000000..7794200 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/files_3.js b/libraries/SdFat/extras/html/search/files_3.js new file mode 100644 index 0000000..19c93d7 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_3.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['ios_2eh',['ios.h',['../ios_8h.html',1,'']]], + ['iostream_2eh',['iostream.h',['../iostream_8h.html',1,'']]], + ['istream_2eh',['istream.h',['../istream_8h.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/files_4.html b/libraries/SdFat/extras/html/search/files_4.html new file mode 100644 index 0000000..e6bc285 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/files_4.js b/libraries/SdFat/extras/html/search/files_4.js new file mode 100644 index 0000000..13b542b --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['minimumserial_2eh',['MinimumSerial.h',['../_minimum_serial_8h.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/files_5.html b/libraries/SdFat/extras/html/search/files_5.html new file mode 100644 index 0000000..5ab2ed6 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/files_5.js b/libraries/SdFat/extras/html/search/files_5.js new file mode 100644 index 0000000..fbe6ff4 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['ostream_2eh',['ostream.h',['../ostream_8h.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/files_6.html b/libraries/SdFat/extras/html/search/files_6.html new file mode 100644 index 0000000..9453495 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/files_6.js b/libraries/SdFat/extras/html/search/files_6.js new file mode 100644 index 0000000..7a8b712 --- /dev/null +++ b/libraries/SdFat/extras/html/search/files_6.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['sdfat_2eh',['SdFat.h',['../_sd_fat_8h.html',1,'']]], + ['sdfatconfig_2eh',['SdFatConfig.h',['../_sd_fat_config_8h.html',1,'']]], + ['sdspicard_2eh',['SdSpiCard.h',['../_sd_spi_card_8h.html',1,'']]], + ['stdiostream_2eh',['StdioStream.h',['../_stdio_stream_8h.html',1,'']]], + ['syscall_2eh',['SysCall.h',['../_sys_call_8h.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_0.html b/libraries/SdFat/extras/html/search/functions_0.html new file mode 100644 index 0000000..246d167 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_0.js b/libraries/SdFat/extras/html/search/functions_0.js new file mode 100644 index 0000000..53143e8 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_0.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['arduinoinstream',['ArduinoInStream',['../class_arduino_in_stream.html#a61ee22a5824849ec3261ee2f814dfb93',1,'ArduinoInStream']]], + ['arduinooutstream',['ArduinoOutStream',['../class_arduino_out_stream.html#a228b667f9f53dc91c6ed7735d34f04a8',1,'ArduinoOutStream']]], + ['available',['available',['../class_minimum_serial.html#a2abe4370989968938b5dc4872d51c3df',1,'MinimumSerial::available()'],['../class_print_file.html#a600592235b2bee6bdb3a9701d0d6eee3',1,'PrintFile::available()'],['../class_file.html#acf613c4e75bae85f543b30e701ebcc44',1,'File::available()'],['../class_fat_file.html#ac1fa779d98db7ffdb96f8019ab0060d6',1,'FatFile::available()']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_1.html b/libraries/SdFat/extras/html/search/functions_1.html new file mode 100644 index 0000000..5f14d67 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_1.js b/libraries/SdFat/extras/html/search/functions_1.js new file mode 100644 index 0000000..3b9b854 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_1.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['bad',['bad',['../classios.html#a7daa417c60277a4a4a452df4ad0af8e6',1,'ios']]], + ['begin',['begin',['../class_minimum_serial.html#a5c56beb3472bb97f949defeecacda52c',1,'MinimumSerial::begin()'],['../class_sd_file_system.html#ad94237ef45c52698e97b04e8c131f21e',1,'SdFileSystem::begin()'],['../class_sd_fat.html#abfafe10a64b28e6c1698ed82d340f624',1,'SdFat::begin()'],['../class_sd_fat_sdio.html#ac742b37bd8f2f4eb4df44b37c98398e0',1,'SdFatSdio::begin()'],['../class_sd_fat_soft_spi.html#a061019e4b5e17fad3cf8b0e3a08532e4',1,'SdFatSoftSpi::begin()'],['../class_sd_fat_e_x.html#a25acc97272c6004a6a4118bacef07467',1,'SdFatEX::begin()'],['../class_sd_fat_soft_spi_e_x.html#af84b3a6a61dd4c7f3c2c4bb17a8a6609',1,'SdFatSoftSpiEX::begin()'],['../class_sd2_card.html#a8506e1a2d7c4d8ec3f26e8b62ea81cd7',1,'Sd2Card::begin()'],['../class_fat_file_system.html#a5dda20d3dcbfc8c641babbb2c9aac382',1,'FatFileSystem::begin()'],['../class_sdio_card.html#ac749bdad92a4465d062f5d21a7f4faf5',1,'SdioCard::begin()'],['../class_sd_spi_card.html#a824cd60ef8ac2b06262597d6f30a4ea7',1,'SdSpiCard::begin()'],['../class_sd_spi_card_e_x.html#a4fd0b23d230c6ad7dc406e798bbd5470',1,'SdSpiCardEX::begin()']]], + ['block',['block',['../class_fat_cache.html#ab3d9c4f94af61065b6d6d0892827fd8a',1,'FatCache']]], + ['blockspercluster',['blocksPerCluster',['../class_fat_volume.html#a06beed4cea5e38116b58254a57125442',1,'FatVolume']]], + ['blocksperfat',['blocksPerFat',['../class_fat_volume.html#abc66d856d05198d9ebe7104c8c4155d7',1,'FatVolume']]], + ['boolalpha',['boolalpha',['../ios_8h.html#a0016daaaf730481e2ad36972fa7abb17',1,'ios.h']]], + ['buf',['buf',['../classobufstream.html#a4f699181bd3727f4288f4f95a5ce207f',1,'obufstream']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_10.html b/libraries/SdFat/extras/html/search/functions_10.html new file mode 100644 index 0000000..c322f40 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_10.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_10.js b/libraries/SdFat/extras/html/search/functions_10.js new file mode 100644 index 0000000..5223bda --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_10.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['tellg',['tellg',['../classistream.html#a18332bdcb7fbe33ca06045c786cac4c3',1,'istream']]], + ['tellp',['tellp',['../classostream.html#a92dec0e2bc8352df1419d1cdc434e619',1,'ostream']]], + ['timestamp',['timestamp',['../class_fat_file.html#aa53a8d1d2467ad9af7d61cbf8ee85243',1,'FatFile::timestamp(FatFile *file)'],['../class_fat_file.html#a56dabdf73833b7e961c4530eb8e16d23',1,'FatFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)']]], + ['truncate',['truncate',['../class_fat_file.html#aa6e663098a578635d37d92e82d18d616',1,'FatFile::truncate()'],['../class_fat_file_system.html#ad60cb13557f35578f868e03e9ccb8be1',1,'FatFileSystem::truncate()']]], + ['type',['type',['../class_sdio_card.html#a2151106a93280ae41bab654428214661',1,'SdioCard::type()'],['../class_sd_spi_card.html#a061d92bf154a1863a6321385b7505f6e',1,'SdSpiCard::type()']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_11.html b/libraries/SdFat/extras/html/search/functions_11.html new file mode 100644 index 0000000..c49fcd4 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_11.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_11.js b/libraries/SdFat/extras/html/search/functions_11.js new file mode 100644 index 0000000..e5df246 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_11.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['ungetc',['ungetc',['../class_stdio_stream.html#ac00e0dd906c2e857ece53794c6c92786',1,'StdioStream']]], + ['unsetf',['unsetf',['../classios__base.html#a3bf7d054a433ed15e8b984e16f630fa4',1,'ios_base']]], + ['uppercase',['uppercase',['../ios_8h.html#af5d5e1a0effa1b500bb882feed5a2061',1,'ios.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_12.html b/libraries/SdFat/extras/html/search/functions_12.html new file mode 100644 index 0000000..6a02772 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_12.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_12.js b/libraries/SdFat/extras/html/search/functions_12.js new file mode 100644 index 0000000..d3159c0 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_12.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['vol',['vol',['../class_fat_file_system.html#a4ca68fe47bb675df0a80df1ed7a53698',1,'FatFileSystem']]], + ['volume',['volume',['../class_fat_file.html#a3c64bd8a9abb9a6461d4addb405614df',1,'FatFile']]], + ['volumeblockcount',['volumeBlockCount',['../class_fat_volume.html#a07bc98088ce4a9c725700899c184f7fc',1,'FatVolume']]], + ['vwd',['vwd',['../class_fat_file_system.html#acf257d02b7166683bda2abc5058004bf',1,'FatFileSystem']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_13.html b/libraries/SdFat/extras/html/search/functions_13.html new file mode 100644 index 0000000..23ac5da --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_13.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_13.js b/libraries/SdFat/extras/html/search/functions_13.js new file mode 100644 index 0000000..696afe6 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_13.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['width',['width',['../classios__base.html#afa30e7644b4eae5928ad9c487ad387de',1,'ios_base::width()'],['../classios__base.html#ab2ba0f005bbf3d8ebed93b64068492e0',1,'ios_base::width(unsigned n)']]], + ['wipe',['wipe',['../class_fat_file_system.html#a36d7831f92acfbfef1c4a24dd7103dc4',1,'FatFileSystem::wipe()'],['../class_fat_volume.html#a8088aa74cf601996905dadd2eea6966c',1,'FatVolume::wipe()']]], + ['write',['write',['../class_minimum_serial.html#a0ca1d9631fe5f2f00878bd481dbbd3aa',1,'MinimumSerial::write()'],['../class_print_file.html#a460b033ff85e85f684f8d9b615645db1',1,'PrintFile::write(uint8_t b)'],['../class_print_file.html#a29c1d534d21c3a82ad04232d37119a57',1,'PrintFile::write(const uint8_t *buf, size_t size)'],['../class_file.html#a618a6b2b7e81bfb93e0d3c158f614f90',1,'File::write(uint8_t b)'],['../class_file.html#aa531c1641a2363e1f6b9d103f37433da',1,'File::write(const uint8_t *buf, size_t size)'],['../class_fat_file.html#aa4a5b81161994cea07938702cdfce49f',1,'FatFile::write(const char *str)'],['../class_fat_file.html#a5524bd9f3b8f54ee163e391cba618186',1,'FatFile::write(uint8_t b)'],['../class_fat_file.html#a0ab9df44a9ee4b6eb0a78f15f1e30004',1,'FatFile::write(const void *buf, size_t nbyte)']]], + ['writeblock',['writeBlock',['../class_base_block_driver.html#a87df3db1b400286883661525441d39fa',1,'BaseBlockDriver::writeBlock()'],['../class_sdio_card.html#ae53e5f72ddf9ace3f47774d968e064ed',1,'SdioCard::writeBlock()'],['../class_sd_spi_card.html#a03a0bdb0f37a88076f24a2133cf5b4ed',1,'SdSpiCard::writeBlock()'],['../class_sd_spi_card_e_x.html#a6bd5e6bcfc2ab9574daa11bdd342be7b',1,'SdSpiCardEX::writeBlock()']]], + ['writeblocks',['writeBlocks',['../class_base_block_driver.html#a3d6520b21252ebfb17b0cac0b87689b1',1,'BaseBlockDriver::writeBlocks()'],['../class_sdio_card.html#a8b811f875497e90e75fbe6c2d41d89cb',1,'SdioCard::writeBlocks()'],['../class_sd_spi_card.html#a181d96fe44891b7caabcd47dd29ac913',1,'SdSpiCard::writeBlocks()'],['../class_sd_spi_card_e_x.html#a9a7a5815b56c2cc77590a72635593762',1,'SdSpiCardEX::writeBlocks()']]], + ['writedata',['writeData',['../class_sd_spi_card.html#a9495c0b148eb380358bb4a9721c0dffa',1,'SdSpiCard']]], + ['writestart',['writeStart',['../class_sd_spi_card.html#a56d4750a5d2f693943eec985cb61ffe2',1,'SdSpiCard::writeStart(uint32_t blockNumber)'],['../class_sd_spi_card.html#a8bf0dc991308dcd2a7427bad89a9e2ba',1,'SdSpiCard::writeStart(uint32_t blockNumber, uint32_t eraseCount)']]], + ['writestop',['writeStop',['../class_sd_spi_card.html#aef9154785a4de5560fb807e4f9316fb0',1,'SdSpiCard']]], + ['ws',['ws',['../iostream_8h.html#a8adf4c714b8c8f201dedc83ee04556b1',1,'iostream.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_14.html b/libraries/SdFat/extras/html/search/functions_14.html new file mode 100644 index 0000000..16e2625 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_14.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_14.js b/libraries/SdFat/extras/html/search/functions_14.js new file mode 100644 index 0000000..685c4a7 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_14.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['yield',['yield',['../class_sys_call.html#a2219ba5ea8e411b022a3a00df5f380e0',1,'SysCall']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_2.html b/libraries/SdFat/extras/html/search/functions_2.html new file mode 100644 index 0000000..3995cf8 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_2.js b/libraries/SdFat/extras/html/search/functions_2.js new file mode 100644 index 0000000..cd0abd8 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_2.js @@ -0,0 +1,24 @@ +var searchData= +[ + ['cacheclear',['cacheClear',['../class_fat_volume.html#aa1e3b1d0c21d202deb82668068ab00e8',1,'FatVolume']]], + ['card',['card',['../class_sd_file_system.html#ab5dcfbeeb7caa38a38db86003341eb07',1,'SdFileSystem']]], + ['cardbegin',['cardBegin',['../class_sd_fat.html#ae380e4572776db851b2f80a3ed143fca',1,'SdFat::cardBegin()'],['../class_sd_fat_sdio.html#ac49062cc8fb2a42564d0ff05b4c0be8b',1,'SdFatSdio::cardBegin()']]], + ['carderrorcode',['cardErrorCode',['../class_sd_file_system.html#aedfd5a0830c955bc5514e52f2f2dd066',1,'SdFileSystem']]], + ['carderrordata',['cardErrorData',['../class_sd_file_system.html#a0602ab3c04ea33293649f0a15fc81e05',1,'SdFileSystem']]], + ['cardsize',['cardSize',['../class_sdio_card.html#a3d8f9a92f7faec77094ec65e6c41dd45',1,'SdioCard::cardSize()'],['../class_sd_spi_card.html#afca8bd6b7e465bf9c475ba375c4deec8',1,'SdSpiCard::cardSize()']]], + ['chdir',['chdir',['../class_fat_file_system.html#a5667915e63187a43a71dfada63800865',1,'FatFileSystem::chdir(bool set_cwd=false)'],['../class_fat_file_system.html#a44af1b98e8d986d12107b654453acbc4',1,'FatFileSystem::chdir(const char *path, bool set_cwd=false)']]], + ['chvol',['chvol',['../class_fat_file_system.html#af24917d6e00c8766dab168eb834047ec',1,'FatFileSystem']]], + ['clear',['clear',['../classfstream.html#a682b278a6a299ffb21b8737717ff12bf',1,'fstream::clear()'],['../classofstream.html#a09edfdb3dbda20aff105e751001313f0',1,'ofstream::clear()'],['../classios.html#aa49ed6670d1743e7a373b2d915ec739a',1,'ios::clear()']]], + ['clearerr',['clearerr',['../class_stdio_stream.html#aa737e5680fc2808a03a603ea8559d82b',1,'StdioStream']]], + ['clearerror',['clearError',['../class_fat_file.html#a052e2c15a39b322a5307b693b8835b22',1,'FatFile']]], + ['clearwriteerror',['clearWriteError',['../class_fat_file.html#aeca2a2eff91e6aa55fe1b0e3860c9a05',1,'FatFile']]], + ['close',['close',['../class_fat_file.html#afd16af325e0642e4bff6430b7d8bb18b',1,'FatFile::close()'],['../classfstream.html#ac5720ee620c09d63dd186823e688ea9a',1,'fstream::close()'],['../classifstream.html#ac5892f472afdef6160f5fe2401b16dce',1,'ifstream::close()'],['../classofstream.html#a240f3752c7ff7a78d10c143d2083715f',1,'ofstream::close()']]], + ['clustercount',['clusterCount',['../class_fat_volume.html#a18446a9c5924304fa7a87d5f03ccaf21',1,'FatVolume']]], + ['clustersizeshift',['clusterSizeShift',['../class_fat_volume.html#ac0e63f33d71d5dc95a602834274def6a',1,'FatVolume']]], + ['contiguousrange',['contiguousRange',['../class_fat_file.html#aa367708bcc8bc0e0c45c0c2a812c65da',1,'FatFile']]], + ['createcontiguous',['createContiguous',['../class_fat_file.html#a0afc2a1cffa238d1cb2049bfa2d8d199',1,'FatFile::createContiguous(FatFile *dirFile, const char *path, uint32_t size)'],['../class_fat_file.html#a0853fbd44aee2798d14d8e3aed78f8bf',1,'FatFile::createContiguous(const char *path, uint32_t size)']]], + ['curcluster',['curCluster',['../class_fat_file.html#a4c03e2f6729526786e6ab4a623e0339b',1,'FatFile']]], + ['curposition',['curPosition',['../class_fat_file.html#a20c55b134bfd1d287a00bf64eba9332e',1,'FatFile']]], + ['curtimems',['curTimeMS',['../_sys_call_8h.html#a7a1c5babdcf00c78d4d2e6a012bd9e68',1,'SysCall.h']]], + ['cwd',['cwd',['../class_fat_file.html#a3b68e603ad8e47bad915f0547e580adb',1,'FatFile']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_3.html b/libraries/SdFat/extras/html/search/functions_3.html new file mode 100644 index 0000000..4e302d6 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_3.js b/libraries/SdFat/extras/html/search/functions_3.js new file mode 100644 index 0000000..e4cdd50 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_3.js @@ -0,0 +1,21 @@ +var searchData= +[ + ['datastartblock',['dataStartBlock',['../class_fat_volume.html#a443364af257c219f8e908d5b073d8fa3',1,'FatVolume']]], + ['datetimecallback',['dateTimeCallback',['../class_fat_file.html#a29a623f50df057e8b49045ba6611ec2b',1,'FatFile']]], + ['datetimecallbackcancel',['dateTimeCallbackCancel',['../class_fat_file.html#a5df02f1d037e6091375488af25244ebc',1,'FatFile']]], + ['dbgfat',['dbgFat',['../class_fat_volume.html#a25c6311b70fa274b3be94ff25fdebba7',1,'FatVolume']]], + ['dec',['dec',['../ios_8h.html#ada38ab90e22f0ebb638cb864a35c562d',1,'ios.h']]], + ['dir_5fis_5ffile',['DIR_IS_FILE',['../_fat_structs_8h.html#a5ce8bde4d6ff3950df951e84c7bb8d58',1,'FatStructs.h']]], + ['dir_5fis_5ffile_5for_5fsubdir',['DIR_IS_FILE_OR_SUBDIR',['../_fat_structs_8h.html#a9d99b04fa090825a9b9c2468fa81e627',1,'FatStructs.h']]], + ['dir_5fis_5fhidden',['DIR_IS_HIDDEN',['../_fat_structs_8h.html#a5137c8165addb9d32c6094d03a9d029d',1,'FatStructs.h']]], + ['dir_5fis_5flong_5fname',['DIR_IS_LONG_NAME',['../_fat_structs_8h.html#a504c3d996b412f386becc27a8c49cd2c',1,'FatStructs.h']]], + ['dir_5fis_5fsubdir',['DIR_IS_SUBDIR',['../_fat_structs_8h.html#ace8ed88fcb41afc4d2fe0eabf96e71c6',1,'FatStructs.h']]], + ['dir_5fis_5fsystem',['DIR_IS_SYSTEM',['../_fat_structs_8h.html#a46cad0d590c5e290c52ccf660b316dd9',1,'FatStructs.h']]], + ['direntry',['dirEntry',['../class_fat_file.html#a6858d18c807411a071fd6d1b39d50087',1,'FatFile']]], + ['dirindex',['dirIndex',['../class_fat_file.html#ae5ec24d4a94d3780384d3f2b731c7eb9',1,'FatFile']]], + ['dirname',['dirName',['../class_fat_file.html#a648461081fe07578780f4cd3f246cb66',1,'FatFile']]], + ['dirsize',['dirSize',['../class_fat_file.html#ae2ed15f05c9ccbce355e7a8d3ce8382d',1,'FatFile']]], + ['dirty',['dirty',['../class_fat_cache.html#ab4d3b0c16bb6a116c7d01afff2dcb307',1,'FatCache']]], + ['dmabusy',['dmaBusy',['../class_sdio_card.html#a9781b9b4f91366a69dd077ad8fb364c5',1,'SdioCard']]], + ['dmpfile',['dmpFile',['../class_fat_file.html#a4f01d27954ae49aeb6888ac7302f55d9',1,'FatFile']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_4.html b/libraries/SdFat/extras/html/search/functions_4.html new file mode 100644 index 0000000..58ca83a --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_4.js b/libraries/SdFat/extras/html/search/functions_4.js new file mode 100644 index 0000000..fd5e3ef --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_4.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['endl',['endl',['../iostream_8h.html#ab9868f8e151efc1705646437dbb59bb2',1,'iostream.h']]], + ['eof',['eof',['../classios.html#ad2f091f3ed1a2e13f62557854c0885a7',1,'ios']]], + ['erase',['erase',['../class_sdio_card.html#a1ce82b035257790ed8e4a9be3d966b80',1,'SdioCard::erase()'],['../class_sd_spi_card.html#a1caa13d19df6596b2c0dd62365c75362',1,'SdSpiCard::erase()']]], + ['erasesingleblockenable',['eraseSingleBlockEnable',['../class_sd_spi_card.html#aed4591884254c9f58daa8738d7c1ccdd',1,'SdSpiCard']]], + ['error',['error',['../class_sd_spi_card.html#aa12ad53111abcb187d3c6119a3a77592',1,'SdSpiCard']]], + ['errorcode',['errorCode',['../class_sdio_card.html#a4ff272009a24fc4078ac87c2d87ccd16',1,'SdioCard::errorCode()'],['../class_sd_spi_card.html#a50bf5f92223222beacec2b203a6b7a95',1,'SdSpiCard::errorCode()']]], + ['errordata',['errorData',['../class_sdio_card.html#a8251b9aa0d623487e80cf908fc1625b5',1,'SdioCard::errorData()'],['../class_sd_spi_card.html#a7b1abdb8dd5254cd4af0df19ba59ce4a',1,'SdSpiCard::errorData()']]], + ['errorhalt',['errorHalt',['../class_sd_file_system.html#a855267374306bfee2df67642c99d4d18',1,'SdFileSystem::errorHalt()'],['../class_sd_file_system.html#ae1f79a2974ebe134e70f898c32d97e98',1,'SdFileSystem::errorHalt(Print *pr)'],['../class_sd_file_system.html#a32c20dfa6a8cb8af95f25847b19bdbca',1,'SdFileSystem::errorHalt(char const *msg)'],['../class_sd_file_system.html#a27fb329d6aee79a63c20386218ce7e9e',1,'SdFileSystem::errorHalt(Print *pr, char const *msg)'],['../class_sd_file_system.html#af856494745a9842d9728dfeabf19c51e',1,'SdFileSystem::errorHalt(const __FlashStringHelper *msg)'],['../class_sd_file_system.html#a746c80d048c30baf0b281e16932670a2',1,'SdFileSystem::errorHalt(Print *pr, const __FlashStringHelper *msg)']]], + ['errorline',['errorLine',['../class_sdio_card.html#aafa9feb1b5a90f3cf96456b6b286bfdf',1,'SdioCard']]], + ['errorprint',['errorPrint',['../class_sd_file_system.html#ab0b78154d6874c29279ba81f36ccb09c',1,'SdFileSystem::errorPrint()'],['../class_sd_file_system.html#a03736274debea71fef5e2ff34d7ec3dc',1,'SdFileSystem::errorPrint(Print *pr)'],['../class_sd_file_system.html#a2e2436b7b2666737cbaf4b22218bc69f',1,'SdFileSystem::errorPrint(const char *msg)'],['../class_sd_file_system.html#a0eb6b92a0700ba932f6127962981d153',1,'SdFileSystem::errorPrint(Print *pr, char const *msg)'],['../class_sd_file_system.html#a1ccb1f937f42e9c1331c942bc357f6da',1,'SdFileSystem::errorPrint(const __FlashStringHelper *msg)'],['../class_sd_file_system.html#a43344a079d9af92ea4b550914d0512f6',1,'SdFileSystem::errorPrint(Print *pr, const __FlashStringHelper *msg)']]], + ['exists',['exists',['../class_fat_file.html#a50242f98dea0d4488ce4039a279f2a57',1,'FatFile::exists()'],['../class_fat_file_system.html#aee58c6352652f216577196e32a594b67',1,'FatFileSystem::exists()']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_5.html b/libraries/SdFat/extras/html/search/functions_5.html new file mode 100644 index 0000000..5f9f05a --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_5.js b/libraries/SdFat/extras/html/search/functions_5.js new file mode 100644 index 0000000..32b5e43 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_5.js @@ -0,0 +1,42 @@ +var searchData= +[ + ['fail',['fail',['../classios.html#a1c7b563046a50c5a0430405964998034',1,'ios']]], + ['fat_5fdate',['FAT_DATE',['../_fat_structs_8h.html#a44899ad42ddf32ff1c1a73b5251b304a',1,'FatStructs.h']]], + ['fat_5fday',['FAT_DAY',['../_fat_structs_8h.html#a4cc8bc105529bf9e9c11e8ef099d68b0',1,'FatStructs.h']]], + ['fat_5fhour',['FAT_HOUR',['../_fat_structs_8h.html#ae7c733d49a5570054f6db3bd53332ba1',1,'FatStructs.h']]], + ['fat_5fminute',['FAT_MINUTE',['../_fat_structs_8h.html#a1b09676a41ae6c9e19664bdcd5b1d34e',1,'FatStructs.h']]], + ['fat_5fmonth',['FAT_MONTH',['../_fat_structs_8h.html#a429bc2d96f5bc26dc3bd6cc2bd535b84',1,'FatStructs.h']]], + ['fat_5fsecond',['FAT_SECOND',['../_fat_structs_8h.html#a4d553e2088d42e01d6c08ee84e611b00',1,'FatStructs.h']]], + ['fat_5ftime',['FAT_TIME',['../_fat_structs_8h.html#a375720927be5a39475d48b2d75dae29a',1,'FatStructs.h']]], + ['fat_5fyear',['FAT_YEAR',['../_fat_structs_8h.html#a279a75f907dd2603543c7bdad00ff603',1,'FatStructs.h']]], + ['fatcount',['fatCount',['../class_fat_volume.html#acdedc6a200b01e401c9cd9b511eae6ec',1,'FatVolume']]], + ['fatfile',['FatFile',['../class_fat_file.html#a7b591c9b92165fa8e4eae8c30c30e533',1,'FatFile::FatFile()'],['../class_fat_file.html#a29d31067d0aa3a9a74b1a660c38775cc',1,'FatFile::FatFile(const char *path, uint8_t oflag)']]], + ['fatstartblock',['fatStartBlock',['../class_fat_volume.html#a0dd0cc689b63ef0702aed1cf36b1722d',1,'FatVolume']]], + ['fattype',['fatType',['../class_fat_volume.html#a1364f11fe9bb4717ce0685e2b7b86027',1,'FatVolume']]], + ['fatvolume',['FatVolume',['../class_fat_volume.html#a026de2bb58026e4edea130db2949b84c',1,'FatVolume']]], + ['fclose',['fclose',['../class_stdio_stream.html#a4ddd4658d49182013d2fa2a181e96c5a',1,'StdioStream']]], + ['feof',['feof',['../class_stdio_stream.html#acb38c3211feedbf2206eb1d9a3a9d24f',1,'StdioStream']]], + ['ferror',['ferror',['../class_stdio_stream.html#afd64cec6440b923660b444f6d5f0586e',1,'StdioStream']]], + ['fflush',['fflush',['../class_stdio_stream.html#a7ce32ec7ea3f2fd8ea42b9633890f1c0',1,'StdioStream']]], + ['fgetc',['fgetc',['../class_stdio_stream.html#a160bd2828cb7e7370cffe1046eff8899',1,'StdioStream']]], + ['fgets',['fgets',['../class_fat_file.html#a31ef26b3ee37cf5f5f4c6024c0ddab69',1,'FatFile::fgets()'],['../class_stdio_stream.html#aa240c1021a1aad1cc57f63a483541dc7',1,'StdioStream::fgets()']]], + ['file',['File',['../class_file.html#a9ecb14efb960d1369926182479f56213',1,'File']]], + ['fileattr',['fileAttr',['../class_fat_file.html#a7e043dfb89d268bfd620bbbadacf1002',1,'FatFile']]], + ['filesize',['fileSize',['../class_fat_file.html#a02fc3b3ca36b4745f695f3de8c8ec36d',1,'FatFile']]], + ['fill',['fill',['../classios__base.html#ade5bd46462e075999c3a5c2cff2015f1',1,'ios_base::fill()'],['../classios__base.html#aa5683f9bdf295311bd5a6d3cdc2fedd5',1,'ios_base::fill(char c)']]], + ['firstblock',['firstBlock',['../class_fat_file.html#ac87b753811e540c7b799da56fa89724b',1,'FatFile']]], + ['firstcluster',['firstCluster',['../class_fat_file.html#a1057bc23b92a074539f661e896e79a09',1,'FatFile']]], + ['flags',['flags',['../classios__base.html#ab5e9c7dbcbc33b7de9dcb70525ec7384',1,'ios_base::flags() const '],['../classios__base.html#ae67e900dc12e4c7cbc0741ad1c70d6c2',1,'ios_base::flags(fmtflags fl)']]], + ['flush',['flush',['../class_minimum_serial.html#a872f0ff70f0e256352004f83d13fff28',1,'MinimumSerial::flush()'],['../class_print_file.html#a53c4cb94af030fdf83a9160ec9a96949',1,'PrintFile::flush()'],['../class_file.html#af87fa862de707575b8badd044a5af80e',1,'File::flush()'],['../classostream.html#af6be1f30d824f5a65d27d5b5d20b8c6c',1,'ostream::flush()'],['../iostream_8h.html#a2f6f5344fca38fd4fe7b6231fd992a0d',1,'flush(): iostream.h']]], + ['fopen',['fopen',['../class_stdio_stream.html#a4ffc37225fb6deed98905aa71d1f9c4b',1,'StdioStream']]], + ['fputc',['fputc',['../class_stdio_stream.html#a9f23cfa6b112a5da6ae08340af23c57b',1,'StdioStream']]], + ['fputs',['fputs',['../class_stdio_stream.html#a6adea52f55ef7d97cdb54e9e11fc2daa',1,'StdioStream']]], + ['fread',['fread',['../class_stdio_stream.html#a2d363b02abcef82b25ff025d50375bce',1,'StdioStream']]], + ['freeclustercount',['freeClusterCount',['../class_fat_volume.html#a1683b063fc6202ab85470b9610f16f93',1,'FatVolume']]], + ['freestack',['FreeStack',['../_free_stack_8h.html#a2c0121d5649d35329a8d0a71e4ffb89b',1,'FreeStack.h']]], + ['fsbegin',['fsBegin',['../class_sd_fat.html#add6a9a3ad07585f6e0e5c35e35cacb9a',1,'SdFat::fsBegin()'],['../class_sd_fat_sdio.html#aac0e8d86182a0e0566c4671c15f3df61',1,'SdFatSdio::fsBegin()']]], + ['fseek',['fseek',['../class_stdio_stream.html#a71584fd5c5cda3c31ce6cdbcc56f104d',1,'StdioStream']]], + ['fstream',['fstream',['../classfstream.html#aed23877c52f828cab8de7a23603b3b6c',1,'fstream']]], + ['ftell',['ftell',['../class_stdio_stream.html#a809639fc5fb4fa5b6789dc121659f386',1,'StdioStream']]], + ['fwrite',['fwrite',['../class_stdio_stream.html#ad79465afb52579cbc801f4585c3f9c25',1,'StdioStream']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_6.html b/libraries/SdFat/extras/html/search/functions_6.html new file mode 100644 index 0000000..c980da2 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_6.js b/libraries/SdFat/extras/html/search/functions_6.js new file mode 100644 index 0000000..9556521 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_6.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['gcount',['gcount',['../classistream.html#ad2b705d2f363ed59db6ac4046f78b4bb',1,'istream']]], + ['get',['get',['../classistream.html#a36573c9b7fc522e6c85a73221019fd11',1,'istream::get()'],['../classistream.html#a9c7313d6f21f1f7ac9b0e759e74b4db2',1,'istream::get(char &ch)'],['../classistream.html#a4247f47e388598c69ef3bd39ea4c056f',1,'istream::get(char *str, streamsize n, char delim= '\n')']]], + ['getc',['getc',['../class_stdio_stream.html#a28ba31e7b526607744bfa41844ffce31',1,'StdioStream']]], + ['geterror',['getError',['../class_fat_file.html#ad0dbbd083180f44c7a3ce7124d4ce19c',1,'FatFile']]], + ['getline',['getline',['../classistream.html#a7d86035d178e526283e5c7555ab7b243',1,'istream']]], + ['getname',['getName',['../class_fat_file.html#aafa565e286440aab612cdb430fc01da5',1,'FatFile']]], + ['getpos',['getpos',['../class_fat_file.html#aaa4f9886887947815a61eaf015996932',1,'FatFile']]], + ['getsfn',['getSFN',['../class_fat_file.html#aba30e92a66f8e0d2f815c85662772a58',1,'FatFile']]], + ['getwriteerror',['getWriteError',['../class_fat_file.html#a8062c0d3a118e8d77d0310418703d5f5',1,'FatFile']]], + ['good',['good',['../classios.html#a5fdf9247f642a7a5c5a21323ffd45366',1,'ios']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_7.html b/libraries/SdFat/extras/html/search/functions_7.html new file mode 100644 index 0000000..3857329 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_7.js b/libraries/SdFat/extras/html/search/functions_7.js new file mode 100644 index 0000000..42d85c2 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['halt',['halt',['../class_sys_call.html#a9b1ef8900e97f572ca561760b4dd4191',1,'SysCall']]], + ['hex',['hex',['../ios_8h.html#ace2036d970905192360d622140bfe336',1,'ios.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_8.html b/libraries/SdFat/extras/html/search/functions_8.html new file mode 100644 index 0000000..088e437 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_8.js b/libraries/SdFat/extras/html/search/functions_8.js new file mode 100644 index 0000000..9c9541d --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_8.js @@ -0,0 +1,26 @@ +var searchData= +[ + ['ibufstream',['ibufstream',['../classibufstream.html#afe28f27d24a62a21428b60fe8834dd05',1,'ibufstream::ibufstream()'],['../classibufstream.html#a819561105ef7dc3828e0cfedfed708d8',1,'ibufstream::ibufstream(const char *str)']]], + ['ifstream',['ifstream',['../classifstream.html#a11f4bfaa5c37cfcf8878c367fd861a88',1,'ifstream']]], + ['ignore',['ignore',['../classistream.html#a12597b03d86b66047a5581bbd26eb032',1,'istream']]], + ['init',['init',['../classibufstream.html#a1d7bae17d9d2c79218085251946f322a',1,'ibufstream::init()'],['../classobufstream.html#a8f75dbadab2fed7770d01a2cc2628258',1,'obufstream::init()'],['../class_fat_cache.html#ae1d8a2da1493b5ffca0520184daaddf1',1,'FatCache::init()'],['../class_fat_volume.html#acab819fa25a91dad1cc698a7e1e0eb32',1,'FatVolume::init()'],['../class_fat_volume.html#a034d997a1e7a0b2b664a4357bcccd256',1,'FatVolume::init(uint8_t part)']]], + ['initerrorhalt',['initErrorHalt',['../class_sd_file_system.html#a8e1f26486bb878a24fa9868e59dbbbc2',1,'SdFileSystem::initErrorHalt()'],['../class_sd_file_system.html#a24bd0f699cf0fe11fd2148b15c49251a',1,'SdFileSystem::initErrorHalt(Print *pr)'],['../class_sd_file_system.html#a893833a880e2a83757480ba4c1351041',1,'SdFileSystem::initErrorHalt(char const *msg)'],['../class_sd_file_system.html#a3077b1a53d789d0401b707963cb28f46',1,'SdFileSystem::initErrorHalt(Print *pr, char const *msg)'],['../class_sd_file_system.html#a2a1e4cc8056ba23b55dfa2c6486b8798',1,'SdFileSystem::initErrorHalt(const __FlashStringHelper *msg)'],['../class_sd_file_system.html#ab03d98012dea18733c3252f27832de69',1,'SdFileSystem::initErrorHalt(Print *pr, const __FlashStringHelper *msg)']]], + ['initerrorprint',['initErrorPrint',['../class_sd_file_system.html#ae31c9cbd7e1c03129d6c99b25f73cd50',1,'SdFileSystem::initErrorPrint()'],['../class_sd_file_system.html#a066707dce0667213b5f083d59f67448d',1,'SdFileSystem::initErrorPrint(Print *pr)'],['../class_sd_file_system.html#a538796f79fd9db9c5bbeefd9defe639a',1,'SdFileSystem::initErrorPrint(char const *msg)'],['../class_sd_file_system.html#ad9855d33ebd465715b706d0926291b13',1,'SdFileSystem::initErrorPrint(Print *pr, char const *msg)'],['../class_sd_file_system.html#ad6ffec5a7d82be46d46b8a4f82d0803b',1,'SdFileSystem::initErrorPrint(const __FlashStringHelper *msg)'],['../class_sd_file_system.html#a8a2018b6366145a9843d3d29a47d6560',1,'SdFileSystem::initErrorPrint(Print *pr, const __FlashStringHelper *msg)']]], + ['internal',['internal',['../ios_8h.html#a8dd76c1ce8fced364a98428ca1eea7a6',1,'ios.h']]], + ['invalidate',['invalidate',['../class_fat_cache.html#a70071a128d647b49b523dbb2f5f944a5',1,'FatCache']]], + ['ios',['ios',['../classios.html#adc5dbd7b69da79493ebc84aa1e681aaa',1,'ios']]], + ['is_5fopen',['is_open',['../classfstream.html#ae4a71c6f3da2f168ec222739d796fc8b',1,'fstream::is_open()'],['../classifstream.html#aaa16c6422ea371995d02159f2e6707b2',1,'ifstream::is_open()'],['../classofstream.html#a9c97eb2eb6e35ae87cf7f7453a67e70a',1,'ofstream::is_open()']]], + ['isbusy',['isBusy',['../class_sd_spi_card.html#aa3cb9139dbc1e6596c6717da2b486328',1,'SdSpiCard']]], + ['isdir',['isDir',['../class_fat_file.html#aef41d65e0f1ce753d18cc9ed691f7de4',1,'FatFile']]], + ['isdirectory',['isDirectory',['../class_file.html#a6ba5bdb943363cda56649238ccb18c27',1,'File']]], + ['isfile',['isFile',['../class_fat_file.html#afcf6270ea8d4a3a5f8e89523bc684e22',1,'FatFile']]], + ['ishidden',['isHidden',['../class_fat_file.html#a7eefe7408f34b6326f0c6e78af7eb05f',1,'FatFile']]], + ['islfn',['isLFN',['../class_fat_file.html#aed36d17f8fde597b6ed9446faec1f7e3',1,'FatFile']]], + ['isopen',['isOpen',['../class_fat_file.html#a4c8a07b081f04aa25839c6f56c739bdc',1,'FatFile']]], + ['isreadonly',['isReadOnly',['../class_fat_file.html#a6872d3acb1e70f81c9c2be2495977583',1,'FatFile']]], + ['isroot',['isRoot',['../class_fat_file.html#aa4a206803a4bf8243be20244c1aef4d2',1,'FatFile']]], + ['isroot32',['isRoot32',['../class_fat_file.html#a1449b294e3a838396c62e47674ca8cf0',1,'FatFile']]], + ['isrootfixed',['isRootFixed',['../class_fat_file.html#a8215bd4b21e11ec83fa88ef226ceb06f',1,'FatFile']]], + ['issubdir',['isSubDir',['../class_fat_file.html#a95b503b17442c2b364a2f53de1b2aeba',1,'FatFile']]], + ['issystem',['isSystem',['../class_fat_file.html#add932e13e5bf32ad467af6ec34824e3c',1,'FatFile']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_9.html b/libraries/SdFat/extras/html/search/functions_9.html new file mode 100644 index 0000000..61de44a --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_9.js b/libraries/SdFat/extras/html/search/functions_9.js new file mode 100644 index 0000000..0f3e7bd --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_9.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['lbn',['lbn',['../class_fat_cache.html#a9f981b53e212f79937e5f6381b169374',1,'FatCache']]], + ['left',['left',['../ios_8h.html#a24a80a73f0a0d2d72d1cb74f49ff4759',1,'ios.h']]], + ['legal83char',['legal83Char',['../class_fat_file.html#a94df8090f16e9666cdc53ca20f6aff90',1,'FatFile']]], + ['length',['length',['../classobufstream.html#ac650708e968b0c0545a3badeb809cf15',1,'obufstream']]], + ['ls',['ls',['../class_fat_file.html#ad49f688a494b351ccbb0102dcfafb925',1,'FatFile::ls(uint8_t flags=0)'],['../class_fat_file.html#acabf31ff85e696fbf384c49428012fea',1,'FatFile::ls(print_t *pr, uint8_t flags=0, uint8_t indent=0)'],['../class_fat_file_system.html#a2398fb37a7a9d5e0dc0ffde6a44a993d',1,'FatFileSystem::ls(uint8_t flags=0)'],['../class_fat_file_system.html#a122b61dbec5051304bcc81bc08b1b99d',1,'FatFileSystem::ls(const char *path, uint8_t flags=0)'],['../class_fat_file_system.html#ae12fb8bfad5c4a8e052dda70a5a0ed93',1,'FatFileSystem::ls(print_t *pr, uint8_t flags=0)'],['../class_fat_file_system.html#aa79695db8e910300507210b3067d39fd',1,'FatFileSystem::ls(print_t *pr, const char *path, uint8_t flags)']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_a.html b/libraries/SdFat/extras/html/search/functions_a.html new file mode 100644 index 0000000..a46b662 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_a.js b/libraries/SdFat/extras/html/search/functions_a.js new file mode 100644 index 0000000..b9e2c88 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['mkdir',['mkdir',['../class_fat_file.html#abab5b9f72cc796388dd4eed01d13d90d',1,'FatFile::mkdir()'],['../class_fat_file_system.html#a231c62c98ba8ac3c2624dc5ad2053ebf',1,'FatFileSystem::mkdir()']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_b.html b/libraries/SdFat/extras/html/search/functions_b.html new file mode 100644 index 0000000..3b49416 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_b.js b/libraries/SdFat/extras/html/search/functions_b.js new file mode 100644 index 0000000..acaa5a8 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_b.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['name',['name',['../class_file.html#a7ca23d8d3997c10c221977c64736f575',1,'File']]], + ['noboolalpha',['noboolalpha',['../ios_8h.html#aa6a1ec04992fc8090ca775a39678be01',1,'ios.h']]], + ['noshowbase',['noshowbase',['../ios_8h.html#ab861ff5f863de0ae002b65390dde36b0',1,'ios.h']]], + ['noshowpoint',['noshowpoint',['../ios_8h.html#ad85399d1b75151cf9e2436f2a1ccfc13',1,'ios.h']]], + ['noshowpos',['noshowpos',['../ios_8h.html#a985805b22ffb4ce2f5298168662bd2d7',1,'ios.h']]], + ['noskipws',['noskipws',['../ios_8h.html#a773b847300db776fde08a0b562792131',1,'ios.h']]], + ['nouppercase',['nouppercase',['../ios_8h.html#a24b96fb317e056b34aa84c4bb965a79a',1,'ios.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_c.html b/libraries/SdFat/extras/html/search/functions_c.html new file mode 100644 index 0000000..57c6455 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_c.js b/libraries/SdFat/extras/html/search/functions_c.js new file mode 100644 index 0000000..616374f --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_c.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['obufstream',['obufstream',['../classobufstream.html#a74f7dbcf1131b77d3665aa85d6629722',1,'obufstream::obufstream()'],['../classobufstream.html#a7af0555c5c08ebf9cbc70fc5e2f67db7',1,'obufstream::obufstream(char *buf, size_t size)']]], + ['oct',['oct',['../ios_8h.html#ae661b435df22f8e8e643817f4f915123',1,'ios.h']]], + ['ofstream',['ofstream',['../classofstream.html#ae8a8145adf2cfe1f948ad482ed504b75',1,'ofstream']]], + ['open',['open',['../class_fat_file.html#a5f64576d3d19177ab3cf3812b69abdfa',1,'FatFile::open(FatFileSystem *fs, const char *path, uint8_t oflag)'],['../class_fat_file.html#ad3fa9daaccb4e4179fb88a8ca037aa80',1,'FatFile::open(FatFile *dirFile, uint16_t index, uint8_t oflag)'],['../class_fat_file.html#a211be757679b18708f6b6a36464e4f61',1,'FatFile::open(FatFile *dirFile, const char *path, uint8_t oflag)'],['../class_fat_file.html#ab0e7075062c89f356441f80fc64d03e6',1,'FatFile::open(const char *path, uint8_t oflag=O_READ)'],['../class_fat_file_system.html#a947e4586077a922892b632edac33b67a',1,'FatFileSystem::open(const char *path, uint8_t mode=FILE_READ)'],['../class_fat_file_system.html#a0abfb1f754a8fb559cfa884ee040f56f',1,'FatFileSystem::open(const String &path, uint8_t mode=FILE_READ)'],['../classfstream.html#a85b24d94552991f33caf4c3a83420879',1,'fstream::open()'],['../classifstream.html#a169694d6535fd551fd6db48a2867590e',1,'ifstream::open()'],['../classofstream.html#a4b9d30c742fbe01baa336406c7afdcb2',1,'ofstream::open()']]], + ['opennext',['openNext',['../class_fat_file.html#a8034c4649eb0d26715b1a8a69e73d9d0',1,'FatFile']]], + ['opennextfile',['openNextFile',['../class_file.html#acd72000ab1f6a1ce73ac8fbdc854ae0c',1,'File']]], + ['openroot',['openRoot',['../class_fat_file.html#a7e0c0548fed3a69e7284b91b694439d4',1,'FatFile']]], + ['operator_20bool',['operator bool',['../class_minimum_serial.html#a73a1a2a92604ecb8507afde0022aedd8',1,'MinimumSerial::operator bool()'],['../class_file.html#af171fbf441c899cf71d88b8b0b83d38b',1,'File::operator bool()']]], + ['operator_20const_20void_20_2a',['operator const void *',['../classios.html#a8c2e7e42e31d3d7898a51c0bc837b2a3',1,'ios']]], + ['operator_21',['operator!',['../classios.html#a1ae2d4f1ccdfcaaef6a3a8ac9e28c267',1,'ios']]], + ['operator_3c_3c',['operator<<',['../classostream.html#a4dfc0cdb38bced959ba7cf963db38c30',1,'ostream::operator<<(ostream &(*pf)(ostream &str))'],['../classostream.html#af52c607ea168aff1025222c62cad392f',1,'ostream::operator<<(ios_base &(*pf)(ios_base &str))'],['../classostream.html#a63e3999be154253cf92a45c22e548f51',1,'ostream::operator<<(bool arg)'],['../classostream.html#a618b5d6861dde2347847102b89e0ccfa',1,'ostream::operator<<(const char *arg)'],['../classostream.html#aebe24ff723b806cbee19deb2165d0a5b',1,'ostream::operator<<(const signed char *arg)'],['../classostream.html#ac0cf68ffa4706994f47acb1fa37c601a',1,'ostream::operator<<(const unsigned char *arg)'],['../classostream.html#a1d1e11d2fadaf4c9e34194a1f28572e4',1,'ostream::operator<<(char arg)'],['../classostream.html#ad06f8c6c47667e9c7b14620882c09434',1,'ostream::operator<<(signed char arg)'],['../classostream.html#a69912ec4a8536f289b716e95953d09d7',1,'ostream::operator<<(unsigned char arg)'],['../classostream.html#a8065697d56d5e5d1a0ca50c1916b4955',1,'ostream::operator<<(double arg)'],['../classostream.html#a6c68e418e19d9dcdfe6b1790b2621666',1,'ostream::operator<<(float arg)'],['../classostream.html#a227c47e2b631f29d8873b00290bb4872',1,'ostream::operator<<(short arg)'],['../classostream.html#ace10a3a767dc55faff2cec71cd0a89b1',1,'ostream::operator<<(unsigned short arg)'],['../classostream.html#a62488f7ce7822c777ea27d15223b8e5f',1,'ostream::operator<<(int arg)'],['../classostream.html#ad31df6cd88c7248c01808e40889a7907',1,'ostream::operator<<(unsigned int arg)'],['../classostream.html#a15db9977ed82e503bd3cd1f585acf9e6',1,'ostream::operator<<(long arg)'],['../classostream.html#aaedd44fefa48cf3f0967fcd699a2909d',1,'ostream::operator<<(unsigned long arg)'],['../classostream.html#a2a8febd7c07f078120dd69bb71f25a94',1,'ostream::operator<<(const void *arg)'],['../classostream.html#a99ee8d9265d9354f197d02a3d17116be',1,'ostream::operator<<(const __FlashStringHelper *arg)'],['../iostream_8h.html#aa125ac928f3377cbc6e3cf288b9378fd',1,'operator<<(ostream &os, const setfill &arg): iostream.h'],['../iostream_8h.html#a23d4c29ef8ae37ec7d972d0b66187652',1,'operator<<(ostream &os, const setprecision &arg): iostream.h'],['../iostream_8h.html#a331649f2fdb01ed069dc18a5fad781b1',1,'operator<<(ostream &os, const setw &arg): iostream.h']]], + ['operator_3e_3e',['operator>>',['../classistream.html#aa67d3b8ac67e2097d876a66657ec6067',1,'istream::operator>>(istream &(*pf)(istream &str))'],['../classistream.html#ac6e2f17c80edd19deecdc20f804c424e',1,'istream::operator>>(ios_base &(*pf)(ios_base &str))'],['../classistream.html#a5a0a2c0e06abadb79951ebe34f36d62a',1,'istream::operator>>(ios &(*pf)(ios &str))'],['../classistream.html#a99db66d2e192f02deff0171ad098271f',1,'istream::operator>>(char *str)'],['../classistream.html#addaf5e0f39a15cc213117165dfef0d77',1,'istream::operator>>(char &ch)'],['../classistream.html#a390af4d28adbdc537e436f2121d1c862',1,'istream::operator>>(signed char *str)'],['../classistream.html#a49ab1a573fbf69809d19a52855a30072',1,'istream::operator>>(signed char &ch)'],['../classistream.html#a52e85d01198968330f20026a52cb9f72',1,'istream::operator>>(unsigned char *str)'],['../classistream.html#a74875fcf9ccdc0dca4b46a0b66821798',1,'istream::operator>>(unsigned char &ch)'],['../classistream.html#a3708636d095d360695e9c23335639317',1,'istream::operator>>(bool &arg)'],['../classistream.html#a662060e885a0551c390b7042b3b9e4a5',1,'istream::operator>>(short &arg)'],['../classistream.html#a31a706a374c5a594e400734b8992e2a0',1,'istream::operator>>(unsigned short &arg)'],['../classistream.html#ae8451bc86d83828892d9d67c67b7f02b',1,'istream::operator>>(int &arg)'],['../classistream.html#a35c9847ebf7b822c5ec9742e9de19345',1,'istream::operator>>(unsigned int &arg)'],['../classistream.html#aa26e7f35e74d96803bb0dfb3fb0dc154',1,'istream::operator>>(long &arg)'],['../classistream.html#a5aafa4c7f6615a7f1441962b61b8ef59',1,'istream::operator>>(unsigned long &arg)'],['../classistream.html#af9bf453725ce1d9ef62142a7ee38936e',1,'istream::operator>>(double &arg)'],['../classistream.html#aa8efce6fecab80cf7a17d5dfa31f5aa8',1,'istream::operator>>(float &arg)'],['../classistream.html#a62ef4762feacc64a8acdcbf8f1296936',1,'istream::operator>>(void *&arg)'],['../iostream_8h.html#a4a4079de901e0f3f10c743115bd345b2',1,'operator>>(istream &obj, const setfill &arg): iostream.h'],['../iostream_8h.html#a2f819cd0ccda31a8b648f20534469308',1,'operator>>(istream &is, const setprecision &arg): iostream.h'],['../iostream_8h.html#a8d1b3da6f1074322a6e9e11ff4ce8c33',1,'operator>>(istream &is, const setw &arg): iostream.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_d.html b/libraries/SdFat/extras/html/search/functions_d.html new file mode 100644 index 0000000..58b3d31 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_d.js b/libraries/SdFat/extras/html/search/functions_d.js new file mode 100644 index 0000000..0ab9be2 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_d.js @@ -0,0 +1,23 @@ +var searchData= +[ + ['peek',['peek',['../class_print_file.html#a3a2a66f4a0cb69ab4edc66d39997fda7',1,'PrintFile::peek()'],['../class_file.html#a0e5025f39bd584563bfe4b05fc1db268',1,'File::peek()'],['../class_fat_file.html#ac05b7136b887539426856c623869aa3a',1,'FatFile::peek()'],['../classistream.html#a4022265e0ede3698454f1ff59348c14a',1,'istream::peek()']]], + ['position',['position',['../class_file.html#aae991c597c0bc4c5eb44c1f3b06a21ec',1,'File']]], + ['precision',['precision',['../classios__base.html#a9d36cb5a859b74e04f640d2f5e53b41d',1,'ios_base::precision() const '],['../classios__base.html#a5b70cc65fc2c276136fea99bddedb6f0',1,'ios_base::precision(unsigned int n)']]], + ['print',['print',['../class_stdio_stream.html#ad3f6ee8e8ca5dcf6dabfd88199b172e2',1,'StdioStream::print(char c)'],['../class_stdio_stream.html#a1158ea5f9bf041f21b1733b7811c9bb9',1,'StdioStream::print(const char *str)'],['../class_stdio_stream.html#aac4d7b3548d03b8fd70adf12c7ee315c',1,'StdioStream::print(const __FlashStringHelper *str)'],['../class_stdio_stream.html#a26f5b98560b6771225005b073166108b',1,'StdioStream::print(double val, uint8_t prec=2)'],['../class_stdio_stream.html#a06b6eb9f0a7000fdcc73cd6af8d40560',1,'StdioStream::print(float val, uint8_t prec=2)'],['../class_stdio_stream.html#a7129f85c7c5f16867f467731ef84dee9',1,'StdioStream::print(T val)']]], + ['printcreatedatetime',['printCreateDateTime',['../class_fat_file.html#a558530f20314a8d8ee3d1a488fc7f46e',1,'FatFile']]], + ['printdec',['printDec',['../class_stdio_stream.html#ac0a907feb1e4b7e00de99857b4c0a470',1,'StdioStream::printDec(char n)'],['../class_stdio_stream.html#a2707ea97f6113c226781469f4f39ff62',1,'StdioStream::printDec(signed char n)'],['../class_stdio_stream.html#a6e6ac78caa6259a4c4934707bf497a2b',1,'StdioStream::printDec(unsigned char n)'],['../class_stdio_stream.html#a218af88db35f38babf01d6e0a9cdceeb',1,'StdioStream::printDec(int16_t n)'],['../class_stdio_stream.html#a90b2999af94a3578fff7579c2acf8e35',1,'StdioStream::printDec(uint16_t n)'],['../class_stdio_stream.html#ad4591f1234b57f63c1acf0f3392099ac',1,'StdioStream::printDec(int32_t n)'],['../class_stdio_stream.html#a8b6c2c80342abe45e6f564e9bd5bb7ea',1,'StdioStream::printDec(uint32_t n)'],['../class_stdio_stream.html#aaa8921947d4dbbae840d285cb633e8aa',1,'StdioStream::printDec(double value, uint8_t prec)'],['../class_stdio_stream.html#a6a09284b1c6d0769c27916a2e131e749',1,'StdioStream::printDec(float value, uint8_t prec)']]], + ['printfatdate',['printFatDate',['../class_fat_file.html#a8fdb038aafdf3a17ac80b53c063aa73b',1,'FatFile::printFatDate(uint16_t fatDate)'],['../class_fat_file.html#ada5364f66204b1a64afbf9d2e6cd2b0b',1,'FatFile::printFatDate(print_t *pr, uint16_t fatDate)']]], + ['printfattime',['printFatTime',['../class_fat_file.html#a7740731f08ef97de7dfbc9b075c4c7d1',1,'FatFile::printFatTime(uint16_t fatTime)'],['../class_fat_file.html#a4e7e56ba52ca17c602af1b85684b09a9',1,'FatFile::printFatTime(print_t *pr, uint16_t fatTime)']]], + ['printfield',['printField',['../class_fat_file.html#a7478cad0f9e5079311b9e1fa558016ff',1,'FatFile::printField(float value, char term, uint8_t prec=2)'],['../class_fat_file.html#abd3e1747511216462b3ef98167156cbb',1,'FatFile::printField(int16_t value, char term)'],['../class_fat_file.html#a9972c2419c293ef9c382bff666b9ae4d',1,'FatFile::printField(uint16_t value, char term)'],['../class_fat_file.html#a41b3b32dd8482429b74c7af3432d6cf8',1,'FatFile::printField(int32_t value, char term)'],['../class_fat_file.html#a097240f08baadeb1c64b63eab9afb088',1,'FatFile::printField(uint32_t value, char term)'],['../class_stdio_stream.html#a4988592ada39c4b4c603b061f84d183f',1,'StdioStream::printField(double value, char term, uint8_t prec=2)'],['../class_stdio_stream.html#a3b90b2317cc391f94784a847f5313c08',1,'StdioStream::printField(float value, char term, uint8_t prec=2)'],['../class_stdio_stream.html#a02c2ad1a2e71e82d238b8386cf3e6c41',1,'StdioStream::printField(T value, char term)']]], + ['printfile',['PrintFile',['../class_print_file.html#adc3bcb2a5c4207de7ff7e9be3ac54233',1,'PrintFile']]], + ['printfilesize',['printFileSize',['../class_fat_file.html#a12a5d2de2737c201aa39ca1bd2ab9c47',1,'FatFile']]], + ['printhex',['printHex',['../class_stdio_stream.html#add39b2b4ec3daa7c8922e96ce5d368bc',1,'StdioStream']]], + ['printhexln',['printHexln',['../class_stdio_stream.html#aec6ebea511489b0ef6b61d9132d93af9',1,'StdioStream']]], + ['println',['println',['../class_stdio_stream.html#ad0cd3acc05a91456f505752377bd405a',1,'StdioStream::println()'],['../class_stdio_stream.html#a3793dd66cf347a1ca0b7b167e948cce9',1,'StdioStream::println(double val, uint8_t prec=2)'],['../class_stdio_stream.html#aac250d041a7844c8db1cbd2d97ecfdaa',1,'StdioStream::println(float val, uint8_t prec=2)'],['../class_stdio_stream.html#a3b14532768d07e6ed89c762d04792c12',1,'StdioStream::println(T val)']]], + ['printmodifydatetime',['printModifyDateTime',['../class_fat_file.html#a05cee5df46a370bf916d3ba597c82e39',1,'FatFile']]], + ['printname',['printName',['../class_fat_file.html#ad1cbc3aeb0f5193b7a26595966da9621',1,'FatFile::printName()'],['../class_fat_file.html#afe18a787fb8640e2d2483370c770f82f',1,'FatFile::printName(print_t *pr)']]], + ['printsfn',['printSFN',['../class_fat_file.html#a791cd7aade71f609aab62ec018aea3c0',1,'FatFile']]], + ['put',['put',['../classostream.html#a11aad8a1efd284ccfa91cbfb78d089bd',1,'ostream']]], + ['putc',['putc',['../class_stdio_stream.html#adf9e552212aad6fc2284da0ee62d04dc',1,'StdioStream']]], + ['putcrlf',['putCRLF',['../class_stdio_stream.html#a09ccc4b6cabc3502c1052e85d94e84ef',1,'StdioStream']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_e.html b/libraries/SdFat/extras/html/search/functions_e.html new file mode 100644 index 0000000..b44e5c5 --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_e.js b/libraries/SdFat/extras/html/search/functions_e.js new file mode 100644 index 0000000..cf628ae --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_e.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['rdstate',['rdstate',['../classios.html#aacc57e1e46e23f2f54898ff6a89129a2',1,'ios']]], + ['read',['read',['../class_minimum_serial.html#a4890dd60f2ffb61eba0821cc80d411ad',1,'MinimumSerial::read()'],['../class_file.html#a4c46a1975e66c37977bf07c58ec10b4e',1,'File::read()'],['../class_fat_file.html#a60ae55ff6fe158c2340071d702a363c5',1,'FatFile::read()'],['../class_fat_file.html#a200e6e0553d5b709520c9dfac9ef77dd',1,'FatFile::read(void *buf, size_t nbyte)'],['../class_fat_cache.html#ac2bb0b8f2ce3ab5cd86cf30b4a663cea',1,'FatCache::read()']]], + ['readblock',['readBlock',['../class_base_block_driver.html#a16bb3305f3130253dd7ab6e19aa1b524',1,'BaseBlockDriver::readBlock()'],['../class_sdio_card.html#ac94605c428fa9258106835cceec470d8',1,'SdioCard::readBlock()'],['../class_sd_spi_card.html#a4393634a82c6683ee94d1fefe0be332a',1,'SdSpiCard::readBlock()'],['../class_sd_spi_card_e_x.html#abb69c8bd538dafed1e7f33382ee48d61',1,'SdSpiCardEX::readBlock()']]], + ['readblocks',['readBlocks',['../class_base_block_driver.html#a3a029a2d02fc7cbdd7c15c8d622565c4',1,'BaseBlockDriver::readBlocks()'],['../class_sdio_card.html#a7de36d26a01dc39b7dc122c54ee03b12',1,'SdioCard::readBlocks()'],['../class_sd_spi_card.html#ac630f77c3137923b47c1bd12a9bbfadf',1,'SdSpiCard::readBlocks()'],['../class_sd_spi_card_e_x.html#a9e158cda94fadd12267fe7e63d06622a',1,'SdSpiCardEX::readBlocks()']]], + ['readcid',['readCID',['../class_sdio_card.html#add77777fbcf91cc41e8ec62fda169e79',1,'SdioCard::readCID()'],['../class_sd_spi_card.html#aa073dc42828164883db1b9faeff909ea',1,'SdSpiCard::readCID()']]], + ['readcsd',['readCSD',['../class_sdio_card.html#a1da0ca418c153e24b4e13b4c1e20d450',1,'SdioCard::readCSD()'],['../class_sd_spi_card.html#a9fbea9525e70f6e3602fe5153a5a1290',1,'SdSpiCard::readCSD()']]], + ['readdata',['readData',['../class_sd_spi_card.html#a3a1d1b4b4ceb42fcd41aaf6649482770',1,'SdSpiCard']]], + ['readdir',['readDir',['../class_fat_file.html#a1325afe074c3efecff666678cd9f116a',1,'FatFile']]], + ['readline',['readline',['../class_arduino_in_stream.html#ad4c60f813b8df6dd1d6696a3458de09c',1,'ArduinoInStream']]], + ['readocr',['readOCR',['../class_sdio_card.html#adc583f7a27f57ce55ce474b1379b9303',1,'SdioCard::readOCR()'],['../class_sd_spi_card.html#ab446e49338b3ce834a750ac6dae35f61',1,'SdSpiCard::readOCR()']]], + ['readstart',['readStart',['../class_sd_spi_card.html#a3b1710d11496c32ba4323831e00ac6d1',1,'SdSpiCard']]], + ['readstatus',['readStatus',['../class_sd_spi_card.html#a91d0413599efe0d63c8c2dfe4a12d9ae',1,'SdSpiCard']]], + ['readstop',['readStop',['../class_sd_spi_card.html#afdac7c399fa1ba3f904cf503526e007e',1,'SdSpiCard']]], + ['remove',['remove',['../class_fat_file.html#ac837a537fbcca14c7aa390c5fc9f4e7c',1,'FatFile::remove()'],['../class_fat_file.html#afe820bbb056863e91ec482961c8dc695',1,'FatFile::remove(FatFile *dirFile, const char *path)'],['../class_fat_file_system.html#abf7d7d0dab43083d5be10d70ff4669e4',1,'FatFileSystem::remove()']]], + ['rename',['rename',['../class_fat_file.html#a4b42f2454ff462555c07ea094a92a1e0',1,'FatFile::rename()'],['../class_fat_file_system.html#a0187891a24017b41bd7c5ba63e659e65',1,'FatFileSystem::rename()']]], + ['rewind',['rewind',['../class_fat_file.html#a5aac6e0b3cb08fc8b8668e916a8b0ca5',1,'FatFile::rewind()'],['../class_stdio_stream.html#ad985866675193d2ee1dde9e27b0d08da',1,'StdioStream::rewind()']]], + ['rewinddirectory',['rewindDirectory',['../class_file.html#ae1419603dea25a6c8480b941d7ac63a3',1,'File']]], + ['right',['right',['../ios_8h.html#aee80fd600c5c58a2bebbd48afdcf8280',1,'ios.h']]], + ['rmdir',['rmdir',['../class_fat_file.html#a9515bac181d33e7f0125e88fa2ccd283',1,'FatFile::rmdir()'],['../class_fat_file_system.html#aaed2edc7ff7fedb163458c870bb41b33',1,'FatFileSystem::rmdir()']]], + ['rmrfstar',['rmRfStar',['../class_fat_file.html#ac780a80526f86d3def701ecdc99d8bfe',1,'FatFile']]], + ['rootdirentrycount',['rootDirEntryCount',['../class_fat_volume.html#ab2d483670a0a6a6a4754b23614fe11bc',1,'FatVolume']]], + ['rootdirstart',['rootDirStart',['../class_fat_volume.html#ae9363ebbbae90e895ea56e8fa3f60c13',1,'FatVolume']]] +]; diff --git a/libraries/SdFat/extras/html/search/functions_f.html b/libraries/SdFat/extras/html/search/functions_f.html new file mode 100644 index 0000000..db9a07c --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/functions_f.js b/libraries/SdFat/extras/html/search/functions_f.js new file mode 100644 index 0000000..858c87a --- /dev/null +++ b/libraries/SdFat/extras/html/search/functions_f.js @@ -0,0 +1,32 @@ +var searchData= +[ + ['sdbasefile',['SdBaseFile',['../class_sd_base_file.html#a94d44fc448dc8a06867d490100a57781',1,'SdBaseFile']]], + ['sdfat',['SdFat',['../class_sd_fat.html#a232871b6bbd0f40d6a2883b3c7b0425f',1,'SdFat']]], + ['sdfatex',['SdFatEX',['../class_sd_fat_e_x.html#a86b1fdf8b81dff2fced176d39b851474',1,'SdFatEX']]], + ['sdfile',['SdFile',['../class_sd_file.html#aca7da9858a5e53e10f3c2fa9aeca8485',1,'SdFile']]], + ['sdspicard',['SdSpiCard',['../class_sd_spi_card.html#a0441c5da53bd3bd72fb833fc940f25e8',1,'SdSpiCard']]], + ['seek',['seek',['../class_file.html#a2d41ea52356b769e05e1242685758c08',1,'File']]], + ['seekcur',['seekCur',['../class_fat_file.html#a5812037ea30777cc350698ad26f2c73f',1,'FatFile']]], + ['seekend',['seekEnd',['../class_fat_file.html#a84f677f4e75ef6fa2eb632f4cdf6b486',1,'FatFile']]], + ['seekg',['seekg',['../classistream.html#a52d637b1aeca9946085a4a72e0208aec',1,'istream::seekg(pos_type pos)'],['../classistream.html#a60dd48a3b374fb9cbdc59e1f930dea95',1,'istream::seekg(off_type off, seekdir way)']]], + ['seekp',['seekp',['../classostream.html#a18b453d2770a8852c312cbda919c4687',1,'ostream::seekp(pos_type pos)'],['../classostream.html#af6265a5be29237517b30673667ba4213',1,'ostream::seekp(off_type off, seekdir way)']]], + ['seekset',['seekSet',['../class_fat_file.html#ab067190d25733ed7e697d9890f61fd7a',1,'FatFile']]], + ['setcwd',['setCwd',['../class_fat_file.html#a360ef9c05e677271bed6c0a4d663634c',1,'FatFile']]], + ['setf',['setf',['../classios__base.html#ab5db835cb45bba7684ebf72d9a3cccb4',1,'ios_base::setf(fmtflags fl)'],['../classios__base.html#a74dbc93607ab7d68a87ec326b92b6c81',1,'ios_base::setf(fmtflags fl, fmtflags mask)']]], + ['setfill',['setfill',['../structsetfill.html#abcd87f0632678d277df55406d25c8325',1,'setfill']]], + ['setpos',['setpos',['../class_fat_file.html#acf264de4e3ca36c5e8a39e56173c9044',1,'FatFile']]], + ['setprecision',['setprecision',['../structsetprecision.html#a73fce143591989f56ef887a2ea86ac45',1,'setprecision']]], + ['setstate',['setstate',['../classios.html#aee5d194656bdfb0c8621b23ea2f51afb',1,'ios']]], + ['setw',['setw',['../structsetw.html#afd8bfd075474f63df3c8b44ad47517d2',1,'setw']]], + ['showbase',['showbase',['../ios_8h.html#a73159e1398939807aeae6015dd86f2f4',1,'ios.h']]], + ['showpoint',['showpoint',['../ios_8h.html#a322f5897ace09768cd782f0c8f222770',1,'ios.h']]], + ['showpos',['showpos',['../ios_8h.html#a80798554dbfece679adb0e05eb855943',1,'ios.h']]], + ['size',['size',['../class_file.html#a603d3cd3319142d00a7ebd434970b017',1,'File']]], + ['skipwhite',['skipWhite',['../classistream.html#a0f7468be86d93de5d33fa99095898279',1,'istream']]], + ['skipws',['skipws',['../ios_8h.html#a972282e5d9d894f61c8a54423858c0a4',1,'ios.h']]], + ['spistart',['spiStart',['../class_sd_spi_card.html#aa39feb6ebb269071ac6843a424ac311c',1,'SdSpiCard']]], + ['spistop',['spiStop',['../class_sd_spi_card.html#a1033a4a68d38f52dddf6a1764fcca3e1',1,'SdSpiCard']]], + ['stdiostream',['StdioStream',['../class_stdio_stream.html#a96b2c027e76bfca6d6835c9ae1be2ad2',1,'StdioStream']]], + ['sync',['sync',['../class_fat_file.html#a67f3dc4896c542d695e11aac927f585e',1,'FatFile::sync()'],['../class_fat_cache.html#a4d76d4f46ce5994f6fc4678a7b4f8cf1',1,'FatCache::sync()']]], + ['syncblocks',['syncBlocks',['../class_base_block_driver.html#a5361ff2658d7654bf00b97c54c6aa2aa',1,'BaseBlockDriver::syncBlocks()'],['../class_sdio_card.html#affcd36a5c3a42042fe24716671f06632',1,'SdioCard::syncBlocks()'],['../class_sd_spi_card.html#a1b6d5f412c4ad75c2f575ca75c56c095',1,'SdSpiCard::syncBlocks()'],['../class_sd_spi_card_e_x.html#af4a7c15bae6add50d66d066c0927a021',1,'SdSpiCardEX::syncBlocks()']]] +]; diff --git a/libraries/SdFat/extras/html/search/mag_sel.png b/libraries/SdFat/extras/html/search/mag_sel.png new file mode 100644 index 0000000..81f6040 Binary files /dev/null and b/libraries/SdFat/extras/html/search/mag_sel.png differ diff --git a/libraries/SdFat/extras/html/search/nomatches.html b/libraries/SdFat/extras/html/search/nomatches.html new file mode 100644 index 0000000..b1ded27 --- /dev/null +++ b/libraries/SdFat/extras/html/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
+
No Matches
+
+ + diff --git a/libraries/SdFat/extras/html/search/pages_0.html b/libraries/SdFat/extras/html/search/pages_0.html new file mode 100644 index 0000000..75d203d --- /dev/null +++ b/libraries/SdFat/extras/html/search/pages_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/pages_0.js b/libraries/SdFat/extras/html/search/pages_0.js new file mode 100644 index 0000000..b18ff99 --- /dev/null +++ b/libraries/SdFat/extras/html/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['arduino_20_25sdfat_20library',['Arduino %SdFat Library',['../index.html',1,'']]] +]; diff --git a/libraries/SdFat/extras/html/search/search.css b/libraries/SdFat/extras/html/search/search.css new file mode 100644 index 0000000..4d7612f --- /dev/null +++ b/libraries/SdFat/extras/html/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + position: absolute; + float: none; + display: inline; + margin-top: 8px; + right: 0px; + width: 170px; + z-index: 102; + background-color: white; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:111px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:0px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 1; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/libraries/SdFat/extras/html/search/search.js b/libraries/SdFat/extras/html/search/search.js new file mode 100644 index 0000000..dedce3b --- /dev/null +++ b/libraries/SdFat/extras/html/search/search.js @@ -0,0 +1,791 @@ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/typedefs_0.js b/libraries/SdFat/extras/html/search/typedefs_0.js new file mode 100644 index 0000000..f638c2b --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['blockdriver',['BlockDriver',['../_block_driver_8h.html#ace97f2377acdc471a01f9f7ec1fd6bbb',1,'BlockDriver.h']]], + ['bpb_5ft',['bpb_t',['../_fat_structs_8h.html#a5c8af240713e05e7e6c959006ced35fb',1,'FatStructs.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/typedefs_1.html b/libraries/SdFat/extras/html/search/typedefs_1.html new file mode 100644 index 0000000..c44c36f --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/typedefs_1.js b/libraries/SdFat/extras/html/search/typedefs_1.js new file mode 100644 index 0000000..d85cd76 --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['dir_5ft',['dir_t',['../_fat_structs_8h.html#a803db59d4e16a0c54a647afc6a7954e3',1,'FatStructs.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/typedefs_2.html b/libraries/SdFat/extras/html/search/typedefs_2.html new file mode 100644 index 0000000..d64bac3 --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/typedefs_2.js b/libraries/SdFat/extras/html/search/typedefs_2.js new file mode 100644 index 0000000..c41622d --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_2.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['fat32_5fboot_5ft',['fat32_boot_t',['../_fat_structs_8h.html#a38fa081d004647a828095d31b07ec491',1,'FatStructs.h']]], + ['fat32_5ffsinfo_5ft',['fat32_fsinfo_t',['../_fat_structs_8h.html#a6030ed0fce3a819326a2548407fc8556',1,'FatStructs.h']]], + ['fat_5fboot_5ft',['fat_boot_t',['../_fat_structs_8h.html#aedac4595ee08198da26c14b9891a07d5',1,'FatStructs.h']]], + ['fmtflags',['fmtflags',['../classios__base.html#ac9a54e52cef4f01ac0afd8ae896a3413',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/typedefs_3.html b/libraries/SdFat/extras/html/search/typedefs_3.html new file mode 100644 index 0000000..10b9917 --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/typedefs_3.js b/libraries/SdFat/extras/html/search/typedefs_3.js new file mode 100644 index 0000000..14dc331 --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['iostate',['iostate',['../classios__base.html#aef19291eeae0f072ac42c6ba1fe3033c',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/typedefs_4.html b/libraries/SdFat/extras/html/search/typedefs_4.html new file mode 100644 index 0000000..c1ff64d --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/typedefs_4.js b/libraries/SdFat/extras/html/search/typedefs_4.js new file mode 100644 index 0000000..54a6125 --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['ldir_5ft',['ldir_t',['../_fat_structs_8h.html#aa1b540ee1eedd1aa9b267d11cba0d9e2',1,'FatStructs.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/typedefs_5.html b/libraries/SdFat/extras/html/search/typedefs_5.html new file mode 100644 index 0000000..14adc8e --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/typedefs_5.js b/libraries/SdFat/extras/html/search/typedefs_5.js new file mode 100644 index 0000000..765b832 --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['mbr_5ft',['mbr_t',['../_fat_structs_8h.html#a7c429e5097f101c8c97663d6c4155bd9',1,'FatStructs.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/typedefs_6.html b/libraries/SdFat/extras/html/search/typedefs_6.html new file mode 100644 index 0000000..742e92b --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/typedefs_6.js b/libraries/SdFat/extras/html/search/typedefs_6.js new file mode 100644 index 0000000..d83d28f --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_6.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['off_5ftype',['off_type',['../classios__base.html#a45de7cca0d01da781f4b886179c65c22',1,'ios_base']]], + ['openmode',['openmode',['../classios__base.html#aaa192ec0dccc43050715553a34644523',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/typedefs_7.html b/libraries/SdFat/extras/html/search/typedefs_7.html new file mode 100644 index 0000000..ad03564 --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/typedefs_7.js b/libraries/SdFat/extras/html/search/typedefs_7.js new file mode 100644 index 0000000..d9134e7 --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_7.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['part_5ft',['part_t',['../_fat_structs_8h.html#a37251e7d5c69a159be727a3fc8c9d0e6',1,'FatStructs.h']]], + ['pos_5ftype',['pos_type',['../classios__base.html#abe85cf1f181b8bce8022f05ab76aae7f',1,'ios_base']]], + ['print_5ft',['print_t',['../_fat_volume_8h.html#ac62f6449331cfe1a71f29be30efe7890',1,'FatVolume.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/typedefs_8.html b/libraries/SdFat/extras/html/search/typedefs_8.html new file mode 100644 index 0000000..4e9ac73 --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/typedefs_8.js b/libraries/SdFat/extras/html/search/typedefs_8.js new file mode 100644 index 0000000..e8ea77a --- /dev/null +++ b/libraries/SdFat/extras/html/search/typedefs_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['streamsize',['streamsize',['../classios__base.html#a82836e1d3cc603fba8f0b54d323a2dff',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_0.html b/libraries/SdFat/extras/html/search/variables_0.html new file mode 100644 index 0000000..c98c046 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_0.js b/libraries/SdFat/extras/html/search/variables_0.js new file mode 100644 index 0000000..c3aa3dc --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['_5f_5fbrkval',['__brkval',['../_free_stack_8h.html#ad193a2cc121e0d4614a1c21eb463fb56',1,'FreeStack.h']]], + ['_5f_5fbss_5fend',['__bss_end',['../_free_stack_8h.html#adbad17f740c2d7f2bc4833681c93c932',1,'FreeStack.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_1.html b/libraries/SdFat/extras/html/search/variables_1.html new file mode 100644 index 0000000..3eab7ea --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_1.js b/libraries/SdFat/extras/html/search/variables_1.js new file mode 100644 index 0000000..4f7759a --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_1.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['adjustfield',['adjustfield',['../classios__base.html#adaaf735381254aa096ebe3605e8bbd0a',1,'ios_base']]], + ['app',['app',['../classios__base.html#a8380aac3c405730708888fdc68905820',1,'ios_base']]], + ['ate',['ate',['../classios__base.html#aa434355c165500065276d955d8b36e99',1,'ios_base']]], + ['attr',['attr',['../structlong_directory_entry.html#aa36bf1210d0c2b3b80948e5f697eb02e',1,'longDirectoryEntry']]], + ['attributes',['attributes',['../structdirectory_entry.html#a16c6cde55c8175c90935c386f1cfb21a',1,'directoryEntry']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_10.html b/libraries/SdFat/extras/html/search/variables_10.html new file mode 100644 index 0000000..7e4c8b2 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_10.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_10.js b/libraries/SdFat/extras/html/search/variables_10.js new file mode 100644 index 0000000..887ae38 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_10.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['reserved1',['reserved1',['../structfat__boot.html#affa7e6efb3ccea19ba7ea0ddadce7463',1,'fat_boot::reserved1()'],['../structfat32__boot.html#a7075c3c00aae071110fd1acb2e6fd599',1,'fat32_boot::reserved1()'],['../structfat32__fsinfo.html#ac24bd4801a60a54e5133ed1bb71bcdaa',1,'fat32_fsinfo::reserved1()']]], + ['reserved2',['reserved2',['../structfat32__fsinfo.html#a9ec0e2756cd7e169268798a558df3814',1,'fat32_fsinfo']]], + ['reservednt',['reservedNT',['../structdirectory_entry.html#afe7d00be85f3b78549b21610050da52b',1,'directoryEntry']]], + ['reservedsectorcount',['reservedSectorCount',['../structbios_parm_block.html#adb4830c345b27293c7d7b97b77f52e01',1,'biosParmBlock::reservedSectorCount()'],['../structfat__boot.html#a13f272a8f780fb43a400f873a3fd7b73',1,'fat_boot::reservedSectorCount()'],['../structfat32__boot.html#a8e490f05ad3552dfbdf8f9332d287ba0',1,'fat32_boot::reservedSectorCount()']]], + ['right',['right',['../classios__base.html#aec064a12730b5d87e718c1864e29ac64',1,'ios_base']]], + ['rootdirentrycount',['rootDirEntryCount',['../structbios_parm_block.html#a9a1b24bb2dbb3a123c4ffc703954d71d',1,'biosParmBlock::rootDirEntryCount()'],['../structfat__boot.html#a2124f89e12307df944f08e6657dbf4af',1,'fat_boot::rootDirEntryCount()'],['../structfat32__boot.html#a94185496fb56c6e0e8078fc3803e9142',1,'fat32_boot::rootDirEntryCount()']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_11.html b/libraries/SdFat/extras/html/search/variables_11.html new file mode 100644 index 0000000..8dd1dba --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_11.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_11.js b/libraries/SdFat/extras/html/search/variables_11.js new file mode 100644 index 0000000..6e928ac --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_11.js @@ -0,0 +1,16 @@ +var searchData= +[ + ['sectorspercluster',['sectorsPerCluster',['../structbios_parm_block.html#a45d5e2d8c93a028a074e8ce3dc751ab5',1,'biosParmBlock::sectorsPerCluster()'],['../structfat__boot.html#ab3063726125b16a2ccad719548d79abd',1,'fat_boot::sectorsPerCluster()'],['../structfat32__boot.html#a63ded2780732f166f7b7d36bc6aed702',1,'fat32_boot::sectorsPerCluster()']]], + ['sectorsperfat16',['sectorsPerFat16',['../structbios_parm_block.html#a24d6e5a9069491d5db6dbe747336985b',1,'biosParmBlock::sectorsPerFat16()'],['../structfat__boot.html#a0d5ab13399759acfa571e49b85600db1',1,'fat_boot::sectorsPerFat16()'],['../structfat32__boot.html#aeaa78272cd42b162ea448e1642f75cab',1,'fat32_boot::sectorsPerFat16()']]], + ['sectorsperfat32',['sectorsPerFat32',['../structbios_parm_block.html#ad80429df03a6b80f79b18cb6e1008d64',1,'biosParmBlock::sectorsPerFat32()'],['../structfat32__boot.html#aa00db084ff2f7e25febef321469adeb9',1,'fat32_boot::sectorsPerFat32()']]], + ['sectorspertrack',['sectorsPerTrack',['../structfat__boot.html#a6d5ceaf374e0607be8b8162bf657f282',1,'fat_boot::sectorsPerTrack()'],['../structfat32__boot.html#a9525b2e63f84a5cf62ea20199cedf5de',1,'fat32_boot::sectorsPerTrack()']]], + ['sectorspertrtack',['sectorsPerTrtack',['../structbios_parm_block.html#a7c27cb7f66c2c9d5266d896e8df227c7',1,'biosParmBlock']]], + ['seqpos',['seqPos',['../structfname__t.html#a96b7c779dec8dd568be3290451078a4e',1,'fname_t']]], + ['sfn',['sfn',['../structfname__t.html#a37ed0c108b1feb81be4f8c041a4336bd',1,'fname_t']]], + ['showbase',['showbase',['../classios__base.html#a7e3373ab307feecfc228bc9bdb29cd01',1,'ios_base']]], + ['showpoint',['showpoint',['../classios__base.html#ac9bb172682e157f037bd7fb82a236ee6',1,'ios_base']]], + ['showpos',['showpos',['../classios__base.html#a7bfa4a883933105d10f8ce2693cb9f21',1,'ios_base']]], + ['skipws',['skipws',['../classios__base.html#a64977c777d6e45826d1be9763f17f824',1,'ios_base']]], + ['stream_5fbuf_5fsize',['STREAM_BUF_SIZE',['../_stdio_stream_8h.html#ad9a6150ef11e2616c1a99bc777df17d3',1,'StdioStream.h']]], + ['structsignature',['structSignature',['../structfat32__fsinfo.html#aa4a9ed657a0f58a7a1c75760c3a79fd4',1,'fat32_fsinfo']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_12.html b/libraries/SdFat/extras/html/search/variables_12.html new file mode 100644 index 0000000..bc2b2f6 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_12.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_12.js b/libraries/SdFat/extras/html/search/variables_12.js new file mode 100644 index 0000000..1307ab9 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_12.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['tailsignature',['tailSignature',['../structfat32__fsinfo.html#a484dd16425e4e687dc914d12309470e0',1,'fat32_fsinfo']]], + ['totalsectors',['totalSectors',['../structpartition_table.html#acf96e59ce648a9a0cf35751c3b6d7730',1,'partitionTable']]], + ['totalsectors16',['totalSectors16',['../structbios_parm_block.html#a686c686fde2fb109bea120f2f434db87',1,'biosParmBlock::totalSectors16()'],['../structfat__boot.html#ac8bd40dd9186882e423e10b0c83e89b7',1,'fat_boot::totalSectors16()'],['../structfat32__boot.html#acbcae2f15475a886f674f932da1deb3f',1,'fat32_boot::totalSectors16()']]], + ['totalsectors32',['totalSectors32',['../structbios_parm_block.html#abead42e130c40e2aa535202e7cb07578',1,'biosParmBlock::totalSectors32()'],['../structfat__boot.html#addeb2dd8f78418edbf544303d44133e2',1,'fat_boot::totalSectors32()'],['../structfat32__boot.html#ab79466016103c2762c6b057dd458d434',1,'fat32_boot::totalSectors32()']]], + ['trunc',['trunc',['../classios__base.html#ae62b8972f37509819e1384214071194b',1,'ios_base']]], + ['type',['type',['../structpartition_table.html#a3861cf276c728c4dd30ca04e74197ee8',1,'partitionTable::type()'],['../structlong_directory_entry.html#a9adb019dbf24cce65c8d1419cd000f91',1,'longDirectoryEntry::type()']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_13.html b/libraries/SdFat/extras/html/search/variables_13.html new file mode 100644 index 0000000..0486c3e --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_13.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_13.js b/libraries/SdFat/extras/html/search/variables_13.js new file mode 100644 index 0000000..9ca0b15 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_13.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['ungetc_5fbuf_5fsize',['UNGETC_BUF_SIZE',['../_stdio_stream_8h.html#a785dd413c0d7b05f95df82d3453ecacd',1,'StdioStream.h']]], + ['uppercase',['uppercase',['../classios__base.html#ade3db1fe3249e87f4c47a9a8916793d9',1,'ios_base']]], + ['usuallyzero',['usuallyZero',['../structmaster_boot_record.html#afacfc863e98f64053cd9459c6dec948f',1,'masterBootRecord']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_14.html b/libraries/SdFat/extras/html/search/variables_14.html new file mode 100644 index 0000000..e613a52 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_14.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_14.js b/libraries/SdFat/extras/html/search/variables_14.js new file mode 100644 index 0000000..abe9f74 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_14.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['volumelabel',['volumeLabel',['../structfat__boot.html#a9ee733f1b1abc0210ec8f9676bba2218',1,'fat_boot::volumeLabel()'],['../structfat32__boot.html#a8e6349f46344145a7320637a58107b3b',1,'fat32_boot::volumeLabel()']]], + ['volumeserialnumber',['volumeSerialNumber',['../structfat__boot.html#ac05e88a0d27f0340ba008834361d2b20',1,'fat_boot::volumeSerialNumber()'],['../structfat32__boot.html#a20768678da224faefd8acf12cabdbfb8',1,'fat32_boot::volumeSerialNumber()']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_15.html b/libraries/SdFat/extras/html/search/variables_15.html new file mode 100644 index 0000000..5b5841e --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_15.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_15.js b/libraries/SdFat/extras/html/search/variables_15.js new file mode 100644 index 0000000..41474a9 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_15.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['w',['w',['../structsetw.html#ab48d915a24d3f3365c9eb76e138a6f4e',1,'setw']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_2.html b/libraries/SdFat/extras/html/search/variables_2.html new file mode 100644 index 0000000..282f35b --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_2.js b/libraries/SdFat/extras/html/search/variables_2.js new file mode 100644 index 0000000..bee02c7 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_2.js @@ -0,0 +1,19 @@ +var searchData= +[ + ['badbit',['badbit',['../classios__base.html#ac8c2c8f2f6bc9e6ce101c20e88ebce35',1,'ios_base']]], + ['basefield',['basefield',['../classios__base.html#a75ce5482aa207d7aa0265d138b50a102',1,'ios_base']]], + ['begincylinderhigh',['beginCylinderHigh',['../structpartition_table.html#a744f0c7f9ad4c426b10de085b4f52392',1,'partitionTable']]], + ['begincylinderlow',['beginCylinderLow',['../structpartition_table.html#a941fcb4df298f5f73ccca011bf40787a',1,'partitionTable']]], + ['beginhead',['beginHead',['../structpartition_table.html#a7d426694b8cf2151ae38568670a8c845',1,'partitionTable']]], + ['beginsector',['beginSector',['../structpartition_table.html#ae201c11d9671c9efc307c654a2b6c026',1,'partitionTable']]], + ['binary',['binary',['../classios__base.html#ac99947c17c2936d15243671366605602',1,'ios_base']]], + ['boolalpha',['boolalpha',['../classios__base.html#afa74acd95d4bbc7cc3551251aac2bf00',1,'ios_base']]], + ['boot',['boot',['../structpartition_table.html#adf386afb1f33046d8b6a1a0afa780ec9',1,'partitionTable']]], + ['bootcode',['bootCode',['../structfat__boot.html#acf9f5d9f61a6e680e11849f957ecf782',1,'fat_boot::bootCode()'],['../structfat32__boot.html#a7a74880066860140386edf3d9278b9f7',1,'fat32_boot::bootCode()']]], + ['bootsectorsig0',['bootSectorSig0',['../structfat__boot.html#a7951b888af4f357b84dd40af2ef7f29d',1,'fat_boot::bootSectorSig0()'],['../structfat32__boot.html#a1cb46a5427b641a6017a082bc56df1be',1,'fat32_boot::bootSectorSig0()']]], + ['bootsectorsig1',['bootSectorSig1',['../structfat__boot.html#afe8f58668ff594bb2022ce7c06b7726c',1,'fat_boot::bootSectorSig1()'],['../structfat32__boot.html#a53bc302a398f02a86d3b28f25a5ec8e2',1,'fat32_boot::bootSectorSig1()']]], + ['bootsig0',['BOOTSIG0',['../_fat_structs_8h.html#acb7f0c892eb84c121c5698b2605e95e3',1,'FatStructs.h']]], + ['bootsig1',['BOOTSIG1',['../_fat_structs_8h.html#a52f90172e11e828b411c803f29853753',1,'FatStructs.h']]], + ['bootsignature',['bootSignature',['../structfat__boot.html#a712dc388c530e91e4a692e7102d6bdc8',1,'fat_boot::bootSignature()'],['../structfat32__boot.html#ab79a1205277ecab05526fb0bac6e42f6',1,'fat32_boot::bootSignature()']]], + ['bytespersector',['bytesPerSector',['../structbios_parm_block.html#aec24d316af486445d55da14cbbfa6bf4',1,'biosParmBlock::bytesPerSector()'],['../structfat__boot.html#a60b2461f8ebf0ad295a95094e1bd7d65',1,'fat_boot::bytesPerSector()'],['../structfat32__boot.html#a03c7086a8c988257a6678179a67a3fee',1,'fat32_boot::bytesPerSector()']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_3.html b/libraries/SdFat/extras/html/search/variables_3.html new file mode 100644 index 0000000..36e31b1 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_3.js b/libraries/SdFat/extras/html/search/variables_3.js new file mode 100644 index 0000000..e1851c2 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_3.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['c',['c',['../structsetfill.html#a42ffb4e6135c1274ae827cfed7793a82',1,'setfill']]], + ['cache_5ffor_5fread',['CACHE_FOR_READ',['../class_fat_cache.html#ab4b446515ff9a0cebc747630ddd10c93',1,'FatCache']]], + ['cache_5ffor_5fwrite',['CACHE_FOR_WRITE',['../class_fat_cache.html#a81cb572f33443bd6aee9aa33ec395d0f',1,'FatCache']]], + ['cache_5foption_5fno_5fread',['CACHE_OPTION_NO_READ',['../class_fat_cache.html#adf974f55e53ee0aaa85abb0d7d67181c',1,'FatCache']]], + ['cache_5freserve_5ffor_5fwrite',['CACHE_RESERVE_FOR_WRITE',['../class_fat_cache.html#a49d2896ff525ab77852f76df5c2a09c2',1,'FatCache']]], + ['cache_5fstatus_5fdirty',['CACHE_STATUS_DIRTY',['../class_fat_cache.html#aac8c38e5c545d0f80b13d816117f626e',1,'FatCache']]], + ['cache_5fstatus_5fmask',['CACHE_STATUS_MASK',['../class_fat_cache.html#ab70dc4a2e387f0e9bf392044c702ae32',1,'FatCache']]], + ['cache_5fstatus_5fmirror_5ffat',['CACHE_STATUS_MIRROR_FAT',['../class_fat_cache.html#a45236e1c0a2a098f08d3add0e4b1467a',1,'FatCache']]], + ['chksum',['chksum',['../structlong_directory_entry.html#a60c35531bc0e12f2d764d290244f8cc9',1,'longDirectoryEntry']]], + ['cluster',['cluster',['../struct_fat_pos__t.html#a7b50657b0debaf0e6231af2c74a655fe',1,'FatPos_t']]], + ['codearea',['codeArea',['../structmaster_boot_record.html#a26ca1fb4ebbff2cc1a54153b1dfcd688',1,'masterBootRecord']]], + ['creationdate',['creationDate',['../structdirectory_entry.html#a7b43372794655fe6604d3c17c02302fe',1,'directoryEntry']]], + ['creationtime',['creationTime',['../structdirectory_entry.html#a622bfa70c2cd9006108d7473d737a953',1,'directoryEntry']]], + ['creationtimetenths',['creationTimeTenths',['../structdirectory_entry.html#aa5e1ce5b411b88f005b28a3e7c7c5af6',1,'directoryEntry']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_4.html b/libraries/SdFat/extras/html/search/variables_4.html new file mode 100644 index 0000000..c736635 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_4.js b/libraries/SdFat/extras/html/search/variables_4.js new file mode 100644 index 0000000..6ca820e --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_4.js @@ -0,0 +1,23 @@ +var searchData= +[ + ['data',['data',['../unioncache__t.html#ae675b7a3a87d809070de111d1d1f1d81',1,'cache_t']]], + ['dec',['dec',['../classios__base.html#a2826aed005e7c1f6858060cddae7971a',1,'ios_base']]], + ['dir',['dir',['../unioncache__t.html#a7396fdbdb7c52bd1d72c5329ff32acd1',1,'cache_t']]], + ['dir_5fatt_5farchive',['DIR_ATT_ARCHIVE',['../_fat_structs_8h.html#a0d0745a2bc191d12f6e3294a890c4b13',1,'FatStructs.h']]], + ['dir_5fatt_5fdefined_5fbits',['DIR_ATT_DEFINED_BITS',['../_fat_structs_8h.html#ad0c6ed5cf186a40f98cc3929b52cf8ee',1,'FatStructs.h']]], + ['dir_5fatt_5fdirectory',['DIR_ATT_DIRECTORY',['../_fat_structs_8h.html#a5fe039a9af7304fc97a0e903acd217f7',1,'FatStructs.h']]], + ['dir_5fatt_5ffile_5ftype_5fmask',['DIR_ATT_FILE_TYPE_MASK',['../_fat_structs_8h.html#af006ada1b85a9761dd9538273c1ee97f',1,'FatStructs.h']]], + ['dir_5fatt_5fhidden',['DIR_ATT_HIDDEN',['../_fat_structs_8h.html#aed394afe98ff4b7876a5815319b6ef94',1,'FatStructs.h']]], + ['dir_5fatt_5flong_5fname',['DIR_ATT_LONG_NAME',['../_fat_structs_8h.html#a0039e1903007eb7383a9fe4b80a3569e',1,'FatStructs.h']]], + ['dir_5fatt_5flong_5fname_5fmask',['DIR_ATT_LONG_NAME_MASK',['../_fat_structs_8h.html#a74ddbd24c315a682449a51a2a35adf39',1,'FatStructs.h']]], + ['dir_5fatt_5fread_5fonly',['DIR_ATT_READ_ONLY',['../_fat_structs_8h.html#ae5efa2fd21e8a563a3a45f8a52538cde',1,'FatStructs.h']]], + ['dir_5fatt_5fsystem',['DIR_ATT_SYSTEM',['../_fat_structs_8h.html#a31c7e5c119c9ebc1237746c985cf385d',1,'FatStructs.h']]], + ['dir_5fatt_5fvolume_5fid',['DIR_ATT_VOLUME_ID',['../_fat_structs_8h.html#a410501be78b30a75224dd4e81a4a1105',1,'FatStructs.h']]], + ['dir_5fname_5f0xe5',['DIR_NAME_0XE5',['../_fat_structs_8h.html#a1696d3db9949d6e22d1c2c595fd14669',1,'FatStructs.h']]], + ['dir_5fname_5fdeleted',['DIR_NAME_DELETED',['../_fat_structs_8h.html#a8c08d4823047505f3231e86c5033d08c',1,'FatStructs.h']]], + ['dir_5fname_5ffree',['DIR_NAME_FREE',['../_fat_structs_8h.html#a0f1f0001102ae59b9e7c9e3b04cc06d8',1,'FatStructs.h']]], + ['dir_5fnt_5flc_5fbase',['DIR_NT_LC_BASE',['../_fat_structs_8h.html#a39f9b8960dba007b537e9b71c25384fe',1,'FatStructs.h']]], + ['dir_5fnt_5flc_5fext',['DIR_NT_LC_EXT',['../_fat_structs_8h.html#a8766a8bbab6ad3da38c1b308545d7572',1,'FatStructs.h']]], + ['disksignature',['diskSignature',['../structmaster_boot_record.html#a77151c641444c0653ff71a253f0423ef',1,'masterBootRecord']]], + ['drivenumber',['driveNumber',['../structfat__boot.html#aebd280b93563b75b9612d3db844b0d16',1,'fat_boot::driveNumber()'],['../structfat32__boot.html#aca415c1a6eb1c242d460a6d0ffa9ebec',1,'fat32_boot::driveNumber()']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_5.html b/libraries/SdFat/extras/html/search/variables_5.html new file mode 100644 index 0000000..4e9e673 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_5.js b/libraries/SdFat/extras/html/search/variables_5.js new file mode 100644 index 0000000..09381d7 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_5.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['endcylinderhigh',['endCylinderHigh',['../structpartition_table.html#a32fea225b8ffd925ad919ffc56e9abda',1,'partitionTable']]], + ['endcylinderlow',['endCylinderLow',['../structpartition_table.html#ad7829e34be70084abe145227b0d18274',1,'partitionTable']]], + ['endhead',['endHead',['../structpartition_table.html#a4a3945bfd3a29f474984cb9f180dbd51',1,'partitionTable']]], + ['endsector',['endSector',['../structpartition_table.html#a27cdc4320c418ed0d833ab163ed77ad7',1,'partitionTable']]], + ['eofbit',['eofbit',['../classios__base.html#af75072b7ef2a931c77a2cb8e7ccda460',1,'ios_base']]], + ['extended_5fboot_5fsig',['EXTENDED_BOOT_SIG',['../_fat_structs_8h.html#aefadfae26e4cc8d57c1ff727a9d1cd20',1,'FatStructs.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_6.html b/libraries/SdFat/extras/html/search/variables_6.html new file mode 100644 index 0000000..3460c61 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_6.js b/libraries/SdFat/extras/html/search/variables_6.js new file mode 100644 index 0000000..fecfaa2 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_6.js @@ -0,0 +1,39 @@ +var searchData= +[ + ['failbit',['failbit',['../classios__base.html#a36157154001bcce17827db6786e35efd',1,'ios_base']]], + ['fat12eoc',['FAT12EOC',['../_fat_structs_8h.html#af314c45d1d37d09c9e44847326232466',1,'FatStructs.h']]], + ['fat12eoc_5fmin',['FAT12EOC_MIN',['../_fat_structs_8h.html#a48951911b522ebf72bf5561c3402aa15',1,'FatStructs.h']]], + ['fat16',['fat16',['../unioncache__t.html#a8f3a4e9392a7d8ace954fc44c57df887',1,'cache_t']]], + ['fat16eoc',['FAT16EOC',['../_fat_structs_8h.html#afcd95ebc621a46c82b9997c8b9208550',1,'FatStructs.h']]], + ['fat16eoc_5fmin',['FAT16EOC_MIN',['../_fat_structs_8h.html#a2f549b850b74666ba7d922bcb373896e',1,'FatStructs.h']]], + ['fat32',['fat32',['../unioncache__t.html#a57e16421bf460d1ba6cb9ce9a23a4a83',1,'cache_t']]], + ['fat32backbootblock',['fat32BackBootBlock',['../structbios_parm_block.html#a7a4e93790b6e66f090c1551020b099bd',1,'biosParmBlock::fat32BackBootBlock()'],['../structfat32__boot.html#ac93acdae62dab5cd1f7a35187992dbf2',1,'fat32_boot::fat32BackBootBlock()']]], + ['fat32eoc',['FAT32EOC',['../_fat_structs_8h.html#a67a9dbf970f43fadd41a6a9fede60c47',1,'FatStructs.h']]], + ['fat32eoc_5fmin',['FAT32EOC_MIN',['../_fat_structs_8h.html#a8f97a312e990c3f4faf7e98c3256aae5',1,'FatStructs.h']]], + ['fat32flags',['fat32Flags',['../structbios_parm_block.html#a626ac3dc473d764688b8171916eecf44',1,'biosParmBlock::fat32Flags()'],['../structfat32__boot.html#aaa31a140202021bf33aed72765531b3f',1,'fat32_boot::fat32Flags()']]], + ['fat32fsinfo',['fat32FSInfo',['../structbios_parm_block.html#a25ea392d8284e6c1d007cb8fcad4b86c',1,'biosParmBlock::fat32FSInfo()'],['../structfat32__boot.html#a03ff6d1197c08688f20c7aad40206bc4',1,'fat32_boot::fat32FSInfo()']]], + ['fat32mask',['FAT32MASK',['../_fat_structs_8h.html#a7491c79fff0bda3b026ffa098a28d6df',1,'FatStructs.h']]], + ['fat32reserved',['fat32Reserved',['../structbios_parm_block.html#a351f87fe3446b1a71963a30bbdc23218',1,'biosParmBlock::fat32Reserved()'],['../structfat32__boot.html#a3343ad07c664fb7564d68c5194ea7da9',1,'fat32_boot::fat32Reserved()']]], + ['fat32rootcluster',['fat32RootCluster',['../structbios_parm_block.html#a77ca01bd99f746e05dd872cbd2979937',1,'biosParmBlock::fat32RootCluster()'],['../structfat32__boot.html#aa216677f22a95dd86ed2e61604883a13',1,'fat32_boot::fat32RootCluster()']]], + ['fat32version',['fat32Version',['../structbios_parm_block.html#abad4f6f0c14dad9f5b7d43de94e685e8',1,'biosParmBlock::fat32Version()'],['../structfat32__boot.html#a29c37e1163772493efb524c5ca0e1aa8',1,'fat32_boot::fat32Version()']]], + ['fat_5fdefault_5fdate',['FAT_DEFAULT_DATE',['../_fat_structs_8h.html#a42eeb0322bced1f7b527c707f8bd54a4',1,'FatStructs.h']]], + ['fat_5fdefault_5ftime',['FAT_DEFAULT_TIME',['../_fat_structs_8h.html#a23c2510407ec3be457e0e4807644deb2',1,'FatStructs.h']]], + ['fatcount',['fatCount',['../structbios_parm_block.html#a7c03f147c3fb18f0df03d346050af13b',1,'biosParmBlock::fatCount()'],['../structfat__boot.html#a04d3b6a45acf28a80ff909dc1b33da2f',1,'fat_boot::fatCount()'],['../structfat32__boot.html#a7882fa8744bd171bfa1512bd442574bc',1,'fat32_boot::fatCount()']]], + ['fbs',['fbs',['../unioncache__t.html#ad1a4f1c0e8b8ca4d530427dbc920c764',1,'cache_t']]], + ['fbs32',['fbs32',['../unioncache__t.html#ad0613173ed4e83920eedfeb33102848a',1,'cache_t']]], + ['filesize',['fileSize',['../structdirectory_entry.html#ac2445d99b50f925f662952e0ccd26a02',1,'directoryEntry']]], + ['filesystemtype',['fileSystemType',['../structfat__boot.html#aee529e32908406866f3ec3c17c4632fa',1,'fat_boot::fileSystemType()'],['../structfat32__boot.html#a13ee6c63e17d634b6826bfdfa94cbd78',1,'fat32_boot::fileSystemType()']]], + ['firstclusterhigh',['firstClusterHigh',['../structdirectory_entry.html#a3b492598b2b05e8425d2a500443613bd',1,'directoryEntry']]], + ['firstclusterlow',['firstClusterLow',['../structdirectory_entry.html#a74bd660417a9c3501eae353326c14bb9',1,'directoryEntry']]], + ['firstsector',['firstSector',['../structpartition_table.html#a02bbdff840c854dc96fa0b6da8589d86',1,'partitionTable']]], + ['flags',['flags',['../structfname__t.html#a39c69edff13165c6e03b308104e7286d',1,'fname_t']]], + ['fname_5fflag_5flc_5fbase',['FNAME_FLAG_LC_BASE',['../_fat_file_8h.html#a79e43960e1b4eecf274f5faea9c3168c',1,'FatFile.h']]], + ['fname_5fflag_5flc_5fext',['FNAME_FLAG_LC_EXT',['../_fat_file_8h.html#a135b7572768b09661aa38afaceec7296',1,'FatFile.h']]], + ['fname_5fflag_5flost_5fchars',['FNAME_FLAG_LOST_CHARS',['../_fat_file_8h.html#acd45286b7dfc5ba68be18c8c3a9d298d',1,'FatFile.h']]], + ['fname_5fflag_5fmixed_5fcase',['FNAME_FLAG_MIXED_CASE',['../_fat_file_8h.html#a63994c21f3b723a55247f063a1b01c9c',1,'FatFile.h']]], + ['fname_5fflag_5fneed_5flfn',['FNAME_FLAG_NEED_LFN',['../_fat_file_8h.html#a1a041207a19d2fd9a1e2739343ccb29b',1,'FatFile.h']]], + ['freecount',['freeCount',['../structfat32__fsinfo.html#a6c2d84388c0a38a74f7682fd602492c7',1,'fat32_fsinfo']]], + ['fsinfo',['fsinfo',['../unioncache__t.html#a46c7b14586a6248824a97101111cbae1',1,'cache_t']]], + ['fsinfo_5flead_5fsig',['FSINFO_LEAD_SIG',['../_fat_structs_8h.html#a7a7a74a7315ad523e3b0c9dbd44d9a32',1,'FatStructs.h']]], + ['fsinfo_5fstruct_5fsig',['FSINFO_STRUCT_SIG',['../_fat_structs_8h.html#a9bf6b77df7bec6c49d81562c54371e81',1,'FatStructs.h']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_7.html b/libraries/SdFat/extras/html/search/variables_7.html new file mode 100644 index 0000000..34e7f98 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_7.js b/libraries/SdFat/extras/html/search/variables_7.js new file mode 100644 index 0000000..26e4052 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['goodbit',['goodbit',['../classios__base.html#a07a00996a6e525b88bdfe7935d5ead05',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_8.html b/libraries/SdFat/extras/html/search/variables_8.html new file mode 100644 index 0000000..1c5802c --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_8.js b/libraries/SdFat/extras/html/search/variables_8.js new file mode 100644 index 0000000..ad9850f --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_8.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['headcount',['headCount',['../structbios_parm_block.html#a2324ca82e2a7da4d91f458fa32a6e239',1,'biosParmBlock::headCount()'],['../structfat__boot.html#ae31da876cd9f48de5268a129218df2c2',1,'fat_boot::headCount()'],['../structfat32__boot.html#a1a5298db692526bc64243766d6b54181',1,'fat32_boot::headCount()']]], + ['hex',['hex',['../classios__base.html#a3608e51eb0a80ea94ddadd5b713a3750',1,'ios_base']]], + ['hidddensectors',['hidddenSectors',['../structbios_parm_block.html#a9413199be8525190d40589f60c22bcab',1,'biosParmBlock::hidddenSectors()'],['../structfat__boot.html#a18f1b4c245fe7bd09f5a9430c005e23a',1,'fat_boot::hidddenSectors()'],['../structfat32__boot.html#ab10224aa4bba42b262fcd3479e279e1f',1,'fat32_boot::hidddenSectors()']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_9.html b/libraries/SdFat/extras/html/search/variables_9.html new file mode 100644 index 0000000..ea8a856 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_9.js b/libraries/SdFat/extras/html/search/variables_9.js new file mode 100644 index 0000000..58cb2a2 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_9.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['in',['in',['../classios__base.html#ae5432e3c269064480652c4602f5f74ad',1,'ios_base']]], + ['internal',['internal',['../classios__base.html#afc720b7f6f461ec8e9cf5505059e5d7c',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_a.html b/libraries/SdFat/extras/html/search/variables_a.html new file mode 100644 index 0000000..f2e7496 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_a.js b/libraries/SdFat/extras/html/search/variables_a.js new file mode 100644 index 0000000..e043c52 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['jump',['jump',['../structfat__boot.html#a83f9f2d1d0130f25f34c90dfc82e3751',1,'fat_boot::jump()'],['../structfat32__boot.html#a2d93fc193a64ecffbd71ead207fe4810',1,'fat32_boot::jump()']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_b.html b/libraries/SdFat/extras/html/search/variables_b.html new file mode 100644 index 0000000..cd7dfb6 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_b.js b/libraries/SdFat/extras/html/search/variables_b.js new file mode 100644 index 0000000..76ff7e4 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_b.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['lastaccessdate',['lastAccessDate',['../structdirectory_entry.html#abca70dc5c5fcbe199fd78df010111331',1,'directoryEntry']]], + ['lastwritedate',['lastWriteDate',['../structdirectory_entry.html#a12b2e7cf87482a942a0b5d3df6c51468',1,'directoryEntry']]], + ['lastwritetime',['lastWriteTime',['../structdirectory_entry.html#a7bab435322d1928f66fbce53ee1f402d',1,'directoryEntry']]], + ['ldir_5fname1_5fdim',['LDIR_NAME1_DIM',['../_fat_structs_8h.html#af843af29c67dd30ca7c5684806bf02fc',1,'FatStructs.h']]], + ['ldir_5fname2_5fdim',['LDIR_NAME2_DIM',['../_fat_structs_8h.html#a99cae591c59e261f54617617e173e7e0',1,'FatStructs.h']]], + ['ldir_5fname3_5fdim',['LDIR_NAME3_DIM',['../_fat_structs_8h.html#a99fbd27fa9e5003a8d77ca7fc14d2090',1,'FatStructs.h']]], + ['ldir_5ford_5flast_5flong_5fentry',['LDIR_ORD_LAST_LONG_ENTRY',['../_fat_structs_8h.html#a8cfb60b9eaf04dcdc6e4f5a466af5540',1,'FatStructs.h']]], + ['leadsignature',['leadSignature',['../structfat32__fsinfo.html#aa8ee056cc1beb1355e15610c1beba5e3',1,'fat32_fsinfo']]], + ['left',['left',['../classios__base.html#ad364df9af2cfde1f40bd8e10c62bb215',1,'ios_base']]], + ['len',['len',['../structfname__t.html#a471184cc4c2671526d7d6fb80b2fe20c',1,'fname_t']]], + ['lfn',['lfn',['../structfname__t.html#a76ffd7abd5b7d3acf90b329c905770fd',1,'fname_t']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_c.html b/libraries/SdFat/extras/html/search/variables_c.html new file mode 100644 index 0000000..4f03f98 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_c.js b/libraries/SdFat/extras/html/search/variables_c.js new file mode 100644 index 0000000..9df4d76 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_c.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['mbr',['mbr',['../unioncache__t.html#a6ac10bfb1ebb1139c448456679663bb6',1,'cache_t']]], + ['mbrsig0',['mbrSig0',['../structmaster_boot_record.html#a42b0b413ecb21ac5314d4f6bca05308f',1,'masterBootRecord']]], + ['mbrsig1',['mbrSig1',['../structmaster_boot_record.html#aafbbcb4f6a2d1181c6458d4c9603df4f',1,'masterBootRecord']]], + ['mediatype',['mediaType',['../structbios_parm_block.html#a4237e7c3ba247516d546c149954e5042',1,'biosParmBlock::mediaType()'],['../structfat__boot.html#a63eaf7185663369af2527309634d3c90',1,'fat_boot::mediaType()'],['../structfat32__boot.html#a3b1ab5d2dc872c0d80cd4f34622de417',1,'fat32_boot::mediaType()']]], + ['mustbezero',['mustBeZero',['../structlong_directory_entry.html#af3055930e869875e49b32ef0b49c3649',1,'longDirectoryEntry']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_d.html b/libraries/SdFat/extras/html/search/variables_d.html new file mode 100644 index 0000000..ec2ae78 --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_d.js b/libraries/SdFat/extras/html/search/variables_d.js new file mode 100644 index 0000000..786e88f --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_d.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['name',['name',['../structdirectory_entry.html#a05dc993ea55a1a742de5970541a31ecb',1,'directoryEntry']]], + ['name1',['name1',['../structlong_directory_entry.html#a629f1ca5ba2ccce6cac5295578b6e7b4',1,'longDirectoryEntry']]], + ['name2',['name2',['../structlong_directory_entry.html#ad763b5a3da4b8d326d9888493fbb819a',1,'longDirectoryEntry']]], + ['name3',['name3',['../structlong_directory_entry.html#a6f14c81b7d224dc4431217f92601257a',1,'longDirectoryEntry']]], + ['nextfree',['nextFree',['../structfat32__fsinfo.html#a539b3bb0a2ead9df417df9ac8b6b1606',1,'fat32_fsinfo']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_e.html b/libraries/SdFat/extras/html/search/variables_e.html new file mode 100644 index 0000000..704caba --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_e.js b/libraries/SdFat/extras/html/search/variables_e.js new file mode 100644 index 0000000..e40f1bb --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_e.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['oct',['oct',['../classios__base.html#a4155540f8d3ffdb8d25a2f50ee4df08f',1,'ios_base']]], + ['oemid',['oemId',['../structfat__boot.html#adc034212201e879fea1eb44db43e55a5',1,'fat_boot::oemId()'],['../structfat32__boot.html#af623a473a960ea20904dce0edfb6bb9d',1,'fat32_boot::oemId()']]], + ['ord',['ord',['../structlong_directory_entry.html#a1b65e85dd63d0708cd1b875ce4e5e338',1,'longDirectoryEntry']]], + ['out',['out',['../classios__base.html#a4c1d517774c0d11af3424e90395f26ae',1,'ios_base']]] +]; diff --git a/libraries/SdFat/extras/html/search/variables_f.html b/libraries/SdFat/extras/html/search/variables_f.html new file mode 100644 index 0000000..3f6c92f --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/libraries/SdFat/extras/html/search/variables_f.js b/libraries/SdFat/extras/html/search/variables_f.js new file mode 100644 index 0000000..64a608f --- /dev/null +++ b/libraries/SdFat/extras/html/search/variables_f.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['p',['p',['../structsetprecision.html#a7cb7bb355a303fa39a8035615bde9348',1,'setprecision']]], + ['part',['part',['../structmaster_boot_record.html#aa4e294e50f311635c10c92f4c99227c5',1,'masterBootRecord']]], + ['position',['position',['../struct_fat_pos__t.html#a8e14c6f2705777502b543452743eaa26',1,'FatPos_t']]] +]; diff --git a/libraries/SdFat/extras/html/splitbar.png b/libraries/SdFat/extras/html/splitbar.png new file mode 100644 index 0000000..fe895f2 Binary files /dev/null and b/libraries/SdFat/extras/html/splitbar.png differ diff --git a/libraries/SdFat/extras/html/struct_fat_pos__t-members.html b/libraries/SdFat/extras/html/struct_fat_pos__t-members.html new file mode 100644 index 0000000..b4b3053 --- /dev/null +++ b/libraries/SdFat/extras/html/struct_fat_pos__t-members.html @@ -0,0 +1,102 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
FatPos_t Member List
+
+
+ +

This is the complete list of members for FatPos_t, including all inherited members.

+ + + + +
clusterFatPos_t
FatPos_t() (defined in FatPos_t)FatPos_tinline
positionFatPos_t
+ + + + diff --git a/libraries/SdFat/extras/html/struct_fat_pos__t.html b/libraries/SdFat/extras/html/struct_fat_pos__t.html new file mode 100644 index 0000000..c21fd63 --- /dev/null +++ b/libraries/SdFat/extras/html/struct_fat_pos__t.html @@ -0,0 +1,144 @@ + + + + + + +SdFat: FatPos_t Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
FatPos_t Struct Reference
+
+
+ +

Internal type for file position - do not use in user apps. + More...

+ +

#include <FatFile.h>

+ + + + + + +

+Public Attributes

uint32_t cluster
 
uint32_t position
 
+

Detailed Description

+

Internal type for file position - do not use in user apps.

+

Member Data Documentation

+ +
+
+ + + + +
uint32_t FatPos_t::cluster
+
+

cluster for position

+ +
+
+ +
+
+ + + + +
uint32_t FatPos_t::position
+
+

stream position

+ +
+
+
The documentation for this struct was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/FatLib/FatFile.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/structbios_parm_block-members.html b/libraries/SdFat/extras/html/structbios_parm_block-members.html new file mode 100644 index 0000000..7fc6fae --- /dev/null +++ b/libraries/SdFat/extras/html/structbios_parm_block-members.html @@ -0,0 +1,118 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
biosParmBlock Member List
+
+ + + + + diff --git a/libraries/SdFat/extras/html/structbios_parm_block.html b/libraries/SdFat/extras/html/structbios_parm_block.html new file mode 100644 index 0000000..4a79561 --- /dev/null +++ b/libraries/SdFat/extras/html/structbios_parm_block.html @@ -0,0 +1,400 @@ + + + + + + +SdFat: biosParmBlock Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
biosParmBlock Struct Reference
+
+
+ +

BIOS parameter block. + More...

+ +

#include <FatStructs.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

uint16_t bytesPerSector
 
uint16_t fat32BackBootBlock
 
uint16_t fat32Flags
 
uint16_t fat32FSInfo
 
uint8_t fat32Reserved [12]
 
uint32_t fat32RootCluster
 
uint16_t fat32Version
 
uint8_t fatCount
 
uint16_t headCount
 
uint32_t hidddenSectors
 
uint8_t mediaType
 
uint16_t reservedSectorCount
 
uint16_t rootDirEntryCount
 
uint8_t sectorsPerCluster
 
uint16_t sectorsPerFat16
 
uint32_t sectorsPerFat32
 
uint16_t sectorsPerTrtack
 
uint16_t totalSectors16
 
uint32_t totalSectors32
 
+

Detailed Description

+

BIOS parameter block.

+

The BIOS parameter block describes the physical layout of a FAT volume.

+

Member Data Documentation

+ +
+
+ + + + +
uint16_t biosParmBlock::bytesPerSector
+
+

Count of bytes per sector. This value may take on only the following values: 512, 1024, 2048 or 4096

+ +
+
+ +
+
+ + + + +
uint16_t biosParmBlock::fat32BackBootBlock
+
+

If nonzero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6. No value other than 6 is recommended.

+ +
+
+ +
+
+ + + + +
uint16_t biosParmBlock::fat32Flags
+
+

This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. Bits 0-3 – Zero-based number of active FAT. Only valid if mirroring is disabled. Bits 4-6 – Reserved. Bit 7 – 0 means the FAT is mirrored at runtime into all FATs. – 1 means only one FAT is active; it is the one referenced in bits 0-3. Bits 8-15 – Reserved.

+ +
+
+ +
+
+ + + + +
uint16_t biosParmBlock::fat32FSInfo
+
+

Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.

+ +
+
+ +
+
+ + + + +
uint8_t biosParmBlock::fat32Reserved[12]
+
+

Reserved for future expansion. Code that formats FAT32 volumes should always set all of the bytes of this field to 0.

+ +
+
+ +
+
+ + + + +
uint32_t biosParmBlock::fat32RootCluster
+
+

Cluster number of the first cluster of the root directory for FAT32. This usually 2 but not required to be 2.

+ +
+
+ +
+
+ + + + +
uint16_t biosParmBlock::fat32Version
+
+

FAT32 version. High byte is major revision number. Low byte is minor revision number. Only 0.0 define.

+ +
+
+ +
+
+ + + + +
uint8_t biosParmBlock::fatCount
+
+

The count of FAT data structures on the volume. This field should always contain the value 2 for any FAT volume of any type.

+ +
+
+ +
+
+ + + + +
uint16_t biosParmBlock::headCount
+
+

Number of heads for interrupt 0x13. Not used otherwise.

+ +
+
+ +
+
+ + + + +
uint32_t biosParmBlock::hidddenSectors
+
+

Count of hidden sectors preceding the partition that contains this FAT volume. This field is generally only relevant for media visible on interrupt 0x13.

+ +
+
+ +
+
+ + + + +
uint8_t biosParmBlock::mediaType
+
+

This dates back to the old MS-DOS 1.x media determination and is no longer usually used for anything. 0xF8 is the standard value for fixed (nonremovable) media. For removable media, 0xF0 is frequently used. Legal values are 0xF0 or 0xF8-0xFF.

+ +
+
+ +
+
+ + + + +
uint16_t biosParmBlock::reservedSectorCount
+
+

Number of sectors before the first FAT. This value must not be zero.

+ +
+
+ +
+
+ + + + +
uint16_t biosParmBlock::rootDirEntryCount
+
+

For FAT12 and FAT16 volumes, this field contains the count of 32-byte directory entries in the root directory. For FAT32 volumes, this field must be set to 0. For FAT12 and FAT16 volumes, this value should always specify a count that when multiplied by 32 results in a multiple of bytesPerSector. FAT16 volumes should use the value 512.

+ +
+
+ +
+
+ + + + +
uint8_t biosParmBlock::sectorsPerCluster
+
+

Number of sectors per allocation unit. This value must be a power of 2 that is greater than 0. The legal values are 1, 2, 4, 8, 16, 32, 64, and 128.

+ +
+
+ +
+
+ + + + +
uint16_t biosParmBlock::sectorsPerFat16
+
+

Count of sectors occupied by one FAT on FAT12/FAT16 volumes. On FAT32 volumes this field must be 0, and sectorsPerFat32 contains the FAT size count.

+ +
+
+ +
+
+ + + + +
uint32_t biosParmBlock::sectorsPerFat32
+
+

Count of sectors occupied by one FAT on FAT32 volumes.

+ +
+
+ +
+
+ + + + +
uint16_t biosParmBlock::sectorsPerTrtack
+
+

Sectors per track for interrupt 0x13. Not used otherwise.

+ +
+
+ +
+
+ + + + +
uint16_t biosParmBlock::totalSectors16
+
+

This field is the old 16-bit total count of sectors on the volume. This count includes the count of all sectors in all four regions of the volume. This field can be 0; if it is 0, then totalSectors32 must be nonzero. For FAT32 volumes, this field must be 0. For FAT12 and FAT16 volumes, this field contains the sector count, and totalSectors32 is 0 if the total sector count fits (is less than 0x10000).

+ +
+
+ +
+
+ + + + +
uint32_t biosParmBlock::totalSectors32
+
+

This field is the new 32-bit total count of sectors on the volume. This count includes the count of all sectors in all four regions of the volume. This field can be 0; if it is 0, then totalSectors16 must be nonzero.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/structdirectory_entry-members.html b/libraries/SdFat/extras/html/structdirectory_entry-members.html new file mode 100644 index 0000000..9bfada4 --- /dev/null +++ b/libraries/SdFat/extras/html/structdirectory_entry-members.html @@ -0,0 +1,111 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
directoryEntry Member List
+
+ + + + + diff --git a/libraries/SdFat/extras/html/structdirectory_entry.html b/libraries/SdFat/extras/html/structdirectory_entry.html new file mode 100644 index 0000000..70c64b3 --- /dev/null +++ b/libraries/SdFat/extras/html/structdirectory_entry.html @@ -0,0 +1,306 @@ + + + + + + +SdFat: directoryEntry Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
directoryEntry Struct Reference
+
+
+ +

FAT short directory entry. + More...

+ +

#include <FatStructs.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

uint8_t attributes
 
uint16_t creationDate
 
uint16_t creationTime
 
uint8_t creationTimeTenths
 
uint32_t fileSize
 
uint16_t firstClusterHigh
 
uint16_t firstClusterLow
 
uint16_t lastAccessDate
 
uint16_t lastWriteDate
 
uint16_t lastWriteTime
 
uint8_t name [11]
 
uint8_t reservedNT
 
+

Detailed Description

+

FAT short directory entry.

+

Short means short 8.3 name, not the entry size.

+

Date Format. A FAT directory entry date stamp is a 16-bit field that is basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 16-bit word):

+

Bits 9-15: Count of years from 1980, valid value range 0-127 inclusive (1980-2107).

+

Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive.

+

Bits 0-4: Day of month, valid value range 1-31 inclusive.

+

Time Format. A FAT directory entry time stamp is a 16-bit field that has a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 16-bit word).

+

Bits 11-15: Hours, valid value range 0-23 inclusive.

+

Bits 5-10: Minutes, valid value range 0-59 inclusive.

+

Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds).

+

The valid time range is from Midnight 00:00:00 to 23:59:58.

+

Member Data Documentation

+ +
+
+ + + + +
uint8_t directoryEntry::attributes
+
+

Entry attributes.

+

The upper two bits of the attribute byte are reserved and should always be set to 0 when a file is created and never modified or looked at after that. See defines that begin with DIR_ATT_.

+ +
+
+ +
+
+ + + + +
uint16_t directoryEntry::creationDate
+
+

Date file was created.

+ +
+
+ +
+
+ + + + +
uint16_t directoryEntry::creationTime
+
+

Time file was created.

+ +
+
+ +
+
+ + + + +
uint8_t directoryEntry::creationTimeTenths
+
+

The granularity of the seconds part of creationTime is 2 seconds so this field is a count of tenths of a second and its valid value range is 0-199 inclusive. (WHG note - seems to be hundredths)

+ +
+
+ +
+
+ + + + +
uint32_t directoryEntry::fileSize
+
+

32-bit unsigned holding this file's size in bytes.

+ +
+
+ +
+
+ + + + +
uint16_t directoryEntry::firstClusterHigh
+
+

High word of this entry's first cluster number (always 0 for a FAT12 or FAT16 volume).

+ +
+
+ +
+
+ + + + +
uint16_t directoryEntry::firstClusterLow
+
+

Low word of this entry's first cluster number.

+ +
+
+ +
+
+ + + + +
uint16_t directoryEntry::lastAccessDate
+
+

Last access date. Note that there is no last access time, only a date. This is the date of last read or write. In the case of a write, this should be set to the same date as lastWriteDate.

+ +
+
+ +
+
+ + + + +
uint16_t directoryEntry::lastWriteDate
+
+

Date of last write. File creation is considered a write.

+ +
+
+ +
+
+ + + + +
uint16_t directoryEntry::lastWriteTime
+
+

Time of last write. File creation is considered a write.

+ +
+
+ +
+
+ + + + +
uint8_t directoryEntry::name[11]
+
+

Short 8.3 name.

+

The first eight bytes contain the file name with blank fill. The last three bytes contain the file extension with blank fill.

+ +
+
+ +
+
+ + + + +
uint8_t directoryEntry::reservedNT
+
+

Reserved for use by Windows NT. Set value to 0 when a file is created and never modify or look at it after that.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/structfat32__boot-members.html b/libraries/SdFat/extras/html/structfat32__boot-members.html new file mode 100644 index 0000000..e384899 --- /dev/null +++ b/libraries/SdFat/extras/html/structfat32__boot-members.html @@ -0,0 +1,129 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
fat32_boot Member List
+
+ + + + + diff --git a/libraries/SdFat/extras/html/structfat32__boot.html b/libraries/SdFat/extras/html/structfat32__boot.html new file mode 100644 index 0000000..e63e330 --- /dev/null +++ b/libraries/SdFat/extras/html/structfat32__boot.html @@ -0,0 +1,564 @@ + + + + + + +SdFat: fat32_boot Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
fat32_boot Struct Reference
+
+
+ +

Boot sector for a FAT32 volume. + More...

+ +

#include <FatStructs.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

uint8_t bootCode [420]
 
uint8_t bootSectorSig0
 
uint8_t bootSectorSig1
 
uint8_t bootSignature
 
uint16_t bytesPerSector
 
uint8_t driveNumber
 
uint16_t fat32BackBootBlock
 
uint16_t fat32Flags
 
uint16_t fat32FSInfo
 
uint8_t fat32Reserved [12]
 
uint32_t fat32RootCluster
 
uint16_t fat32Version
 
uint8_t fatCount
 
char fileSystemType [8]
 
uint16_t headCount
 
uint32_t hidddenSectors
 
uint8_t jump [3]
 
uint8_t mediaType
 
char oemId [8]
 
uint8_t reserved1
 
uint16_t reservedSectorCount
 
uint16_t rootDirEntryCount
 
uint8_t sectorsPerCluster
 
uint16_t sectorsPerFat16
 
uint32_t sectorsPerFat32
 
uint16_t sectorsPerTrack
 
uint16_t totalSectors16
 
uint32_t totalSectors32
 
char volumeLabel [11]
 
uint32_t volumeSerialNumber
 
+

Detailed Description

+

Boot sector for a FAT32 volume.

+

Member Data Documentation

+ +
+
+ + + + +
uint8_t fat32_boot::bootCode[420]
+
+

X86 boot code

+ +
+
+ +
+
+ + + + +
uint8_t fat32_boot::bootSectorSig0
+
+

must be 0X55

+ +
+
+ +
+
+ + + + +
uint8_t fat32_boot::bootSectorSig1
+
+

must be 0XAA

+ +
+
+ +
+
+ + + + +
uint8_t fat32_boot::bootSignature
+
+

0X29 if next three fields are valid

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::bytesPerSector
+
+

The size of a hardware sector. Valid decimal values for this field are 512, 1024, 2048, and 4096. For most disks used in the United States, the value of this field is 512.

+ +
+
+ +
+
+ + + + +
uint8_t fat32_boot::driveNumber
+
+

Related to the BIOS physical drive number. Floppy drives are identified as 0x00 and physical hard disks are identified as 0x80, regardless of the number of physical disk drives. Typically, this value is set prior to issuing an INT 13h BIOS call to specify the device to access. The value is only relevant if the device is a boot device.

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::fat32BackBootBlock
+
+

If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6. No value other than 6 is recommended.

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::fat32Flags
+
+

This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. Bits 0-3 – Zero-based number of active FAT. Only valid if mirroring is disabled. Bits 4-6 – Reserved. Bit 7 – 0 means the FAT is mirrored at runtime into all FATs. – 1 means only one FAT is active; it is the one referenced in bits 0-3. Bits 8-15 – Reserved.

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::fat32FSInfo
+
+

Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.

+ +
+
+ +
+
+ + + + +
uint8_t fat32_boot::fat32Reserved[12]
+
+

Reserved for future expansion. Code that formats FAT32 volumes should always set all of the bytes of this field to 0.

+ +
+
+ +
+
+ + + + +
uint32_t fat32_boot::fat32RootCluster
+
+

Cluster number of the first cluster of the root directory for FAT32. This usually 2 but not required to be 2.

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::fat32Version
+
+

FAT32 version. High byte is major revision number. Low byte is minor revision number. Only 0.0 define.

+ +
+
+ +
+
+ + + + +
uint8_t fat32_boot::fatCount
+
+

The number of copies of the FAT on the volume. The value of this field is always 2.

+ +
+
+ +
+
+ + + + +
char fat32_boot::fileSystemType[8]
+
+

A text field with a value of FAT32.

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::headCount
+
+

Number of heads for interrupt 0x13. Not used otherwise.

+ +
+
+ +
+
+ + + + +
uint32_t fat32_boot::hidddenSectors
+
+

Count of hidden sectors preceding the partition that contains this FAT volume. This field is generally only relevant for media visible on interrupt 0x13.

+ +
+
+ +
+
+ + + + +
uint8_t fat32_boot::jump[3]
+
+

The first three bytes of the boot sector must be valid, executable x 86-based CPU instructions. This includes a jump instruction that skips the next non-executable bytes.

+ +
+
+ +
+
+ + + + +
uint8_t fat32_boot::mediaType
+
+

This dates back to the old MS-DOS 1.x media determination and is no longer usually used for anything. 0xF8 is the standard value for fixed (non-removable) media. For removable media, 0xF0 is frequently used. Legal values are 0xF0 or 0xF8-0xFF.

+ +
+
+ +
+
+ + + + +
char fat32_boot::oemId[8]
+
+

This is typically a string of characters that identifies the operating system that formatted the volume.

+ +
+
+ +
+
+ + + + +
uint8_t fat32_boot::reserved1
+
+

used by Windows NT - should be zero for FAT

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::reservedSectorCount
+
+

The number of sectors preceding the start of the first FAT, including the boot sector. Must not be zero

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::rootDirEntryCount
+
+

FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0.

+ +
+
+ +
+
+ + + + +
uint8_t fat32_boot::sectorsPerCluster
+
+

Number of sectors per allocation unit. This value must be a power of 2 that is greater than 0. The legal values are 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided.

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::sectorsPerFat16
+
+

On FAT32 volumes this field must be 0, and sectorsPerFat32 contains the FAT size count.

+ +
+
+ +
+
+ + + + +
uint32_t fat32_boot::sectorsPerFat32
+
+

Count of sectors occupied by one FAT on FAT32 volumes.

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::sectorsPerTrack
+
+

Sectors per track for interrupt 0x13. Not used otherwise.

+ +
+
+ +
+
+ + + + +
uint16_t fat32_boot::totalSectors16
+
+

For FAT32 volumes, this field must be 0.

+ +
+
+ +
+
+ + + + +
uint32_t fat32_boot::totalSectors32
+
+

Contains the total number of sectors in the FAT32 volume.

+ +
+
+ +
+
+ + + + +
char fat32_boot::volumeLabel[11]
+
+

A field once used to store the volume label. The volume label is now stored as a special file in the root directory.

+ +
+
+ +
+
+ + + + +
uint32_t fat32_boot::volumeSerialNumber
+
+

A random serial number created when formatting a disk, which helps to distinguish between disks. Usually generated by combining date and time.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/structfat32__fsinfo-members.html b/libraries/SdFat/extras/html/structfat32__fsinfo-members.html new file mode 100644 index 0000000..44fe1c6 --- /dev/null +++ b/libraries/SdFat/extras/html/structfat32__fsinfo-members.html @@ -0,0 +1,106 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
fat32_fsinfo Member List
+
+ + + + + diff --git a/libraries/SdFat/extras/html/structfat32__fsinfo.html b/libraries/SdFat/extras/html/structfat32__fsinfo.html new file mode 100644 index 0000000..3ca8487 --- /dev/null +++ b/libraries/SdFat/extras/html/structfat32__fsinfo.html @@ -0,0 +1,219 @@ + + + + + + +SdFat: fat32_fsinfo Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
fat32_fsinfo Struct Reference
+
+
+ +

FSINFO sector for a FAT32 volume. + More...

+ +

#include <FatStructs.h>

+ + + + + + + + + + + + + + + + +

+Public Attributes

uint32_t freeCount
 
uint32_t leadSignature
 
uint32_t nextFree
 
uint8_t reserved1 [480]
 
uint8_t reserved2 [12]
 
uint32_t structSignature
 
uint8_t tailSignature [4]
 
+

Detailed Description

+

FSINFO sector for a FAT32 volume.

+

Member Data Documentation

+ +
+
+ + + + +
uint32_t fat32_fsinfo::freeCount
+
+

Contains the last known free cluster count on the volume. If the value is 0xFFFFFFFF, then the free count is unknown and must be computed. Any other value can be used, but is not necessarily correct. It should be range checked at least to make sure it is <= volume cluster count.

+ +
+
+ +
+
+ + + + +
uint32_t fat32_fsinfo::leadSignature
+
+

must be 0X52, 0X52, 0X61, 0X41

+ +
+
+ +
+
+ + + + +
uint32_t fat32_fsinfo::nextFree
+
+

This is a hint for the FAT driver. It indicates the cluster number at which the driver should start looking for free clusters. If the value is 0xFFFFFFFF, then there is no hint and the driver should start looking at cluster 2.

+ +
+
+ +
+
+ + + + +
uint8_t fat32_fsinfo::reserved1[480]
+
+

must be zero

+ +
+
+ +
+
+ + + + +
uint8_t fat32_fsinfo::reserved2[12]
+
+

must be zero

+ +
+
+ +
+
+ + + + +
uint32_t fat32_fsinfo::structSignature
+
+

must be 0X72, 0X72, 0X41, 0X61

+ +
+
+ +
+
+ + + + +
uint8_t fat32_fsinfo::tailSignature[4]
+
+

must be 0X00, 0X00, 0X55, 0XAA

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/structfat__boot-members.html b/libraries/SdFat/extras/html/structfat__boot-members.html new file mode 100644 index 0000000..edd34f8 --- /dev/null +++ b/libraries/SdFat/extras/html/structfat__boot-members.html @@ -0,0 +1,122 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
fat_boot Member List
+
+ + + + + diff --git a/libraries/SdFat/extras/html/structfat__boot.html b/libraries/SdFat/extras/html/structfat__boot.html new file mode 100644 index 0000000..b7435ea --- /dev/null +++ b/libraries/SdFat/extras/html/structfat__boot.html @@ -0,0 +1,459 @@ + + + + + + +SdFat: fat_boot Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
fat_boot Struct Reference
+
+
+ +

Boot sector for a FAT12/FAT16 volume. + More...

+ +

#include <FatStructs.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

uint8_t bootCode [448]
 
uint8_t bootSectorSig0
 
uint8_t bootSectorSig1
 
uint8_t bootSignature
 
uint16_t bytesPerSector
 
uint8_t driveNumber
 
uint8_t fatCount
 
char fileSystemType [8]
 
uint16_t headCount
 
uint32_t hidddenSectors
 
uint8_t jump [3]
 
uint8_t mediaType
 
char oemId [8]
 
uint8_t reserved1
 
uint16_t reservedSectorCount
 
uint16_t rootDirEntryCount
 
uint8_t sectorsPerCluster
 
uint16_t sectorsPerFat16
 
uint16_t sectorsPerTrack
 
uint16_t totalSectors16
 
uint32_t totalSectors32
 
char volumeLabel [11]
 
uint32_t volumeSerialNumber
 
+

Detailed Description

+

Boot sector for a FAT12/FAT16 volume.

+

Member Data Documentation

+ +
+
+ + + + +
uint8_t fat_boot::bootCode[448]
+
+

X86 boot code

+ +
+
+ +
+
+ + + + +
uint8_t fat_boot::bootSectorSig0
+
+

must be 0X55

+ +
+
+ +
+
+ + + + +
uint8_t fat_boot::bootSectorSig1
+
+

must be 0XAA

+ +
+
+ +
+
+ + + + +
uint8_t fat_boot::bootSignature
+
+

0X29 if next three fields are valid

+ +
+
+ +
+
+ + + + +
uint16_t fat_boot::bytesPerSector
+
+

The size of a hardware sector. Valid decimal values for this field are 512, 1024, 2048, and 4096. For most disks used in the United States, the value of this field is 512.

+ +
+
+ +
+
+ + + + +
uint8_t fat_boot::driveNumber
+
+

Related to the BIOS physical drive number. Floppy drives are identified as 0x00 and physical hard disks are identified as 0x80, regardless of the number of physical disk drives. Typically, this value is set prior to issuing an INT 13h BIOS call to specify the device to access. The value is only relevant if the device is a boot device.

+ +
+
+ +
+
+ + + + +
uint8_t fat_boot::fatCount
+
+

The number of copies of the FAT on the volume. The value of this field is always 2.

+ +
+
+ +
+
+ + + + +
char fat_boot::fileSystemType[8]
+
+

A field with a value of either FAT, FAT12 or FAT16, depending on the disk format.

+ +
+
+ +
+
+ + + + +
uint16_t fat_boot::headCount
+
+

Number of heads for interrupt 0x13. Not used otherwise.

+ +
+
+ +
+
+ + + + +
uint32_t fat_boot::hidddenSectors
+
+

Count of hidden sectors preceding the partition that contains this FAT volume. This field is generally only relevant for media visible on interrupt 0x13.

+ +
+
+ +
+
+ + + + +
uint8_t fat_boot::jump[3]
+
+

The first three bytes of the boot sector must be valid, executable x 86-based CPU instructions. This includes a jump instruction that skips the next non-executable bytes.

+ +
+
+ +
+
+ + + + +
uint8_t fat_boot::mediaType
+
+

This dates back to the old MS-DOS 1.x media determination and is no longer usually used for anything. 0xF8 is the standard value for fixed (non-removable) media. For removable media, 0xF0 is frequently used. Legal values are 0xF0 or 0xF8-0xFF.

+ +
+
+ +
+
+ + + + +
char fat_boot::oemId[8]
+
+

This is typically a string of characters that identifies the operating system that formatted the volume.

+ +
+
+ +
+
+ + + + +
uint8_t fat_boot::reserved1
+
+

used by Windows NT - should be zero for FAT

+ +
+
+ +
+
+ + + + +
uint16_t fat_boot::reservedSectorCount
+
+

The number of sectors preceding the start of the first FAT, including the boot sector. The value of this field is always 1.

+ +
+
+ +
+
+ + + + +
uint16_t fat_boot::rootDirEntryCount
+
+

For FAT12 and FAT16 volumes, this field contains the count of 32-byte directory entries in the root directory. For FAT32 volumes, this field must be set to 0. For FAT12 and FAT16 volumes, this value should always specify a count that when multiplied by 32 results in a multiple of bytesPerSector. FAT16 volumes should use the value 512.

+ +
+
+ +
+
+ + + + +
uint8_t fat_boot::sectorsPerCluster
+
+

Number of sectors per allocation unit. This value must be a power of 2 that is greater than 0. The legal values are 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided.

+ +
+
+ +
+
+ + + + +
uint16_t fat_boot::sectorsPerFat16
+
+

Count of sectors occupied by one FAT on FAT12/FAT16 volumes. On FAT32 volumes this field must be 0, and sectorsPerFat32 contains the FAT size count.

+ +
+
+ +
+
+ + + + +
uint16_t fat_boot::sectorsPerTrack
+
+

Sectors per track for interrupt 0x13. Not used otherwise.

+ +
+
+ +
+
+ + + + +
uint16_t fat_boot::totalSectors16
+
+

This field is the old 16-bit total count of sectors on the volume. This count includes the count of all sectors in all four regions of the volume. This field can be 0; if it is 0, then totalSectors32 must be non-zero. For FAT32 volumes, this field must be 0. For FAT12 and FAT16 volumes, this field contains the sector count, and totalSectors32 is 0 if the total sector count fits (is less than 0x10000).

+ +
+
+ +
+
+ + + + +
uint32_t fat_boot::totalSectors32
+
+

This field is the new 32-bit total count of sectors on the volume. This count includes the count of all sectors in all four regions of the volume. This field can be 0; if it is 0, then totalSectors16 must be non-zero.

+ +
+
+ +
+
+ + + + +
char fat_boot::volumeLabel[11]
+
+

A field once used to store the volume label. The volume label is now stored as a special file in the root directory.

+ +
+
+ +
+
+ + + + +
uint32_t fat_boot::volumeSerialNumber
+
+

A random serial number created when formatting a disk, which helps to distinguish between disks. Usually generated by combining date and time.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/structfname__t-members.html b/libraries/SdFat/extras/html/structfname__t-members.html new file mode 100644 index 0000000..f4faa77 --- /dev/null +++ b/libraries/SdFat/extras/html/structfname__t-members.html @@ -0,0 +1,104 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
fname_t Member List
+
+
+ +

This is the complete list of members for fname_t, including all inherited members.

+ + + + + + +
flagsfname_t
lenfname_t
lfnfname_t
seqPosfname_t
sfnfname_t
+ + + + diff --git a/libraries/SdFat/extras/html/structfname__t.html b/libraries/SdFat/extras/html/structfname__t.html new file mode 100644 index 0000000..dc8cd6e --- /dev/null +++ b/libraries/SdFat/extras/html/structfname__t.html @@ -0,0 +1,189 @@ + + + + + + +SdFat: fname_t Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
fname_t Struct Reference
+
+
+ +

Internal type for Short File Name - do not use in user apps. + More...

+ +

#include <FatFile.h>

+ + + + + + + + + + + + +

+Public Attributes

uint8_t flags
 
size_t len
 
const char * lfn
 
uint8_t seqPos
 
uint8_t sfn [11]
 
+

Detailed Description

+

Internal type for Short File Name - do not use in user apps.

+

Member Data Documentation

+ +
+
+ + + + +
uint8_t fname_t::flags
+
+

Flags for base and extension character case and LFN.

+ +
+
+ +
+
+ + + + +
size_t fname_t::len
+
+

length of Long File Name

+ +
+
+ +
+
+ + + + +
const char* fname_t::lfn
+
+

Long File Name start.

+ +
+
+ +
+
+ + + + +
uint8_t fname_t::seqPos
+
+

position for sequence number

+ +
+
+ +
+
+ + + + +
uint8_t fname_t::sfn[11]
+
+

Short File Name

+ +
+
+
The documentation for this struct was generated from the following file:
    +
  • Arduino/libraries/SdFat/src/FatLib/FatFile.h
  • +
+
+ + + + diff --git a/libraries/SdFat/extras/html/structlong_directory_entry-members.html b/libraries/SdFat/extras/html/structlong_directory_entry-members.html new file mode 100644 index 0000000..5a3ba56 --- /dev/null +++ b/libraries/SdFat/extras/html/structlong_directory_entry-members.html @@ -0,0 +1,107 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
longDirectoryEntry Member List
+
+ + + + + diff --git a/libraries/SdFat/extras/html/structlong_directory_entry.html b/libraries/SdFat/extras/html/structlong_directory_entry.html new file mode 100644 index 0000000..912e497 --- /dev/null +++ b/libraries/SdFat/extras/html/structlong_directory_entry.html @@ -0,0 +1,236 @@ + + + + + + +SdFat: longDirectoryEntry Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
longDirectoryEntry Struct Reference
+
+
+ +

FAT long directory entry. + More...

+ +

#include <FatStructs.h>

+ + + + + + + + + + + + + + + + + + +

+Public Attributes

uint8_t attr
 
uint8_t chksum
 
uint16_t mustBeZero
 
uint16_t name1 [LDIR_NAME1_DIM]
 
uint16_t name2 [LDIR_NAME2_DIM]
 
uint16_t name3 [LDIR_NAME3_DIM]
 
uint8_t ord
 
uint8_t type
 
+

Detailed Description

+

FAT long directory entry.

+

Member Data Documentation

+ +
+
+ + + + +
uint8_t longDirectoryEntry::attr
+
+

Attributes - must be ATTR_LONG_NAME

+ +
+
+ +
+
+ + + + +
uint8_t longDirectoryEntry::chksum
+
+

Checksum of name in the short dir entry at the end of the long dir set.

+ +
+
+ +
+
+ + + + +
uint16_t longDirectoryEntry::mustBeZero
+
+

Must be ZERO. This is an artifact of the FAT "first cluster"

+ +
+
+ +
+
+ + + + +
uint16_t longDirectoryEntry::name1[LDIR_NAME1_DIM]
+
+

Characters 1-5 of the long-name sub-component in this entry.

+ +
+
+ +
+
+ + + + +
uint16_t longDirectoryEntry::name2[LDIR_NAME2_DIM]
+
+

Characters 6-11 of the long-name sub-component in this entry.

+ +
+
+ +
+
+ + + + +
uint16_t longDirectoryEntry::name3[LDIR_NAME3_DIM]
+
+

Characters 12 and 13 of the long-name sub-component in this entry.

+ +
+
+ +
+
+ + + + +
uint8_t longDirectoryEntry::ord
+
+

The order of this entry in the sequence of long dir entries associated with the short dir entry at the end of the long dir set.

+

If masked with 0X40 (LAST_LONG_ENTRY), this indicates the entry is the last long dir entry in a set of long dir entries. All valid sets of long dir entries must begin with an entry having this mask.

+ +
+
+ +
+
+ + + + +
uint8_t longDirectoryEntry::type
+
+

If zero, indicates a directory entry that is a sub-component of a long name. NOTE: Other values reserved for future extensions.

+

Non-zero implies other directory entry types.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/structmaster_boot_record-members.html b/libraries/SdFat/extras/html/structmaster_boot_record-members.html new file mode 100644 index 0000000..d2d01b7 --- /dev/null +++ b/libraries/SdFat/extras/html/structmaster_boot_record-members.html @@ -0,0 +1,105 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
masterBootRecord Member List
+
+ + + + + diff --git a/libraries/SdFat/extras/html/structmaster_boot_record.html b/libraries/SdFat/extras/html/structmaster_boot_record.html new file mode 100644 index 0000000..959dfa5 --- /dev/null +++ b/libraries/SdFat/extras/html/structmaster_boot_record.html @@ -0,0 +1,213 @@ + + + + + + +SdFat: masterBootRecord Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
masterBootRecord Struct Reference
+
+
+ +

Master Boot Record. + More...

+ +

#include <FatStructs.h>

+
+Collaboration diagram for masterBootRecord:
+
+
Collaboration graph
+ + + +
[legend]
+ + + + + + + + + + + + + + +

+Public Attributes

uint8_t codeArea [440]
 
uint32_t diskSignature
 
uint8_t mbrSig0
 
uint8_t mbrSig1
 
part_t part [4]
 
uint16_t usuallyZero
 
+

Detailed Description

+

Master Boot Record.

+

The first block of a storage device that is formatted with a MBR.

+

Member Data Documentation

+ +
+
+ + + + +
uint8_t masterBootRecord::codeArea[440]
+
+

Code Area for master boot program.

+ +
+
+ +
+
+ + + + +
uint32_t masterBootRecord::diskSignature
+
+

Optional Windows NT disk signature. May contain boot code.

+ +
+
+ +
+
+ + + + +
uint8_t masterBootRecord::mbrSig0
+
+

First MBR signature byte. Must be 0X55

+ +
+
+ +
+
+ + + + +
uint8_t masterBootRecord::mbrSig1
+
+

Second MBR signature byte. Must be 0XAA

+ +
+
+ +
+
+ + + + +
part_t masterBootRecord::part[4]
+
+

Partition tables.

+ +
+
+ +
+
+ + + + +
uint16_t masterBootRecord::usuallyZero
+
+

Usually zero but may be more boot code.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/structmaster_boot_record__coll__graph.png b/libraries/SdFat/extras/html/structmaster_boot_record__coll__graph.png new file mode 100644 index 0000000..790e25c Binary files /dev/null and b/libraries/SdFat/extras/html/structmaster_boot_record__coll__graph.png differ diff --git a/libraries/SdFat/extras/html/structpartition_table-members.html b/libraries/SdFat/extras/html/structpartition_table-members.html new file mode 100644 index 0000000..98227a5 --- /dev/null +++ b/libraries/SdFat/extras/html/structpartition_table-members.html @@ -0,0 +1,111 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
partitionTable Member List
+
+ + + + + diff --git a/libraries/SdFat/extras/html/structpartition_table.html b/libraries/SdFat/extras/html/structpartition_table.html new file mode 100644 index 0000000..f058b19 --- /dev/null +++ b/libraries/SdFat/extras/html/structpartition_table.html @@ -0,0 +1,295 @@ + + + + + + +SdFat: partitionTable Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
partitionTable Struct Reference
+
+
+ +

MBR partition table entry. + More...

+ +

#include <FatStructs.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

unsigned beginCylinderHigh: 2
 
uint8_t beginCylinderLow
 
uint8_t beginHead
 
unsigned beginSector: 6
 
uint8_t boot
 
unsigned endCylinderHigh: 2
 
uint8_t endCylinderLow
 
uint8_t endHead
 
unsigned endSector: 6
 
uint32_t firstSector
 
uint32_t totalSectors
 
uint8_t type
 
+

Detailed Description

+

MBR partition table entry.

+

A partition table entry for a MBR formatted storage device. The MBR partition table has four entries.

+

Member Data Documentation

+ +
+
+ + + + +
unsigned partitionTable::beginCylinderHigh
+
+

High bits cylinder for first block in partition.

+ +
+
+ +
+
+ + + + +
uint8_t partitionTable::beginCylinderLow
+
+

Combine beginCylinderLow with beginCylinderHigh. Legal values are 0-1023. Only used in old PC BIOS.

+ +
+
+ +
+
+ + + + +
uint8_t partitionTable::beginHead
+
+

Head part of Cylinder-head-sector address of the first block in the partition. Legal values are 0-255. Only used in old PC BIOS.

+ +
+
+ +
+
+ + + + +
unsigned partitionTable::beginSector
+
+

Sector part of Cylinder-head-sector address of the first block in the partition. Legal values are 1-63. Only used in old PC BIOS.

+ +
+
+ +
+
+ + + + +
uint8_t partitionTable::boot
+
+

Boot Indicator . Indicates whether the volume is the active partition. Legal values include: 0X00. Do not use for booting. 0X80 Active partition.

+ +
+
+ +
+
+ + + + +
unsigned partitionTable::endCylinderHigh
+
+

High bits of end cylinder

+ +
+
+ +
+
+ + + + +
uint8_t partitionTable::endCylinderLow
+
+

Combine endCylinderLow with endCylinderHigh. Legal values are 0-1023. Only used in old PC BIOS.

+ +
+
+ +
+
+ + + + +
uint8_t partitionTable::endHead
+
+

head part of cylinder-head-sector address of the last sector in the partition. Legal values are 0-255. Only used in old PC BIOS.

+ +
+
+ +
+
+ + + + +
unsigned partitionTable::endSector
+
+

Sector part of cylinder-head-sector address of the last sector in the partition. Legal values are 1-63. Only used in old PC BIOS.

+ +
+
+ +
+
+ + + + +
uint32_t partitionTable::firstSector
+
+

Logical block address of the first block in the partition.

+ +
+
+ +
+
+ + + + +
uint32_t partitionTable::totalSectors
+
+

Length of the partition, in blocks.

+ +
+
+ +
+
+ + + + +
uint8_t partitionTable::type
+
+

Partition type. See defines that begin with PART_TYPE_ for some Microsoft partition types.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/structsetfill-members.html b/libraries/SdFat/extras/html/structsetfill-members.html new file mode 100644 index 0000000..741a2fc --- /dev/null +++ b/libraries/SdFat/extras/html/structsetfill-members.html @@ -0,0 +1,101 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
setfill Member List
+
+
+ +

This is the complete list of members for setfill, including all inherited members.

+ + + +
csetfill
setfill(char arg)setfillinlineexplicit
+ + + + diff --git a/libraries/SdFat/extras/html/structsetfill.html b/libraries/SdFat/extras/html/structsetfill.html new file mode 100644 index 0000000..6e66ad3 --- /dev/null +++ b/libraries/SdFat/extras/html/structsetfill.html @@ -0,0 +1,167 @@ + + + + + + +SdFat: setfill Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
setfill Struct Reference
+
+
+ +

type for setfill manipulator + More...

+ +

#include <iostream.h>

+ + + + +

+Public Member Functions

 setfill (char arg)
 
+ + + +

+Public Attributes

char c
 
+

Detailed Description

+

type for setfill manipulator

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
setfill::setfill (char arg)
+
+inlineexplicit
+
+

constructor

+
Parameters
+ + +
[in]argnew fill character
+
+
+ +
+
+

Member Data Documentation

+ +
+
+ + + + +
char setfill::c
+
+

fill character

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/structsetprecision-members.html b/libraries/SdFat/extras/html/structsetprecision-members.html new file mode 100644 index 0000000..5c61b75 --- /dev/null +++ b/libraries/SdFat/extras/html/structsetprecision-members.html @@ -0,0 +1,101 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
setprecision Member List
+
+
+ +

This is the complete list of members for setprecision, including all inherited members.

+ + + +
psetprecision
setprecision(unsigned int arg)setprecisioninlineexplicit
+ + + + diff --git a/libraries/SdFat/extras/html/structsetprecision.html b/libraries/SdFat/extras/html/structsetprecision.html new file mode 100644 index 0000000..4f8a983 --- /dev/null +++ b/libraries/SdFat/extras/html/structsetprecision.html @@ -0,0 +1,166 @@ + + + + + + +SdFat: setprecision Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
setprecision Struct Reference
+
+
+ +

type for setprecision manipulator + More...

+ +

#include <iostream.h>

+ + + + +

+Public Member Functions

 setprecision (unsigned int arg)
 
+ + + +

+Public Attributes

unsigned int p
 
+

Detailed Description

+

type for setprecision manipulator

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
setprecision::setprecision (unsigned int arg)
+
+inlineexplicit
+
+

constructor

Parameters
+ + +
[in]argnew precision
+
+
+ +
+
+

Member Data Documentation

+ +
+
+ + + + +
unsigned int setprecision::p
+
+

precision

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/structsetw-members.html b/libraries/SdFat/extras/html/structsetw-members.html new file mode 100644 index 0000000..a9a782d --- /dev/null +++ b/libraries/SdFat/extras/html/structsetw-members.html @@ -0,0 +1,101 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
setw Member List
+
+
+ +

This is the complete list of members for setw, including all inherited members.

+ + + +
setw(unsigned arg)setwinlineexplicit
wsetw
+ + + + diff --git a/libraries/SdFat/extras/html/structsetw.html b/libraries/SdFat/extras/html/structsetw.html new file mode 100644 index 0000000..2863e93 --- /dev/null +++ b/libraries/SdFat/extras/html/structsetw.html @@ -0,0 +1,166 @@ + + + + + + +SdFat: setw Struct Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

type for setw manipulator + More...

+ +

#include <iostream.h>

+ + + + +

+Public Member Functions

 setw (unsigned arg)
 
+ + + +

+Public Attributes

unsigned w
 
+

Detailed Description

+

type for setw manipulator

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
setw::setw (unsigned arg)
+
+inlineexplicit
+
+

constructor

Parameters
+ + +
[in]argnew width
+
+
+ +
+
+

Member Data Documentation

+ +
+
+ + + + +
unsigned setw::w
+
+

width

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/sync_off.png b/libraries/SdFat/extras/html/sync_off.png new file mode 100644 index 0000000..3b443fc Binary files /dev/null and b/libraries/SdFat/extras/html/sync_off.png differ diff --git a/libraries/SdFat/extras/html/sync_on.png b/libraries/SdFat/extras/html/sync_on.png new file mode 100644 index 0000000..e08320f Binary files /dev/null and b/libraries/SdFat/extras/html/sync_on.png differ diff --git a/libraries/SdFat/extras/html/tab_a.png b/libraries/SdFat/extras/html/tab_a.png new file mode 100644 index 0000000..3b725c4 Binary files /dev/null and b/libraries/SdFat/extras/html/tab_a.png differ diff --git a/libraries/SdFat/extras/html/tab_b.png b/libraries/SdFat/extras/html/tab_b.png new file mode 100644 index 0000000..e2b4a86 Binary files /dev/null and b/libraries/SdFat/extras/html/tab_b.png differ diff --git a/libraries/SdFat/extras/html/tab_h.png b/libraries/SdFat/extras/html/tab_h.png new file mode 100644 index 0000000..fd5cb70 Binary files /dev/null and b/libraries/SdFat/extras/html/tab_h.png differ diff --git a/libraries/SdFat/extras/html/tab_s.png b/libraries/SdFat/extras/html/tab_s.png new file mode 100644 index 0000000..ab478c9 Binary files /dev/null and b/libraries/SdFat/extras/html/tab_s.png differ diff --git a/libraries/SdFat/extras/html/tabs.css b/libraries/SdFat/extras/html/tabs.css new file mode 100644 index 0000000..9cf578f --- /dev/null +++ b/libraries/SdFat/extras/html/tabs.css @@ -0,0 +1,60 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/libraries/SdFat/extras/html/unioncache__t-members.html b/libraries/SdFat/extras/html/unioncache__t-members.html new file mode 100644 index 0000000..7348ecf --- /dev/null +++ b/libraries/SdFat/extras/html/unioncache__t-members.html @@ -0,0 +1,107 @@ + + + + + + +SdFat: Member List + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+
+
cache_t Member List
+
+
+ +

This is the complete list of members for cache_t, including all inherited members.

+ + + + + + + + + +
datacache_t
dircache_t
fat16cache_t
fat32cache_t
fbscache_t
fbs32cache_t
fsinfocache_t
mbrcache_t
+ + + + diff --git a/libraries/SdFat/extras/html/unioncache__t.html b/libraries/SdFat/extras/html/unioncache__t.html new file mode 100644 index 0000000..124b011 --- /dev/null +++ b/libraries/SdFat/extras/html/unioncache__t.html @@ -0,0 +1,247 @@ + + + + + + +SdFat: cache_t Union Reference + + + + + + + + + + +
+
+ + + + + + +
+
SdFat +
+
+
+ + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
cache_t Union Reference
+
+
+ +

Cache for an raw data block. + More...

+ +

#include <FatVolume.h>

+
+Collaboration diagram for cache_t:
+
+
Collaboration graph
+ + + + + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + +

+Public Attributes

uint8_t data [512]
 
dir_t dir [16]
 
uint16_t fat16 [256]
 
uint32_t fat32 [128]
 
fat_boot_t fbs
 
fat32_boot_t fbs32
 
fat32_fsinfo_t fsinfo
 
mbr_t mbr
 
+

Detailed Description

+

Cache for an raw data block.

+

Member Data Documentation

+ +
+
+ + + + +
uint8_t cache_t::data[512]
+
+

Used to access cached file data blocks.

+ +
+
+ +
+
+ + + + +
dir_t cache_t::dir[16]
+
+

Used to access cached directory entries.

+ +
+
+ +
+
+ + + + +
uint16_t cache_t::fat16[256]
+
+

Used to access cached FAT16 entries.

+ +
+
+ +
+
+ + + + +
uint32_t cache_t::fat32[128]
+
+

Used to access cached FAT32 entries.

+ +
+
+ +
+
+ + + + +
fat_boot_t cache_t::fbs
+
+

Used to access to a cached FAT boot sector.

+ +
+
+ +
+
+ + + + +
fat32_boot_t cache_t::fbs32
+
+

Used to access to a cached FAT32 boot sector.

+ +
+
+ +
+
+ + + + +
fat32_fsinfo_t cache_t::fsinfo
+
+

Used to access to a cached FAT32 FSINFO sector.

+ +
+
+ +
+
+ + + + +
mbr_t cache_t::mbr
+
+

Used to access a cached Master Boot Record.

+ +
+
+
The documentation for this union was generated from the following file: +
+ + + + diff --git a/libraries/SdFat/extras/html/unioncache__t__coll__graph.png b/libraries/SdFat/extras/html/unioncache__t__coll__graph.png new file mode 100644 index 0000000..16bea1b Binary files /dev/null and b/libraries/SdFat/extras/html/unioncache__t__coll__graph.png differ diff --git a/libraries/SdFat/library.properties b/libraries/SdFat/library.properties new file mode 100644 index 0000000..fb482ae --- /dev/null +++ b/libraries/SdFat/library.properties @@ -0,0 +1,9 @@ +name=SdFat +version=1.0.3 +author=Bill Greiman +maintainer=Bill Greiman +sentence=FAT16/FAT32 file system for SD cards. +paragraph=FAT16/FAT32 file system for SD cards. +category=Data Storage +url=https://github.com/greiman/SdFat +architectures=* diff --git a/libraries/SdFat/src/BlockDriver.h b/libraries/SdFat/src/BlockDriver.h new file mode 100644 index 0000000..9c45351 --- /dev/null +++ b/libraries/SdFat/src/BlockDriver.h @@ -0,0 +1,35 @@ +/* Arduino SdFat Library + * Copyright (C) 2016 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 + * . + */ + /** + * \file + * \brief Define block driver. + */ +#ifndef BlockDriver_h +#define BlockDriver_h +#include "FatLib/BaseBlockDriver.h" +#include "SdCard/SdSpiCard.h" +//----------------------------------------------------------------------------- +/** typedef for BlockDriver */ +#if ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS +typedef BaseBlockDriver BlockDriver; +#else // ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS +typedef SdSpiCard BlockDriver; +#endif // ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS +#endif // BlockDriver_h diff --git a/libraries/SdFat/src/FatLib/ArduinoFiles.h b/libraries/SdFat/src/FatLib/ArduinoFiles.h new file mode 100644 index 0000000..45038c3 --- /dev/null +++ b/libraries/SdFat/src/FatLib/ArduinoFiles.h @@ -0,0 +1,244 @@ +/* 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 + * . + */ +/** + * \file + * \brief PrintFile class + */ +#ifndef ArduinoFiles_h +#define ArduinoFiles_h +#include "FatLibConfig.h" +#if ENABLE_ARDUINO_FEATURES +#include "FatFile.h" +#include +//------------------------------------------------------------------------------ +/** Arduino SD.h style flag for open for read. */ +#define FILE_READ O_READ +/** Arduino SD.h style flag for open at EOF for read/write with create. */ +#define FILE_WRITE (O_RDWR | O_CREAT | O_AT_END) +//============================================================================== +/** + * \class PrintFile + * \brief FatFile with Print. + */ +class PrintFile : public FatFile, public Print { + public: + PrintFile() {} + /** Create a file object and open it in the current working directory. + * + * \param[in] path A path for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a + * bitwise-inclusive OR of open flags. see + * FatFile::open(FatFile*, const char*, uint8_t). + */ + PrintFile(const char* path, uint8_t oflag) : FatFile(path, oflag) {} +#if DESTRUCTOR_CLOSES_FILE + ~PrintFile() {} +#endif // DESTRUCTOR_CLOSES_FILE + using FatFile::clearWriteError; + using FatFile::getWriteError; + using FatFile::read; + using FatFile::write; + /** \return number of bytes available from the current position to EOF + * or INT_MAX if more than INT_MAX bytes are available. + */ + int available() { + uint32_t n = FatFile::available(); + return n > INT_MAX ? INT_MAX : n; + } + /** Ensure that any bytes written to the file are saved to the SD card. */ + void flush() { + FatFile::sync(); + } + /** Return the next available byte without consuming it. + * + * \return The byte if no error and not at eof else -1; + */ + int peek() { + return FatFile::peek(); + } + /** Read the next byte from a file. + * + * \return For success return the next byte in the file as an int. + * If an error occurs or end of file is reached return -1. + */ +// int read() { +// return FatFile::read(); +// } + /** Write a byte to a file. Required by the Arduino Print class. + * \param[in] b the byte to be written. + * Use getWriteError to check for errors. + * \return 1 for success and 0 for failure. + */ + size_t write(uint8_t b) { + return FatFile::write(b); + } + /** Write data to an open file. Form required by Print. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] size Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \a nbyte. If an error occurs, write() returns -1. Possible errors + * include write() is called before a file has been opened, write is called + * for a read-only file, device is full, a corrupt file system or an + * I/O error. + */ + size_t write(const uint8_t *buf, size_t size) { + return FatFile::write(buf, size); + } +}; +//============================================================================== +/** + * \class File + * \brief Arduino SD.h style File API + */ +class File : public FatFile, public Stream { + public: + File() {} + /** Create a file object and open it in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a + * bitwise-inclusive OR of open flags. see + * FatFile::open(FatFile*, const char*, uint8_t). + */ + File(const char* path, uint8_t oflag) { + open(path, oflag); + } + using FatFile::clearWriteError; + using FatFile::getWriteError; + using FatFile::read; + using FatFile::write; + /** The parenthesis operator. + * + * \return true if a file is open. + */ + operator bool() { + return isOpen(); + } + /** \return number of bytes available from the current position to EOF + * or INT_MAX if more than INT_MAX bytes are available. + */ + int available() { + uint32_t n = FatFile::available(); + return n > INT_MAX ? INT_MAX : n; + } + /** Ensure that any bytes written to the file are saved to the SD card. */ + void flush() { + FatFile::sync(); + } + /** This function reports if the current file is a directory or not. + * \return true if the file is a directory. + */ + bool isDirectory() { + return isDir(); + } + /** No longer implemented due to Long File Names. + * + * Use getName(char* name, size_t size). + * \return a pointer to replacement suggestion. + */ + const char* name() const { + return "use getName()"; + } + /** Return the next available byte without consuming it. + * + * \return The byte if no error and not at eof else -1; + */ + int peek() { + return FatFile::peek(); + } + /** \return the current file position. */ + uint32_t position() { + return curPosition(); + } + /** Opens the next file or folder in a directory. + * + * \param[in] mode open mode flags. + * \return a File object. + */ + File openNextFile(uint8_t mode = O_READ) { + File tmpFile; + tmpFile.openNext(this, mode); + return tmpFile; + } + /** Read the next byte from a file. + * + * \return For success return the next byte in the file as an int. + * If an error occurs or end of file is reached return -1. + */ + int read() { + return FatFile::read(); + } + /** Rewind a file if it is a directory */ + void rewindDirectory() { + if (isDir()) { + rewind(); + } + } + /** + * Seek to a new position in the file, which must be between + * 0 and the size of the file (inclusive). + * + * \param[in] pos the new file position. + * \return true for success else false. + */ + bool seek(uint32_t pos) { + return seekSet(pos); + } + /** \return the file's size. */ + uint32_t size() { + return fileSize(); + } + /** Write a byte to a file. Required by the Arduino Print class. + * \param[in] b the byte to be written. + * Use getWriteError to check for errors. + * \return 1 for success and 0 for failure. + */ + size_t write(uint8_t b) { + return FatFile::write(b); + } + /** Write data to an open file. Form required by Print. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] size Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \a nbyte. If an error occurs, write() returns -1. Possible errors + * include write() is called before a file has been opened, write is called + * for a read-only file, device is full, a corrupt file system or an + * I/O error. + */ + size_t write(const uint8_t *buf, size_t size) { + return FatFile::write(buf, size); + } +}; +#endif // ENABLE_ARDUINO_FEATURES +#endif // ArduinoFiles_h diff --git a/libraries/SdFat/src/FatLib/ArduinoStream.h b/libraries/SdFat/src/FatLib/ArduinoStream.h new file mode 100644 index 0000000..e9c01b7 --- /dev/null +++ b/libraries/SdFat/src/FatLib/ArduinoStream.h @@ -0,0 +1,148 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef ArduinoStream_h +#define ArduinoStream_h +/** + * \file + * \brief ArduinoInStream and ArduinoOutStream classes + */ +#include "FatLibConfig.h" +#if ENABLE_ARDUINO_FEATURES +#include "bufstream.h" +//============================================================================== +/** + * \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()) { + yield(); + } + + 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) { + (void)off; + (void)way; + return false; + } + /** Internal - do not use. + * \param[in] pos + * \return true/false. + */ + bool seekpos(pos_type pos) { + (void)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) { + (void)off; + (void)way; + return false; + } + bool seekpos(pos_type pos) { + (void)pos; + return false; + } + bool sync() { + return true; + } + pos_type tellpos() { + return 0; + } + /// @endcond + private: + ArduinoOutStream() {} + Print* m_pr; +}; +#endif // ENABLE_ARDUINO_FEATURES +#endif // ArduinoStream_h diff --git a/libraries/SdFat/src/FatLib/BaseBlockDriver.h b/libraries/SdFat/src/FatLib/BaseBlockDriver.h new file mode 100644 index 0000000..f9774e7 --- /dev/null +++ b/libraries/SdFat/src/FatLib/BaseBlockDriver.h @@ -0,0 +1,75 @@ +/* FatLib Library + * Copyright (C) 2016 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef BaseBlockDriver_h +#define BaseBlockDriver_h +#include "FatLibConfig.h" +/** + * \class BaseBlockDriver + * \brief Base block driver. + */ +class BaseBlockDriver { + public: + /** + * Read a 512 byte block from an SD card. + * + * \param[in] block Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + virtual bool readBlock(uint32_t block, uint8_t* dst) = 0; + /** End multi-block transfer and go to idle state. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + virtual bool syncBlocks() = 0; + /** + * Writes a 512 byte block to an SD card. + * + * \param[in] block Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + virtual bool writeBlock(uint32_t block, const uint8_t* src) = 0; +#if USE_MULTI_BLOCK_IO + /** + * Read multiple 512 byte blocks from an SD card. + * + * \param[in] block Logical block to be read. + * \param[in] nb Number of blocks to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + virtual bool readBlocks(uint32_t block, uint8_t* dst, size_t nb) = 0; + /** + * Write multiple 512 byte blocks to an SD card. + * + * \param[in] block Logical block to be written. + * \param[in] nb Number of blocks to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + virtual bool writeBlocks(uint32_t block, const uint8_t* src, size_t nb) = 0; +#endif // USE_MULTI_BLOCK_IO +}; +#endif // BaseBlockDriver_h diff --git a/libraries/SdFat/src/FatLib/FatApiConstants.h b/libraries/SdFat/src/FatLib/FatApiConstants.h new file mode 100644 index 0000000..22dae03 --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatApiConstants.h @@ -0,0 +1,67 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef FatApiConstants_h +#define FatApiConstants_h +//------------------------------------------------------------------------------ +// use the gnu style oflag in open() +/** open() oflag for reading */ +const uint8_t O_READ = 0X01; +/** open() oflag - same as O_IN */ +const uint8_t O_RDONLY = O_READ; +/** open() oflag for write */ +const uint8_t O_WRITE = 0X02; +/** open() oflag - same as O_WRITE */ +const uint8_t O_WRONLY = O_WRITE; +/** open() oflag for reading and writing */ +const uint8_t O_RDWR = (O_READ | O_WRITE); +/** open() oflag mask for access modes */ +const uint8_t O_ACCMODE = (O_READ | O_WRITE); +/** The file offset shall be set to the end of the file prior to each write. */ +const uint8_t O_APPEND = 0X04; +/** synchronous writes - call sync() after each write */ +const uint8_t O_SYNC = 0X08; +/** truncate the file to zero length */ +const uint8_t O_TRUNC = 0X10; +/** set the initial position at the end of the file */ +const uint8_t O_AT_END = 0X20; +/** create the file if nonexistent */ +const uint8_t O_CREAT = 0X40; +/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ +const uint8_t O_EXCL = 0X80; + +// FatFile class static and const definitions +// flags for ls() +/** ls() flag for list all files including hidden. */ +const uint8_t LS_A = 1; +/** ls() flag to print modify. date */ +const uint8_t LS_DATE = 2; +/** ls() flag to print file size. */ +const uint8_t LS_SIZE = 4; +/** ls() flag for recursive list of subdirectories */ +const uint8_t LS_R = 8; + +// flags for timestamp +/** set the file's last access date */ +const uint8_t T_ACCESS = 1; +/** set the file's creation date and time */ +const uint8_t T_CREATE = 2; +/** Set the file's write date and time */ +const uint8_t T_WRITE = 4; +#endif // FatApiConstants_h diff --git a/libraries/SdFat/src/FatLib/FatFile.cpp b/libraries/SdFat/src/FatLib/FatFile.cpp new file mode 100644 index 0000000..8f3a820 --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatFile.cpp @@ -0,0 +1,1493 @@ +/* FatLib Library + * Copyright (C) 2012 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#include "FatFile.h" +#include "FatFileSystem.h" +//------------------------------------------------------------------------------ +// Pointer to cwd directory. +FatFile* FatFile::m_cwd = 0; +// Callback function for date/time. +void (*FatFile::m_dateTime)(uint16_t* date, uint16_t* time) = 0; +//------------------------------------------------------------------------------ +// Add a cluster to a file. +bool FatFile::addCluster() { + m_flags |= F_FILE_DIR_DIRTY; + return m_vol->allocateCluster(m_curCluster, &m_curCluster); +} +//------------------------------------------------------------------------------ +// Add a cluster to a directory file and zero the cluster. +// Return with first block of cluster in the cache. +bool FatFile::addDirCluster() { + uint32_t block; + cache_t* pc; + + if (isRootFixed()) { + DBG_FAIL_MACRO; + goto fail; + } + // max folder size + if (m_curPosition >= 512UL*4095) { + DBG_FAIL_MACRO; + goto fail; + } + if (!addCluster()) { + DBG_FAIL_MACRO; + goto fail; + } + block = m_vol->clusterFirstBlock(m_curCluster); + pc = m_vol->cacheFetchData(block, FatCache::CACHE_RESERVE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + memset(pc, 0, 512); + // zero rest of clusters + for (uint8_t i = 1; i < m_vol->blocksPerCluster(); i++) { + if (!m_vol->writeBlock(block + i, pc->data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + // Set position to EOF to avoid inconsistent curCluster/curPosition. + m_curPosition += 512UL*m_vol->blocksPerCluster(); + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +// cache a file's directory entry +// return pointer to cached entry or null for failure +dir_t* FatFile::cacheDirEntry(uint8_t action) { + cache_t* pc; + pc = m_vol->cacheFetchData(m_dirBlock, action); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + return pc->dir + (m_dirIndex & 0XF); + +fail: + return 0; +} +//------------------------------------------------------------------------------ +bool FatFile::close() { + bool rtn = sync(); + m_attr = FILE_ATTR_CLOSED; + return rtn; +} +//------------------------------------------------------------------------------ +bool FatFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { + // error if no blocks + if (m_firstCluster == 0) { + DBG_FAIL_MACRO; + goto fail; + } + for (uint32_t c = m_firstCluster; ; c++) { + uint32_t next; + int8_t fg = m_vol->fatGet(c, &next); + if (fg < 0) { + DBG_FAIL_MACRO; + goto fail; + } + // check for contiguous + if (fg == 0 || next != (c + 1)) { + // error if not end of chain + if (fg) { + DBG_FAIL_MACRO; + goto fail; + } + *bgnBlock = m_vol->clusterFirstBlock(m_firstCluster); + *endBlock = m_vol->clusterFirstBlock(c) + + m_vol->blocksPerCluster() - 1; + return true; + } + } + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::createContiguous(FatFile* dirFile, + const char* path, uint32_t size) { + uint32_t count; + + // don't allow zero length file + if (size == 0) { + DBG_FAIL_MACRO; + goto fail; + } + if (!open(dirFile, path, O_CREAT | O_EXCL | O_RDWR)) { + DBG_FAIL_MACRO; + goto fail; + } + // calculate number of clusters needed + count = ((size - 1) >> (m_vol->clusterSizeShift() + 9)) + 1; + + // allocate clusters + if (!m_vol->allocContiguous(count, &m_firstCluster)) { + remove(); + DBG_FAIL_MACRO; + goto fail; + } + m_fileSize = size; + + // insure sync() will update dir entry + m_flags |= F_FILE_DIR_DIRTY; + return sync(); + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::dirEntry(dir_t* dst) { + dir_t* dir; + // Make sure fields on device are correct. + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + // read entry + dir = cacheDirEntry(FatCache::CACHE_FOR_READ); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + // copy to caller's struct + memcpy(dst, dir, sizeof(dir_t)); + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +uint8_t FatFile::dirName(const dir_t* dir, char* name) { + uint8_t j = 0; + uint8_t lcBit = DIR_NT_LC_BASE; + for (uint8_t i = 0; i < 11; i++) { + if (dir->name[i] == ' ') { + continue; + } + if (i == 8) { + // Position bit for extension. + lcBit = DIR_NT_LC_EXT; + name[j++] = '.'; + } + char c = dir->name[i]; + if ('A' <= c && c <= 'Z' && (lcBit & dir->reservedNT)) { + c += 'a' - 'A'; + } + name[j++] = c; + } + name[j] = 0; + return j; +} + +//------------------------------------------------------------------------------ +uint32_t FatFile::dirSize() { + int8_t fg; + if (!isDir()) { + return 0; + } + if (isRootFixed()) { + return 32*m_vol->rootDirEntryCount(); + } + uint16_t n = 0; + uint32_t c = isRoot32() ? m_vol->rootDirStart() : m_firstCluster; + do { + fg = m_vol->fatGet(c, &c); + if (fg < 0 || n > 4095) { + return 0; + } + n += m_vol->blocksPerCluster(); + } while (fg); + return 512UL*n; +} +//------------------------------------------------------------------------------ +int16_t FatFile::fgets(char* str, int16_t num, char* delim) { + char ch; + int16_t n = 0; + int16_t r = -1; + while ((n + 1) < num && (r = read(&ch, 1)) == 1) { + // delete CR + if (ch == '\r') { + continue; + } + str[n++] = ch; + if (!delim) { + if (ch == '\n') { + break; + } + } else { + if (strchr(delim, ch)) { + break; + } + } + } + if (r < 0) { + // read error + return -1; + } + str[n] = '\0'; + return n; +} +//------------------------------------------------------------------------------ +void FatFile::getpos(FatPos_t* pos) { + pos->position = m_curPosition; + pos->cluster = m_curCluster; +} +//------------------------------------------------------------------------------ +bool FatFile::mkdir(FatFile* parent, const char* path, bool pFlag) { + fname_t fname; + FatFile tmpDir; + + if (isOpen() || !parent->isDir()) { + DBG_FAIL_MACRO; + goto fail; + } + if (isDirSeparator(*path)) { + while (isDirSeparator(*path)) { + path++; + } + if (!tmpDir.openRoot(parent->m_vol)) { + DBG_FAIL_MACRO; + goto fail; + } + parent = &tmpDir; + } + while (1) { + if (!parsePathName(path, &fname, &path)) { + DBG_FAIL_MACRO; + goto fail; + } + if (!*path) { + break; + } + if (!open(parent, &fname, O_READ)) { + if (!pFlag || !mkdir(parent, &fname)) { + DBG_FAIL_MACRO; + goto fail; + } + } + tmpDir = *this; + parent = &tmpDir; + close(); + } + return mkdir(parent, &fname); + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::mkdir(FatFile* parent, fname_t* fname) { + uint32_t block; + dir_t dot; + dir_t* dir; + cache_t* pc; + + if (!parent->isDir()) { + DBG_FAIL_MACRO; + goto fail; + } + // create a normal file + if (!open(parent, fname, O_CREAT | O_EXCL | O_RDWR)) { + DBG_FAIL_MACRO; + goto fail; + } + // convert file to directory + m_flags = O_READ; + m_attr = FILE_ATTR_SUBDIR; + + // allocate and zero first cluster + if (!addDirCluster()) { + DBG_FAIL_MACRO; + goto fail; + } + m_firstCluster = m_curCluster; + // Set to start of dir + rewind(); + // force entry to device + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + // cache entry - should already be in cache due to sync() call + dir = cacheDirEntry(FatCache::CACHE_FOR_WRITE); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + // change directory entry attribute + dir->attributes = DIR_ATT_DIRECTORY; + + // make entry for '.' + memcpy(&dot, dir, sizeof(dot)); + dot.name[0] = '.'; + for (uint8_t i = 1; i < 11; i++) { + dot.name[i] = ' '; + } + + // cache block for '.' and '..' + block = m_vol->clusterFirstBlock(m_firstCluster); + pc = m_vol->cacheFetchData(block, FatCache::CACHE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + // copy '.' to block + memcpy(&pc->dir[0], &dot, sizeof(dot)); + // make entry for '..' + dot.name[1] = '.'; + dot.firstClusterLow = parent->m_firstCluster & 0XFFFF; + dot.firstClusterHigh = parent->m_firstCluster >> 16; + // copy '..' to block + memcpy(&pc->dir[1], &dot, sizeof(dot)); + // write first block + return m_vol->cacheSync(); + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::open(FatFileSystem* fs, const char* path, uint8_t oflag) { + return open(fs->vwd(), path, oflag); +} +//------------------------------------------------------------------------------ +bool FatFile::open(FatFile* dirFile, const char* path, uint8_t oflag) { + FatFile tmpDir; + fname_t fname; + + // error if already open + if (isOpen() || !dirFile->isDir()) { + DBG_FAIL_MACRO; + goto fail; + } + if (isDirSeparator(*path)) { + while (isDirSeparator(*path)) { + path++; + } + if (*path == 0) { + return openRoot(dirFile->m_vol); + } + if (!tmpDir.openRoot(dirFile->m_vol)) { + DBG_FAIL_MACRO; + goto fail; + } + dirFile = &tmpDir; + } + while (1) { + if (!parsePathName(path, &fname, &path)) { + DBG_FAIL_MACRO; + goto fail; + } + if (*path == 0) { + break; + } + if (!open(dirFile, &fname, O_READ)) { + DBG_FAIL_MACRO; + goto fail; + } + tmpDir = *this; + dirFile = &tmpDir; + close(); + } + return open(dirFile, &fname, oflag); + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::open(FatFile* dirFile, uint16_t index, uint8_t oflag) { + uint8_t chksum = 0; + uint8_t lfnOrd = 0; + dir_t* dir; + ldir_t*ldir; + + // Error if already open. + if (isOpen() || !dirFile->isDir()) { + DBG_FAIL_MACRO; + goto fail; + } + // Don't open existing file if O_EXCL - user call error. + if (oflag & O_EXCL) { + DBG_FAIL_MACRO; + goto fail; + } + if (index) { + // Check for LFN. + if (!dirFile->seekSet(32UL*(index -1))) { + DBG_FAIL_MACRO; + goto fail; + } + ldir = reinterpret_cast(dirFile->readDirCache()); + if (!ldir) { + DBG_FAIL_MACRO; + goto fail; + } + if (ldir->attr == DIR_ATT_LONG_NAME) { + if (1 == (ldir->ord & 0X1F)) { + chksum = ldir->chksum; + // Use largest possible number. + lfnOrd = index > 20 ? 20 : index; + } + } + } else { + dirFile->rewind(); + } + // read entry into cache + dir = dirFile->readDirCache(); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + // error if empty slot or '.' or '..' + if (dir->name[0] == DIR_NAME_DELETED || + dir->name[0] == DIR_NAME_FREE || + dir->name[0] == '.') { + DBG_FAIL_MACRO; + goto fail; + } + if (lfnOrd && chksum != lfnChecksum(dir->name)) { + DBG_FAIL_MACRO; + goto fail; + } + // open cached entry + if (!openCachedEntry(dirFile, index, oflag, lfnOrd)) { + DBG_FAIL_MACRO; + goto fail; + } + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +// open a cached directory entry. + +bool FatFile::openCachedEntry(FatFile* dirFile, uint16_t dirIndex, + uint8_t oflag, uint8_t lfnOrd) { + uint32_t firstCluster; + memset(this, 0, sizeof(FatFile)); + // location of entry in cache + m_vol = dirFile->m_vol; + m_dirIndex = dirIndex; + m_dirCluster = dirFile->m_firstCluster; + dir_t* dir = &m_vol->cacheAddress()->dir[0XF & dirIndex]; + + // Must be file or subdirectory. + if (!DIR_IS_FILE_OR_SUBDIR(dir)) { + DBG_FAIL_MACRO; + goto fail; + } + m_attr = dir->attributes & FILE_ATTR_COPY; + if (DIR_IS_FILE(dir)) { + m_attr |= FILE_ATTR_FILE; + } + m_lfnOrd = lfnOrd; + // Write, truncate, or at end is an error for a directory or read-only file. + if (oflag & (O_WRITE | O_TRUNC | O_AT_END)) { + if (isSubDir() || isReadOnly()) { + DBG_FAIL_MACRO; + goto fail; + } + } + // save open flags for read/write + m_flags = oflag & F_OFLAG; + + m_dirBlock = m_vol->cacheBlockNumber(); + + // copy first cluster number for directory fields + firstCluster = ((uint32_t)dir->firstClusterHigh << 16) + | dir->firstClusterLow; + + if (oflag & O_TRUNC) { + if (firstCluster && !m_vol->freeChain(firstCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + // need to update directory entry + m_flags |= F_FILE_DIR_DIRTY; + } else { + m_firstCluster = firstCluster; + m_fileSize = dir->fileSize; + } + if ((oflag & O_AT_END) && !seekSet(m_fileSize)) { + DBG_FAIL_MACRO; + goto fail; + } + return true; + +fail: + m_attr = FILE_ATTR_CLOSED; + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::openNext(FatFile* dirFile, uint8_t oflag) { + uint8_t chksum = 0; + ldir_t* ldir; + uint8_t lfnOrd = 0; + uint16_t index; + + // Check for not open and valid directory.. + if (isOpen() || !dirFile->isDir() || (dirFile->curPosition() & 0X1F)) { + DBG_FAIL_MACRO; + goto fail; + } + while (1) { + // read entry into cache + index = dirFile->curPosition()/32; + dir_t* dir = dirFile->readDirCache(); + if (!dir) { + if (dirFile->getError()) { + DBG_FAIL_MACRO; + } + goto fail; + } + // done if last entry + if (dir->name[0] == DIR_NAME_FREE) { + goto fail; + } + // skip empty slot or '.' or '..' + if (dir->name[0] == '.' || dir->name[0] == DIR_NAME_DELETED) { + lfnOrd = 0; + } else if (DIR_IS_FILE_OR_SUBDIR(dir)) { + if (lfnOrd && chksum != lfnChecksum(dir->name)) { + DBG_FAIL_MACRO; + goto fail; + } + if (!openCachedEntry(dirFile, index, oflag, lfnOrd)) { + DBG_FAIL_MACRO; + goto fail; + } + return true; + } else if (DIR_IS_LONG_NAME(dir)) { + ldir = reinterpret_cast(dir); + if (ldir->ord & LDIR_ORD_LAST_LONG_ENTRY) { + lfnOrd = ldir->ord & 0X1F; + chksum = ldir->chksum; + } + } else { + lfnOrd = 0; + } + } + +fail: + return false; +} +#ifndef DOXYGEN_SHOULD_SKIP_THIS +//------------------------------------------------------------------------------ +/** Open a file's parent directory. + * + * \param[in] file Parent of this directory will be opened. Must not be root. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ +bool FatFile::openParent(FatFile* dirFile) { + FatFile dotdot; + uint32_t lbn; + dir_t* dir; + uint32_t ddc; + cache_t* cb; + + if (isOpen() || !dirFile->isOpen()) { + goto fail; + } + if (dirFile->m_dirCluster == 0) { + return openRoot(dirFile->m_vol); + } + lbn = dirFile->m_vol->clusterFirstBlock(dirFile->m_dirCluster); + cb = dirFile->m_vol->cacheFetchData(lbn, FatCache::CACHE_FOR_READ); + if (!cb) { + DBG_FAIL_MACRO; + goto fail; + } + // Point to dir entery for .. + dir = cb->dir + 1; + ddc = dir->firstClusterLow | ((uint32_t)dir->firstClusterHigh << 16); + if (ddc == 0) { + if (!dotdot.openRoot(dirFile->m_vol)) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + memset(&dotdot, 0, sizeof(FatFile)); + dotdot.m_attr = FILE_ATTR_SUBDIR; + dotdot.m_flags = O_READ; + dotdot.m_vol = dirFile->m_vol; + dotdot.m_firstCluster = ddc; + } + uint32_t di; + do { + di = dotdot.curPosition()/32; + dir = dotdot.readDirCache(); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + ddc = dir->firstClusterLow | ((uint32_t)dir->firstClusterHigh << 16); + } while (ddc != dirFile->m_dirCluster); + return open(&dotdot, di, O_READ); + +fail: + return false; +} +#endif // DOXYGEN_SHOULD_SKIP_THIS +//------------------------------------------------------------------------------ +bool FatFile::openRoot(FatVolume* vol) { + // error if file is already open + if (isOpen()) { + DBG_FAIL_MACRO; + goto fail; + } + memset(this, 0, sizeof(FatFile)); + + m_vol = vol; + switch (vol->fatType()) { +#if FAT12_SUPPORT + case 12: +#endif // FAT12_SUPPORT + case 16: + m_attr = FILE_ATTR_ROOT_FIXED; + break; + + case 32: + m_attr = FILE_ATTR_ROOT32; + break; + + default: + DBG_FAIL_MACRO; + goto fail; + } + // read only + m_flags = O_READ; + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +int FatFile::peek() { + FatPos_t pos; + getpos(&pos); + int c = read(); + if (c >= 0) { + setpos(&pos); + } + return c; +} +//------------------------------------------------------------------------------ +int FatFile::read(void* buf, size_t nbyte) { + int8_t fg; + uint8_t blockOfCluster = 0; + uint8_t* dst = reinterpret_cast(buf); + uint16_t offset; + size_t toRead; + uint32_t block; // raw device block number + cache_t* pc; + + // error if not open for read + if (!isOpen() || !(m_flags & O_READ)) { + DBG_FAIL_MACRO; + goto fail; + } + + if (isFile()) { + uint32_t tmp32 = m_fileSize - m_curPosition; + if (nbyte >= tmp32) { + nbyte = tmp32; + } + } else if (isRootFixed()) { + uint16_t tmp16 = 32*m_vol->m_rootDirEntryCount - (uint16_t)m_curPosition; + if (nbyte > tmp16) { + nbyte = tmp16; + } + } + toRead = nbyte; + while (toRead) { + size_t n; + offset = m_curPosition & 0X1FF; // offset in block + if (isRootFixed()) { + block = m_vol->rootDirStart() + (m_curPosition >> 9); + } else { + blockOfCluster = m_vol->blockOfCluster(m_curPosition); + if (offset == 0 && blockOfCluster == 0) { + // start of new cluster + if (m_curPosition == 0) { + // use first cluster in file + m_curCluster = isRoot32() ? m_vol->rootDirStart() : m_firstCluster; + } else { + // get next cluster from FAT + fg = m_vol->fatGet(m_curCluster, &m_curCluster); + if (fg < 0) { + DBG_FAIL_MACRO; + goto fail; + } + if (fg == 0) { + if (isDir()) { + break; + } + DBG_FAIL_MACRO; + goto fail; + } + } + } + block = m_vol->clusterFirstBlock(m_curCluster) + blockOfCluster; + } + if (offset != 0 || toRead < 512 || block == m_vol->cacheBlockNumber()) { + // amount to be read from current block + n = 512 - offset; + if (n > toRead) { + n = toRead; + } + // read block to cache and copy data to caller + pc = m_vol->cacheFetchData(block, FatCache::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + uint8_t* src = pc->data + offset; + memcpy(dst, src, n); +#if USE_MULTI_BLOCK_IO + } else if (toRead >= 1024) { + size_t nb = toRead >> 9; + if (!isRootFixed()) { + uint8_t mb = m_vol->blocksPerCluster() - blockOfCluster; + if (mb < nb) { + nb = mb; + } + } + n = 512*nb; + if (block <= m_vol->cacheBlockNumber() + && block < (m_vol->cacheBlockNumber() + nb)) { + // flush cache if a block is in the cache + if (!m_vol->cacheSyncData()) { + DBG_FAIL_MACRO; + goto fail; + } + } + if (!m_vol->readBlocks(block, dst, nb)) { + DBG_FAIL_MACRO; + goto fail; + } +#endif // USE_MULTI_BLOCK_IO + } else { + // read single block + n = 512; + if (!m_vol->readBlock(block, dst)) { + DBG_FAIL_MACRO; + goto fail; + } + } + dst += n; + m_curPosition += n; + toRead -= n; + } + return nbyte - toRead; + +fail: + m_error |= READ_ERROR; + return -1; +} +//------------------------------------------------------------------------------ +int8_t FatFile::readDir(dir_t* dir) { + int16_t n; + // if not a directory file or miss-positioned return an error + if (!isDir() || (0X1F & m_curPosition)) { + return -1; + } + + while (1) { + n = read(dir, sizeof(dir_t)); + if (n != sizeof(dir_t)) { + return n == 0 ? 0 : -1; + } + // last entry if DIR_NAME_FREE + if (dir->name[0] == DIR_NAME_FREE) { + return 0; + } + // skip empty entries and entry for . and .. + if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') { + continue; + } + // return if normal file or subdirectory + if (DIR_IS_FILE_OR_SUBDIR(dir)) { + return n; + } + } +} +//------------------------------------------------------------------------------ +// Read next directory entry into the cache +// Assumes file is correctly positioned +dir_t* FatFile::readDirCache(bool skipReadOk) { +// uint8_t b; + uint8_t i = (m_curPosition >> 5) & 0XF; + + if (i == 0 || !skipReadOk) { + int8_t n = read(&n, 1); + if (n != 1) { + if (n != 0) { + DBG_FAIL_MACRO; + } + goto fail; + } + m_curPosition += 31; + } else { + m_curPosition += 32; + } + // return pointer to entry + return m_vol->cacheAddress()->dir + i; + +fail: + return 0; +} +//------------------------------------------------------------------------------ +bool FatFile::remove(FatFile* dirFile, const char* path) { + FatFile file; + if (!file.open(dirFile, path, O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + return file.remove(); + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::rename(FatFile* dirFile, const char* newPath) { + dir_t entry; + uint32_t dirCluster = 0; + FatFile file; + FatFile oldFile; + cache_t* pc; + dir_t* dir; + + // Must be an open file or subdirectory. + if (!(isFile() || isSubDir())) { + DBG_FAIL_MACRO; + goto fail; + } + // Can't rename LFN in 8.3 mode. + if (!USE_LONG_FILE_NAMES && isLFN()) { + DBG_FAIL_MACRO; + goto fail; + } + // Can't move file to new volume. + if (m_vol != dirFile->m_vol) { + DBG_FAIL_MACRO; + goto fail; + } + // sync() and cache directory entry + sync(); + oldFile = *this; + dir = cacheDirEntry(FatCache::CACHE_FOR_READ); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + // save directory entry + memcpy(&entry, dir, sizeof(entry)); + // make directory entry for new path + if (isFile()) { + if (!file.open(dirFile, newPath, O_CREAT | O_EXCL | O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + // don't create missing path prefix components + if (!file.mkdir(dirFile, newPath, false)) { + DBG_FAIL_MACRO; + goto fail; + } + // save cluster containing new dot dot + dirCluster = file.m_firstCluster; + } + // change to new directory entry + + m_dirBlock = file.m_dirBlock; + m_dirIndex = file.m_dirIndex; + m_lfnOrd = file.m_lfnOrd; + m_dirCluster = file.m_dirCluster; + // mark closed to avoid possible destructor close call + file.m_attr = FILE_ATTR_CLOSED; + + // cache new directory entry + dir = cacheDirEntry(FatCache::CACHE_FOR_WRITE); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + // copy all but name and name flags to new directory entry + memcpy(&dir->creationTimeTenths, &entry.creationTimeTenths, + sizeof(entry) - sizeof(dir->name) - 2); + dir->attributes = entry.attributes; + + // update dot dot if directory + if (dirCluster) { + // get new dot dot + uint32_t block = m_vol->clusterFirstBlock(dirCluster); + pc = m_vol->cacheFetchData(block, FatCache::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + memcpy(&entry, &pc->dir[1], sizeof(entry)); + + // free unused cluster + if (!m_vol->freeChain(dirCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + // store new dot dot + block = m_vol->clusterFirstBlock(m_firstCluster); + pc = m_vol->cacheFetchData(block, FatCache::CACHE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + memcpy(&pc->dir[1], &entry, sizeof(entry)); + } + // Remove old directory entry; + oldFile.m_firstCluster = 0; + oldFile.m_flags = O_WRITE; + oldFile.m_attr = FILE_ATTR_FILE; + if (!oldFile.remove()) { + DBG_FAIL_MACRO; + goto fail; + } + return m_vol->cacheSync(); + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::rmdir() { + // must be open subdirectory + if (!isSubDir() || (!USE_LONG_FILE_NAMES && isLFN())) { + DBG_FAIL_MACRO; + goto fail; + } + rewind(); + + // make sure directory is empty + while (1) { + dir_t* dir = readDirCache(true); + if (!dir) { + // EOF if no error. + if (!getError()) { + break; + } + DBG_FAIL_MACRO; + goto fail; + } + // done if past last used entry + if (dir->name[0] == DIR_NAME_FREE) { + break; + } + // skip empty slot, '.' or '..' + if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') { + continue; + } + // error not empty + if (DIR_IS_FILE_OR_SUBDIR(dir)) { + DBG_FAIL_MACRO; + goto fail; + } + } + // convert empty directory to normal file for remove + m_attr = FILE_ATTR_FILE; + m_flags |= O_WRITE; + return remove(); + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::rmRfStar() { + uint16_t index; + FatFile f; + if (!isDir()) { + DBG_FAIL_MACRO; + goto fail; + } + rewind(); + while (1) { + // remember position + index = m_curPosition/32; + + dir_t* dir = readDirCache(); + if (!dir) { + // At EOF if no error. + if (!getError()) { + break; + } + DBG_FAIL_MACRO; + goto fail; + } + // done if past last entry + if (dir->name[0] == DIR_NAME_FREE) { + break; + } + + // skip empty slot or '.' or '..' + if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') { + continue; + } + + // skip if part of long file name or volume label in root + if (!DIR_IS_FILE_OR_SUBDIR(dir)) { + continue; + } + + if (!f.open(this, index, O_READ)) { + DBG_FAIL_MACRO; + goto fail; + } + if (f.isSubDir()) { + // recursively delete + if (!f.rmRfStar()) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + // ignore read-only + f.m_flags |= O_WRITE; + if (!f.remove()) { + DBG_FAIL_MACRO; + goto fail; + } + } + // position to next entry if required + if (m_curPosition != (32UL*(index + 1))) { + if (!seekSet(32UL*(index + 1))) { + DBG_FAIL_MACRO; + goto fail; + } + } + } + // don't try to delete root + if (!isRoot()) { + if (!rmdir()) { + DBG_FAIL_MACRO; + goto fail; + } + } + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::seekSet(uint32_t pos) { + uint32_t nCur; + uint32_t nNew; + uint32_t tmp = m_curCluster; + // error if file not open + if (!isOpen()) { + DBG_FAIL_MACRO; + goto fail; + } + // Optimize O_APPEND writes. + if (pos == m_curPosition) { + return true; + } + if (pos == 0) { + // set position to start of file + m_curCluster = 0; + goto done; + } + if (isFile()) { + if (pos > m_fileSize) { + DBG_FAIL_MACRO; + goto fail; + } + } else if (isRootFixed()) { + if (pos <= 32*m_vol->rootDirEntryCount()) { + goto done; + } + DBG_FAIL_MACRO; + goto fail; + } + // calculate cluster index for cur and new position + nCur = (m_curPosition - 1) >> (m_vol->clusterSizeShift() + 9); + nNew = (pos - 1) >> (m_vol->clusterSizeShift() + 9); + + if (nNew < nCur || m_curPosition == 0) { + // must follow chain from first cluster + m_curCluster = isRoot32() ? m_vol->rootDirStart() : m_firstCluster; + } else { + // advance from curPosition + nNew -= nCur; + } + while (nNew--) { + if (m_vol->fatGet(m_curCluster, &m_curCluster) <= 0) { + DBG_FAIL_MACRO; + goto fail; + } + } + +done: + m_curPosition = pos; + return true; + +fail: + m_curCluster = tmp; + return false; +} +//------------------------------------------------------------------------------ +void FatFile::setpos(FatPos_t* pos) { + m_curPosition = pos->position; + m_curCluster = pos->cluster; +} +//------------------------------------------------------------------------------ +bool FatFile::sync() { + if (!isOpen()) { + return true; + } + if (m_flags & F_FILE_DIR_DIRTY) { + dir_t* dir = cacheDirEntry(FatCache::CACHE_FOR_WRITE); + // check for deleted by another open file object + if (!dir || dir->name[0] == DIR_NAME_DELETED) { + DBG_FAIL_MACRO; + goto fail; + } + // do not set filesize for dir files + if (isFile()) { + dir->fileSize = m_fileSize; + } + + // update first cluster fields + dir->firstClusterLow = m_firstCluster & 0XFFFF; + dir->firstClusterHigh = m_firstCluster >> 16; + + // set modify time if user supplied a callback date/time function + if (m_dateTime) { + m_dateTime(&dir->lastWriteDate, &dir->lastWriteTime); + dir->lastAccessDate = dir->lastWriteDate; + } + // clear directory dirty + m_flags &= ~F_FILE_DIR_DIRTY; + } + if (m_vol->cacheSync()) { + return true; + } + DBG_FAIL_MACRO; + +fail: + m_error |= WRITE_ERROR; + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::timestamp(FatFile* file) { + dir_t* dir; + dir_t srcDir; + + // most be files get timestamps + if (!isFile() || !file->isFile() || !file->dirEntry(&srcDir)) { + DBG_FAIL_MACRO; + goto fail; + } + // update directory fields + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + dir = cacheDirEntry(FatCache::CACHE_FOR_WRITE); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + // copy timestamps + dir->lastAccessDate = srcDir.lastAccessDate; + dir->creationDate = srcDir.creationDate; + dir->creationTime = srcDir.creationTime; + dir->creationTimeTenths = srcDir.creationTimeTenths; + dir->lastWriteDate = srcDir.lastWriteDate; + dir->lastWriteTime = srcDir.lastWriteTime; + + // write back entry + return m_vol->cacheSync(); + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, + uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { + uint16_t dirDate; + uint16_t dirTime; + dir_t* dir; + + if (!isFile() + || year < 1980 + || year > 2107 + || month < 1 + || month > 12 + || day < 1 + || day > 31 + || hour > 23 + || minute > 59 + || second > 59) { + DBG_FAIL_MACRO; + goto fail; + } + // update directory entry + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + dir = cacheDirEntry(FatCache::CACHE_FOR_WRITE); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + dirDate = FAT_DATE(year, month, day); + dirTime = FAT_TIME(hour, minute, second); + if (flags & T_ACCESS) { + dir->lastAccessDate = dirDate; + } + if (flags & T_CREATE) { + dir->creationDate = dirDate; + dir->creationTime = dirTime; + // seems to be units of 1/100 second not 1/10 as Microsoft states + dir->creationTimeTenths = second & 1 ? 100 : 0; + } + if (flags & T_WRITE) { + dir->lastWriteDate = dirDate; + dir->lastWriteTime = dirTime; + } + return m_vol->cacheSync(); + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::truncate(uint32_t length) { + uint32_t newPos; + // error if not a normal file or read-only + if (!isFile() || !(m_flags & O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + // error if length is greater than current size + if (length > m_fileSize) { + DBG_FAIL_MACRO; + goto fail; + } + // fileSize and length are zero - nothing to do + if (m_fileSize == 0) { + return true; + } + + // remember position for seek after truncation + newPos = m_curPosition > length ? length : m_curPosition; + + // position to last cluster in truncated file + if (!seekSet(length)) { + DBG_FAIL_MACRO; + goto fail; + } + if (length == 0) { + // free all clusters + if (!m_vol->freeChain(m_firstCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + m_firstCluster = 0; + } else { + uint32_t toFree; + int8_t fg = m_vol->fatGet(m_curCluster, &toFree); + if (fg < 0) { + DBG_FAIL_MACRO; + goto fail; + } + if (fg) { + // free extra clusters + if (!m_vol->freeChain(toFree)) { + DBG_FAIL_MACRO; + goto fail; + } + // current cluster is end of chain + if (!m_vol->fatPutEOC(m_curCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + } + } + m_fileSize = length; + + // need to update directory entry + m_flags |= F_FILE_DIR_DIRTY; + + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + // set file to correct position + return seekSet(newPos); + +fail: + return false; +} +//------------------------------------------------------------------------------ +int FatFile::write(const void* buf, size_t nbyte) { + // convert void* to uint8_t* - must be before goto statements + const uint8_t* src = reinterpret_cast(buf); + cache_t* pc; + uint8_t cacheOption; + // number of bytes left to write - must be before goto statements + size_t nToWrite = nbyte; + size_t n; + // error if not a normal file or is read-only + if (!isFile() || !(m_flags & O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + // seek to end of file if append flag + if ((m_flags & O_APPEND)) { + if (!seekSet(m_fileSize)) { + DBG_FAIL_MACRO; + goto fail; + } + } + // Don't exceed max fileSize. + if (nbyte > (0XFFFFFFFF - m_curPosition)) { + DBG_FAIL_MACRO; + goto fail; + } + while (nToWrite) { + uint8_t blockOfCluster = m_vol->blockOfCluster(m_curPosition); + uint16_t blockOffset = m_curPosition & 0X1FF; + if (blockOfCluster == 0 && blockOffset == 0) { + // start of new cluster + if (m_curCluster != 0) { + int8_t fg = m_vol->fatGet(m_curCluster, &m_curCluster); + if (fg < 0) { + DBG_FAIL_MACRO; + goto fail; + } + if (fg == 0) { + // add cluster if at end of chain + if (!addCluster()) { + DBG_FAIL_MACRO; + goto fail; + } + } + } else { + if (m_firstCluster == 0) { + // allocate first cluster of file + if (!addCluster()) { + DBG_FAIL_MACRO; + goto fail; + } + m_firstCluster = m_curCluster; + } else { + m_curCluster = m_firstCluster; + } + } + } + // block for data write + uint32_t block = m_vol->clusterFirstBlock(m_curCluster) + blockOfCluster; + + if (blockOffset != 0 || nToWrite < 512) { + // partial block - must use cache + // max space in block + n = 512 - blockOffset; + // lesser of space and amount to write + if (n > nToWrite) { + n = nToWrite; + } + + if (blockOffset == 0 && m_curPosition >= m_fileSize) { + // start of new block don't need to read into cache + cacheOption = FatCache::CACHE_RESERVE_FOR_WRITE; + } else { + // rewrite part of block + cacheOption = FatCache::CACHE_FOR_WRITE; + } + pc = m_vol->cacheFetchData(block, cacheOption); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + uint8_t* dst = pc->data + blockOffset; + memcpy(dst, src, n); + if (512 == (n + blockOffset)) { + // Force write if block is full - improves large writes. + if (!m_vol->cacheSyncData()) { + DBG_FAIL_MACRO; + goto fail; + } + } +#if USE_MULTI_BLOCK_IO + } else if (nToWrite >= 1024) { + // use multiple block write command + uint8_t maxBlocks = m_vol->blocksPerCluster() - blockOfCluster; + size_t nBlock = nToWrite >> 9; + if (nBlock > maxBlocks) { + nBlock = maxBlocks; + } + n = 512*nBlock; + if (block <= m_vol->cacheBlockNumber() + && block < (m_vol->cacheBlockNumber() + nBlock)) { + // invalidate cache if block is in cache + m_vol->cacheInvalidate(); + } + if (!m_vol->writeBlocks(block, src, nBlock)) { + DBG_FAIL_MACRO; + goto fail; + } +#endif // USE_MULTI_BLOCK_IO + } else { + // use single block write command + n = 512; + if (m_vol->cacheBlockNumber() == block) { + m_vol->cacheInvalidate(); + } + if (!m_vol->writeBlock(block, src)) { + DBG_FAIL_MACRO; + goto fail; + } + } + m_curPosition += n; + src += n; + nToWrite -= n; + } + if (m_curPosition > m_fileSize) { + // update fileSize and insure sync will update dir entry + m_fileSize = m_curPosition; + m_flags |= F_FILE_DIR_DIRTY; + } else if (m_dateTime) { + // insure sync will update modified date and time + m_flags |= F_FILE_DIR_DIRTY; + } + + if (m_flags & O_SYNC) { + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + } + return nbyte; + +fail: + // return for write error + m_error |= WRITE_ERROR; + return -1; +} diff --git a/libraries/SdFat/src/FatLib/FatFile.h b/libraries/SdFat/src/FatLib/FatFile.h new file mode 100644 index 0000000..db049f5 --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatFile.h @@ -0,0 +1,1001 @@ +/* FatLib Library + * Copyright (C) 2012 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef FatFile_h +#define FatFile_h +/** + * \file + * \brief FatFile class + */ +// #include +#include +#include +#include +#include "FatLibConfig.h" +#include "FatApiConstants.h" +#include "FatStructs.h" +#include "FatVolume.h" +class FatFileSystem; +//------------------------------------------------------------------------------ +// Stuff to store strings in AVR flash. +#ifdef __AVR__ +#include +#else // __AVR__ +#ifndef PSTR +/** store literal string in flash for ARM */ +#define PSTR(x) (x) +#endif // PSTR +#ifndef pgm_read_byte +/** read 8-bits from flash for ARM */ +#define pgm_read_byte(addr) (*(const unsigned char*)(addr)) +#endif // pgm_read_byte +#ifndef pgm_read_word +/** read 16-bits from flash for ARM */ +#define pgm_read_word(addr) (*(const uint16_t*)(addr)) +#endif // pgm_read_word +#ifndef PROGMEM +/** store in flash for ARM */ +#define PROGMEM +#endif // PROGMEM +#endif // __AVR__ +//------------------------------------------------------------------------------ +/** + * \struct FatPos_t + * \brief Internal type for file position - do not use in user apps. + */ +struct FatPos_t { + /** stream position */ + uint32_t position; + /** cluster for position */ + uint32_t cluster; + FatPos_t() : position(0), cluster(0) {} +}; +//------------------------------------------------------------------------------ +/** Expression for path name separator. */ +#define isDirSeparator(c) ((c) == '/') +//------------------------------------------------------------------------------ +/** + * \struct fname_t + * \brief Internal type for Short File Name - do not use in user apps. + */ +struct fname_t { + /** Flags for base and extension character case and LFN. */ + uint8_t flags; + /** length of Long File Name */ + size_t len; + /** Long File Name start. */ + const char* lfn; + /** position for sequence number */ + uint8_t seqPos; + /** Short File Name */ + uint8_t sfn[11]; +}; +/** Derived from a LFN with loss or conversion of characters. */ +const uint8_t FNAME_FLAG_LOST_CHARS = 0X01; +/** Base-name or extension has mixed case. */ +const uint8_t FNAME_FLAG_MIXED_CASE = 0X02; +/** LFN entries are required for file name. */ +const uint8_t FNAME_FLAG_NEED_LFN = + FNAME_FLAG_LOST_CHARS | FNAME_FLAG_MIXED_CASE; +/** Filename base-name is all lower case */ +const uint8_t FNAME_FLAG_LC_BASE = DIR_NT_LC_BASE; +/** Filename extension is all lower case. */ +const uint8_t FNAME_FLAG_LC_EXT = DIR_NT_LC_EXT; +//============================================================================== +/** + * \class FatFile + * \brief Basic file class. + */ +class FatFile { + public: + /** Create an instance. */ + FatFile() : m_attr(FILE_ATTR_CLOSED), m_error(0) {} + /** Create a file object and open it in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see FatFile::open(FatFile*, const char*, uint8_t). + */ + FatFile(const char* path, uint8_t oflag) { + m_attr = FILE_ATTR_CLOSED; + m_error = 0; + open(path, oflag); + } +#if DESTRUCTOR_CLOSES_FILE + ~FatFile() { + if (isOpen()) { + close(); + } + } +#endif // DESTRUCTOR_CLOSES_FILE + +#if ENABLE_ARDUINO_FEATURES + /** List directory contents. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + */ + void ls(uint8_t flags = 0) { + ls(&Serial, flags); + } + /** %Print a directory date field. + * + * Format is yyyy-mm-dd. + * + * \param[in] fatDate The date field from a directory entry. + */ + static void printFatDate(uint16_t fatDate) { + printFatDate(&Serial, fatDate); + } + /** %Print a directory time field. + * + * Format is hh:mm:ss. + * + * \param[in] fatTime The time field from a directory entry. + */ + static void printFatTime(uint16_t fatTime) { + printFatTime(&Serial, fatTime); + } + /** Print a file's name. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + size_t printName() { + return FatFile::printName(&Serial); + } +#endif // ENABLE_ARDUINO_FEATURES + + /** \return value of writeError */ + bool getWriteError() { + return m_error & WRITE_ERROR; + } + /** Set writeError to zero */ + void clearWriteError() { + m_error &= ~WRITE_ERROR; + } + /** Clear all error bits. */ + void clearError() { + m_error = 0; + } + /** \return All error bits. */ + uint8_t getError() { + return m_error; + } + /** get position for streams + * \param[out] pos struct to receive position + */ + void getpos(FatPos_t* pos); + /** set position for streams + * \param[out] pos struct with value for new position + */ + void setpos(FatPos_t* pos); + /** \return The number of bytes available from the current position + * to EOF for normal files. Zero is returned for directory files. + */ + uint32_t available() { + return isFile() ? fileSize() - curPosition() : 0; + } + /** Close a file and force cached data and directory information + * to be written to the storage device. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool close(); + /** Check for contiguous file and return its raw block range. + * + * \param[out] bgnBlock the first block address for the file. + * \param[out] endBlock the last block address for the file. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + /** Create and open a new contiguous file of a specified size. + * + * \param[in] dirFile The directory where the file will be created. + * \param[in] path A path with a validfile name. + * \param[in] size The desired file size. + * + * \return The value true is returned for success and + * the value false, is returned for failure. + */ + bool createContiguous(FatFile* dirFile, + const char* path, uint32_t size); + /** Create and open a new contiguous file of a specified size. + * + * \param[in] path A path with a validfile name. + * \param[in] size The desired file size. + * + * \return The value true is returned for success and + * the value false, is returned for failure. + */ + bool createContiguous(const char* path, uint32_t size) { + return createContiguous(m_cwd, path, size); + } + /** \return The current cluster number for a file or directory. */ + uint32_t curCluster() const { + return m_curCluster; + } + /** \return The current position for a file or directory. */ + uint32_t curPosition() const { + return m_curPosition; + } + /** \return Current working directory */ + static FatFile* cwd() { + return m_cwd; + } + /** Set the date/time callback function + * + * \param[in] dateTime The user's call back function. The callback + * function is of the form: + * + * \code + * void dateTime(uint16_t* date, uint16_t* time) { + * uint16_t year; + * uint8_t month, day, hour, minute, second; + * + * // User gets date and time from GPS or real-time clock here + * + * // return date using FAT_DATE macro to format fields + * *date = FAT_DATE(year, month, day); + * + * // return time using FAT_TIME macro to format fields + * *time = FAT_TIME(hour, minute, second); + * } + * \endcode + * + * Sets the function that is called when a file is created or when + * a file's directory entry is modified by sync(). All timestamps, + * access, creation, and modify, are set when a file is created. + * sync() maintains the last access date and last modify date/time. + * + * See the timestamp() function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t* date, uint16_t* time)) { + m_dateTime = dateTime; + } + /** Cancel the date/time callback function. */ + static void dateTimeCallbackCancel() { + m_dateTime = 0; + } + /** Return a file's directory entry. + * + * \param[out] dir Location for return of the file's directory entry. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool dirEntry(dir_t* dir); + /** + * \return The index of this file in it's directory. + */ + uint16_t dirIndex() { + return m_dirIndex; + } + /** Format the name field of \a dir into the 13 byte array + * \a name in standard 8.3 short name format. + * + * \param[in] dir The directory structure containing the name. + * \param[out] name A 13 byte char array for the formatted name. + * \return length of the name. + */ + static uint8_t dirName(const dir_t* dir, char* name); + /** \return The number of bytes allocated to a directory or zero + * if an error occurs. + */ + uint32_t dirSize(); + /** Dump file in Hex + * \param[in] pr Print stream for list. + * \param[in] pos Start position in file. + * \param[in] n number of locations to dump. + */ + void dmpFile(print_t* pr, uint32_t pos, size_t n); + /** Test for the existence of a file in a directory + * + * \param[in] path Path of the file to be tested for. + * + * The calling instance must be an open directory file. + * + * dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory + * dirFile. + * + * \return true if the file exists else false. + */ + bool exists(const char* path) { + FatFile file; + return file.open(this, path, O_READ); + } + /** + * Get a string from a file. + * + * fgets() reads bytes from a file into the array pointed to by \a str, until + * \a num - 1 bytes are read, or a delimiter is read and transferred to \a str, + * or end-of-file is encountered. The string is then terminated + * with a null byte. + * + * fgets() deletes CR, '\\r', from the string. This insures only a '\\n' + * terminates the string for Windows text files which use CRLF for newline. + * + * \param[out] str Pointer to the array where the string is stored. + * \param[in] num Maximum number of characters to be read + * (including the final null byte). Usually the length + * of the array \a str is used. + * \param[in] delim Optional set of delimiters. The default is "\n". + * + * \return For success fgets() returns the length of the string in \a str. + * If no data is read, fgets() returns zero for EOF or -1 if an error occurred. + */ + int16_t fgets(char* str, int16_t num, char* delim = 0); + /** \return The total number of bytes in a file. */ + uint32_t fileSize() const { + return m_fileSize; + } + /** \return The first cluster number for a file or directory. */ + uint32_t firstCluster() const { + return m_firstCluster; + } + /** + * Get a file's name followed by a zero byte. + * + * \param[out] name An array of characters for the file's name. + * \param[in] size The size of the array in bytes. The array + * must be at least 13 bytes long. The file's name will be + * truncated if the file's name is too long. + * \return The value true, is returned for success and + * the value false, is returned for failure. + */ + bool getName(char* name, size_t size); + /** + * Get a file's Short File Name followed by a zero byte. + * + * \param[out] name An array of characters for the file's name. + * The array must be at least 13 bytes long. + * \return The value true, is returned for success and + * the value false, is returned for failure. + */ + bool getSFN(char* name); + /** \return True if this is a directory else false. */ + bool isDir() const { + return m_attr & FILE_ATTR_DIR; + } + /** \return True if this is a normal file else false. */ + bool isFile() const { + return m_attr & FILE_ATTR_FILE; + } + /** \return True if this is a hidden file else false. */ + bool isHidden() const { + return m_attr & FILE_ATTR_HIDDEN; + } + /** \return true if this file has a Long File Name. */ + bool isLFN() const { + return m_lfnOrd; + } + /** \return True if this is an open file/directory else false. */ + bool isOpen() const { + return m_attr; + } + /** \return True if this is the root directory. */ + bool isRoot() const { + return m_attr & FILE_ATTR_ROOT; + } + /** \return True if this is the FAT32 root directory. */ + bool isRoot32() const { + return m_attr & FILE_ATTR_ROOT32; + } + /** \return True if this is the FAT12 of FAT16 root directory. */ + bool isRootFixed() const { + return m_attr & FILE_ATTR_ROOT_FIXED; + } + /** \return True if file is read-only */ + bool isReadOnly() const { + return m_attr & FILE_ATTR_READ_ONLY; + } + /** \return True if this is a subdirectory else false. */ + bool isSubDir() const { + return m_attr & FILE_ATTR_SUBDIR; + } + /** \return True if this is a system file else false. */ + bool isSystem() const { + return m_attr & FILE_ATTR_SYSTEM; + } + /** Check for a legal 8.3 character. + * \param[in] c Character to be checked. + * \return true for a legal 8.3 character else false. + */ + static bool legal83Char(uint8_t c) { + if (c == '"' || c == '|') { + return false; + } + // *+,./ + if (0X2A <= c && c <= 0X2F && c != 0X2D) { + return false; + } + // :;<=>? + if (0X3A <= c && c <= 0X3F) { + return false; + } + // [\] + if (0X5B <= c && c <= 0X5D) { + return false; + } + return 0X20 < c && c < 0X7F; + } + /** List directory contents. + * + * \param[in] pr Print stream for list. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + * + * \param[in] indent Amount of space before file name. Used for recursive + * list to indicate subdirectory level. + */ + void ls(print_t* pr, uint8_t flags = 0, uint8_t indent = 0); + /** Make a new directory. + * + * \param[in] dir An open FatFile instance for the directory that will + * contain the new directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the new directory. + * + * \param[in] pFlag Create missing parent directories if true. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool mkdir(FatFile* dir, const char* path, bool pFlag = true); + /** Open a file in the volume working directory of a FatFileSystem. + * + * \param[in] fs File System where the file is located. + * + * \param[in] path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag bitwise-inclusive OR of open mode flags. + * See see FatFile::open(FatFile*, const char*, uint8_t). + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool open(FatFileSystem* fs, const char* path, uint8_t oflag); + /** Open a file by index. + * + * \param[in] dirFile An open FatFile instance for the directory. + * + * \param[in] index The \a index of the directory entry for the file to be + * opened. The value for \a index is (directory file position)/32. + * + * \param[in] oflag bitwise-inclusive OR of open mode flags. + * See see FatFile::open(FatFile*, const char*, uint8_t). + * + * See open() by path for definition of flags. + * \return true for success or false for failure. + */ + bool open(FatFile* dirFile, uint16_t index, uint8_t oflag); + /** Open a file or directory by name. + * + * \param[in] dirFile An open FatFile instance for the directory containing + * the file to be opened. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a + * bitwise-inclusive OR of flags from the following list + * + * O_READ - Open for reading. + * + * O_RDONLY - Same as O_READ. + * + * O_WRITE - Open for writing. + * + * O_WRONLY - Same as O_WRITE. + * + * O_RDWR - Open for reading and writing. + * + * O_APPEND - If set, the file offset shall be set to the end of the + * file prior to each write. + * + * O_AT_END - Set the initial position at the end of the file. + * + * O_CREAT - If the file exists, this flag has no effect except as noted + * under O_EXCL below. Otherwise, the file shall be created + * + * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists. + * + * O_SYNC - Call sync() after each write. This flag should not be used with + * write(uint8_t) or any functions do character at a time writes since sync() + * will be called after each byte. + * + * O_TRUNC - If the file exists and is a regular file, and the file is + * successfully opened and is not read only, its length shall be truncated to 0. + * + * WARNING: A given file must not be opened by more than one FatFile object + * or file corruption may occur. + * + * \note Directory files must be opened read only. Write and truncation is + * not allowed for directory files. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool open(FatFile* dirFile, const char* path, uint8_t oflag); + /** Open a file in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag bitwise-inclusive OR of open mode flags. + * See see FatFile::open(FatFile*, const char*, uint8_t). + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool open(const char* path, uint8_t oflag = O_READ) { + return open(m_cwd, path, oflag); + } + /** Open the next file or subdirectory in a directory. + * + * \param[in] dirFile An open FatFile instance for the directory + * containing the file to be opened. + * + * \param[in] oflag bitwise-inclusive OR of open mode flags. + * See see FatFile::open(FatFile*, const char*, uint8_t). + * + * \return true for success or false for failure. + */ + bool openNext(FatFile* dirFile, uint8_t oflag = O_READ); + /** Open a volume's root directory. + * + * \param[in] vol The FAT volume containing the root directory to be opened. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool openRoot(FatVolume* vol); + /** Return the next available byte without consuming it. + * + * \return The byte if no error and not at eof else -1; + */ + int peek(); + /** Print a file's creation date and time + * + * \param[in] pr Print stream for output. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool printCreateDateTime(print_t* pr); + /** %Print a directory date field. + * + * Format is yyyy-mm-dd. + * + * \param[in] pr Print stream for output. + * \param[in] fatDate The date field from a directory entry. + */ + static void printFatDate(print_t* pr, uint16_t fatDate); + /** %Print a directory time field. + * + * Format is hh:mm:ss. + * + * \param[in] pr Print stream for output. + * \param[in] fatTime The time field from a directory entry. + */ + static void printFatTime(print_t* pr, uint16_t fatTime); + /** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. Use '\\n' for CR LF. + * \param[in] prec Number of digits after decimal point. + * \return The number of bytes written or -1 if an error occurs. + */ + int printField(float value, char term, uint8_t prec = 2); + /** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. Use '\\n' for CR LF. + * \return The number of bytes written or -1 if an error occurs. + */ + int printField(int16_t value, char term); + /** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. Use '\\n' for CR LF. + * \return The number of bytes written or -1 if an error occurs. + */ + int printField(uint16_t value, char term); + /** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. Use '\\n' for CR LF. + * \return The number of bytes written or -1 if an error occurs. + */ + int printField(int32_t value, char term); + /** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. Use '\\n' for CR LF. + * \return The number of bytes written or -1 if an error occurs. + */ + int printField(uint32_t value, char term); + /** Print a file's modify date and time + * + * \param[in] pr Print stream for output. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool printModifyDateTime(print_t* pr); + /** Print a file's name + * + * \param[in] pr Print stream for output. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + size_t printName(print_t* pr); + /** Print a file's size. + * + * \param[in] pr Print stream for output. + * + * \return The number of characters printed is returned + * for success and zero is returned for failure. + */ + size_t printFileSize(print_t* pr); + /** Print a file's Short File Name. + * + * \param[in] pr Print stream for output. + * + * \return The number of characters printed is returned + * for success and zero is returned for failure. + */ + size_t printSFN(print_t* pr); + /** Read the next byte from a file. + * + * \return For success read returns the next byte in the file as an int. + * If an error occurs or end of file is reached -1 is returned. + */ + int read() { + uint8_t b; + return read(&b, 1) == 1 ? b : -1; + } + /** Read data from a file starting at the current position. + * + * \param[out] buf Pointer to the location that will receive the data. + * + * \param[in] nbyte Maximum number of bytes to read. + * + * \return For success read() returns the number of bytes read. + * A value less than \a nbyte, including zero, will be returned + * if end of file is reached. + * If an error occurs, read() returns -1. Possible errors include + * read() called before a file has been opened, corrupt file system + * or an I/O error occurred. + */ + int read(void* buf, size_t nbyte); + /** Read the next directory entry from a directory file. + * + * \param[out] dir The dir_t struct that will receive the data. + * + * \return For success readDir() returns the number of bytes read. + * A value of zero will be returned if end of file is reached. + * If an error occurs, readDir() returns -1. Possible errors include + * readDir() called before a directory has been opened, this is not + * a directory file or an I/O error occurred. + */ + int8_t readDir(dir_t* dir); + /** Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool remove(); + /** Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \param[in] dirFile The directory that contains the file. + * \param[in] path Path for the file to be removed. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + static bool remove(FatFile* dirFile, const char* path); + /** Set the file's current position to zero. */ + void rewind() { + seekSet(0); + } + /** Rename a file or subdirectory. + * + * \param[in] dirFile Directory for the new path. + * \param[in] newPath New path name for the file/directory. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool rename(FatFile* dirFile, const char* newPath); + /** Remove a directory file. + * + * The directory file will be removed only if it is empty and is not the + * root directory. rmdir() follows DOS and Windows and ignores the + * read-only attribute for the directory. + * + * \note This function should not be used to delete the 8.3 version of a + * directory that has a long name. For example if a directory has the + * long name "New folder" you should not delete the 8.3 name "NEWFOL~1". + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool rmdir(); + /** Recursively delete a directory and all contained files. + * + * This is like the Unix/Linux 'rm -rf *' if called with the root directory + * hence the name. + * + * Warning - This will remove all contents of the directory including + * subdirectories. The directory will then be removed if it is not root. + * The read-only attribute for files will be ignored. + * + * \note This function should not be used to delete the 8.3 version of + * a directory that has a long name. See remove() and rmdir(). + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool rmRfStar(); + /** Set the files position to current position + \a pos. See seekSet(). + * \param[in] offset The new position in bytes from the current position. + * \return true for success or false for failure. + */ + bool seekCur(int32_t offset) { + return seekSet(m_curPosition + offset); + } + /** Set the files position to end-of-file + \a offset. See seekSet(). + * Can't be used for directory files since file size is not defined. + * \param[in] offset The new position in bytes from end-of-file. + * \return true for success or false for failure. + */ + bool seekEnd(int32_t offset = 0) { + return isFile() ? seekSet(m_fileSize + offset) : false; + } + /** Sets a file's position. + * + * \param[in] pos The new position in bytes from the beginning of the file. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool seekSet(uint32_t pos); + /** Set the current working directory. + * + * \param[in] dir New current working directory. + * + * \return true for success else false. + */ + static bool setCwd(FatFile* dir) { + if (!dir->isDir()) { + return false; + } + m_cwd = dir; + return true; + } + /** \return first block of file or zero for empty file. */ + uint32_t firstBlock() { + if (m_firstCluster) { + return m_vol->clusterFirstBlock(m_firstCluster); + } + return 0; + } + /** The sync() call causes all modified data and directory fields + * to be written to the storage device. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool sync(); + /** Copy a file's timestamps + * + * \param[in] file File to copy timestamps from. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool timestamp(FatFile* file); + /** Set a file's timestamps in its directory entry. + * + * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * T_ACCESS - Set the file's last access date. + * + * T_CREATE - Set the file's creation date and time. + * + * T_WRITE - Set the file's last write/modification date and time. + * + * \param[in] year Valid range 1980 - 2107 inclusive. + * + * \param[in] month Valid range 1 - 12 inclusive. + * + * \param[in] day Valid range 1 - 31 inclusive. + * + * \param[in] hour Valid range 0 - 23 inclusive. + * + * \param[in] minute Valid range 0 - 59 inclusive. + * + * \param[in] second Valid range 0 - 59 inclusive + * + * \note It is possible to set an invalid date since there is no check for + * the number of days in a month. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, + uint8_t hour, uint8_t minute, uint8_t second); + /** Type of file. You should use isFile() or isDir() instead of fileType() + * if possible. + * + * \return The file or directory type. + */ + uint8_t fileAttr() const { + return m_attr; + } + /** Truncate a file to a specified length. The current file position + * will be maintained if it is less than or equal to \a length otherwise + * it will be set to end of file. + * + * \param[in] length The desired length for the file. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool truncate(uint32_t length); + /** \return FatVolume that contains this file. */ + FatVolume* volume() const { + return m_vol; + } + /** Write a string to a file. Used by the Arduino Print class. + * \param[in] str Pointer to the string. + * Use getWriteError to check for errors. + * \return count of characters written for success or -1 for failure. + */ + int write(const char* str) { + return write(str, strlen(str)); + } + /** Write a single byte. + * \param[in] b The byte to be written. + * \return +1 for success or -1 for failure. + */ + int write(uint8_t b) { + return write(&b, 1); + } + /** Write data to an open file. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] nbyte Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \a nbyte. If an error occurs, write() returns -1. Possible errors + * include write() is called before a file has been opened, write is called + * for a read-only file, device is full, a corrupt file system or an I/O error. + * + */ + int write(const void* buf, size_t nbyte); +//------------------------------------------------------------------------------ + private: + /** This file has not been opened. */ + static const uint8_t FILE_ATTR_CLOSED = 0; + /** File is read-only. */ + static const uint8_t FILE_ATTR_READ_ONLY = DIR_ATT_READ_ONLY; + /** File should be hidden in directory listings. */ + static const uint8_t FILE_ATTR_HIDDEN = DIR_ATT_HIDDEN; + /** Entry is for a system file. */ + static const uint8_t FILE_ATTR_SYSTEM = DIR_ATT_SYSTEM; + /** Entry for normal data file */ + static const uint8_t FILE_ATTR_FILE = 0X08; + /** Entry is for a subdirectory */ + static const uint8_t FILE_ATTR_SUBDIR = DIR_ATT_DIRECTORY; + /** A FAT12 or FAT16 root directory */ + static const uint8_t FILE_ATTR_ROOT_FIXED = 0X20; + /** A FAT32 root directory */ + static const uint8_t FILE_ATTR_ROOT32 = 0X40; + /** Entry is for root. */ + static const uint8_t FILE_ATTR_ROOT = FILE_ATTR_ROOT_FIXED | FILE_ATTR_ROOT32; + /** Directory type bits */ + static const uint8_t FILE_ATTR_DIR = FILE_ATTR_SUBDIR | FILE_ATTR_ROOT; + /** Attributes to copy from directory entry */ + static const uint8_t FILE_ATTR_COPY = DIR_ATT_READ_ONLY | DIR_ATT_HIDDEN | + DIR_ATT_SYSTEM | DIR_ATT_DIRECTORY; + + /** experimental don't use */ + + bool openParent(FatFile* dir); + + // private functions + bool addCluster(); + bool addDirCluster(); + dir_t* cacheDirEntry(uint8_t action); + static uint8_t lfnChecksum(uint8_t* name); + bool lfnUniqueSfn(fname_t* fname); + bool openCluster(FatFile* file); + static bool parsePathName(const char* str, fname_t* fname, const char** ptr); + bool mkdir(FatFile* parent, fname_t* fname); + bool open(FatFile* dirFile, fname_t* fname, uint8_t oflag); + bool openCachedEntry(FatFile* dirFile, uint16_t cacheIndex, uint8_t oflag, + uint8_t lfnOrd); + bool readLBN(uint32_t* lbn); + dir_t* readDirCache(bool skipReadOk = false); + bool setDirSize(); + + // bits defined in m_flags + // should be 0X0F + static const uint8_t F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); + // sync of directory entry required + static const uint8_t F_FILE_DIR_DIRTY = 0X80; + + // global pointer to cwd dir + static FatFile* m_cwd; + // data time callback function + static void (*m_dateTime)(uint16_t* date, uint16_t* time); + // private data + static const uint8_t WRITE_ERROR = 0X1; + static const uint8_t READ_ERROR = 0X2; + uint8_t m_attr; // File attributes + uint8_t m_error; // Error bits. + uint8_t m_flags; // See above for definition of m_flags bits + uint8_t m_lfnOrd; + uint16_t m_dirIndex; // index of directory entry in dir file + FatVolume* m_vol; // volume where file is located + uint32_t m_dirCluster; + uint32_t m_curCluster; // cluster for current file position + uint32_t m_curPosition; // current file position + uint32_t m_dirBlock; // block for this files directory entry + uint32_t m_fileSize; // file size in bytes + uint32_t m_firstCluster; // first cluster of file +}; +#endif // FatFile_h diff --git a/libraries/SdFat/src/FatLib/FatFileLFN.cpp b/libraries/SdFat/src/FatLib/FatFileLFN.cpp new file mode 100644 index 0000000..5ab9f45 --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatFileLFN.cpp @@ -0,0 +1,683 @@ +/* FatLib Library + * Copyright (C) 2012 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#include "FatFile.h" +//------------------------------------------------------------------------------ +// +uint8_t FatFile::lfnChecksum(uint8_t* name) { + uint8_t sum = 0; + for (uint8_t i = 0; i < 11; i++) { + sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + name[i]; + } + return sum; +} +#if USE_LONG_FILE_NAMES +//------------------------------------------------------------------------------ +// Saves about 90 bytes of flash on 328 over tolower(). +inline char lfnToLower(char c) { + return 'A' <= c && c <= 'Z' ? c + 'a' - 'A' : c; +} +//------------------------------------------------------------------------------ +// Daniel Bernstein University of Illinois at Chicago. +// Original had + instead of ^ +static uint16_t Bernstein(uint16_t hash, const char *str, size_t len) { + for (size_t i = 0; i < len; i++) { + // hash = hash * 33 ^ str[i]; + hash = ((hash << 5) + hash) ^ str[i]; + } + return hash; +} +//------------------------------------------------------------------------------ +/** + * Fetch a 16-bit long file name character. + * + * \param[in] ldir Pointer to long file name directory entry. + * \param[in] i Index of character. + * \return The 16-bit character. + */ +static uint16_t lfnGetChar(ldir_t *ldir, uint8_t i) { + if (i < LDIR_NAME1_DIM) { + return ldir->name1[i]; + } else if (i < (LDIR_NAME1_DIM + LDIR_NAME2_DIM)) { + return ldir->name2[i - LDIR_NAME1_DIM]; + } else if (i < (LDIR_NAME1_DIM + LDIR_NAME2_DIM + LDIR_NAME2_DIM)) { + return ldir->name3[i - LDIR_NAME1_DIM - LDIR_NAME2_DIM]; + } + return 0; +} +//------------------------------------------------------------------------------ +static bool lfnGetName(ldir_t *ldir, char* name, size_t n) { + uint8_t i; + size_t k = 13*((ldir->ord & 0X1F) - 1); + for (i = 0; i < 13; i++) { + uint16_t c = lfnGetChar(ldir, i); + if (c == 0 || k >= n) { + break; + } + name[k++] = c >= 0X7F ? '?' : c; + } + // Terminate with zero byte if name fits. + if (k < n && (ldir->ord & LDIR_ORD_LAST_LONG_ENTRY)) { + name[k] = 0; + } + // Truncate if name is too long. + name[n - 1] = 0; + return true; +} +//------------------------------------------------------------------------------ +inline bool lfnLegalChar(char c) { + if (c == '/' || c == '\\' || c == '"' || c == '*' || + c == ':' || c == '<' || c == '>' || c == '?' || c == '|') { + return false; + } + return 0X1F < c && c < 0X7F; +} +//------------------------------------------------------------------------------ +/** + * Store a 16-bit long file name character. + * + * \param[in] ldir Pointer to long file name directory entry. + * \param[in] i Index of character. + * \param[in] c The 16-bit character. + */ +static void lfnPutChar(ldir_t *ldir, uint8_t i, uint16_t c) { + if (i < LDIR_NAME1_DIM) { + ldir->name1[i] = c; + } else if (i < (LDIR_NAME1_DIM + LDIR_NAME2_DIM)) { + ldir->name2[i - LDIR_NAME1_DIM] = c; + } else if (i < (LDIR_NAME1_DIM + LDIR_NAME2_DIM + LDIR_NAME2_DIM)) { + ldir->name3[i - LDIR_NAME1_DIM - LDIR_NAME2_DIM] = c; + } +} +//------------------------------------------------------------------------------ +static void lfnPutName(ldir_t *ldir, const char* name, size_t n) { + size_t k = 13*((ldir->ord & 0X1F) - 1); + for (uint8_t i = 0; i < 13; i++, k++) { + uint16_t c = k < n ? name[k] : k == n ? 0 : 0XFFFF; + lfnPutChar(ldir, i, c); + } +} +//============================================================================== +bool FatFile::getName(char* name, size_t size) { + FatFile dirFile; + ldir_t* ldir; + if (!isOpen() || size < 13) { + DBG_FAIL_MACRO; + goto fail; + } + if (!isLFN()) { + return getSFN(name); + } + if (!dirFile.openCluster(this)) { + DBG_FAIL_MACRO; + goto fail; + } + for (uint8_t ord = 1; ord <= m_lfnOrd; ord++) { + if (!dirFile.seekSet(32UL*(m_dirIndex - ord))) { + DBG_FAIL_MACRO; + goto fail; + } + ldir = reinterpret_cast(dirFile.readDirCache()); + if (!ldir) { + DBG_FAIL_MACRO; + goto fail; + } + if (ldir->attr != DIR_ATT_LONG_NAME) { + DBG_FAIL_MACRO; + goto fail; + } + if (ord != (ldir->ord & 0X1F)) { + DBG_FAIL_MACRO; + goto fail; + } + if (!lfnGetName(ldir, name, size)) { + DBG_FAIL_MACRO; + goto fail; + } + if (ldir->ord & LDIR_ORD_LAST_LONG_ENTRY) { + return true; + } + } + // Fall into fail. + DBG_FAIL_MACRO; + +fail: + name[0] = 0; + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::openCluster(FatFile* file) { + if (file->m_dirCluster == 0) { + return openRoot(file->m_vol); + } + memset(this, 0, sizeof(FatFile)); + m_attr = FILE_ATTR_SUBDIR; + m_flags = O_READ; + m_vol = file->m_vol; + m_firstCluster = file->m_dirCluster; + return true; +} +//------------------------------------------------------------------------------ +bool FatFile::parsePathName(const char* path, + fname_t* fname, const char** ptr) { + char c; + bool is83; + uint8_t bit = DIR_NT_LC_BASE; + uint8_t lc = 0; + uint8_t uc = 0; + uint8_t i = 0; + uint8_t in = 7; + int end; + int len = 0; + int si; + int dot; + + // Skip leading spaces. + while (*path == ' ') { + path++; + } + fname->lfn = path; + + for (len = 0; ; len++) { + c = path[len]; + if (c == 0 || isDirSeparator(c)) { + break; + } + if (!lfnLegalChar(c)) { + return false; + } + } + // Advance to next path component. + for (end = len; path[end] == ' ' || isDirSeparator(path[end]); end++) {} + *ptr = &path[end]; + + // Back over spaces and dots. + while (len) { + c = path[len - 1]; + if (c != '.' && c != ' ') { + break; + } + len--; + } + // Max length of LFN is 255. + if (len > 255) { + return false; + } + fname->len = len; + // Blank file short name. + for (uint8_t k = 0; k < 11; k++) { + fname->sfn[k] = ' '; + } + // skip leading spaces and dots. + for (si = 0; path[si] == '.' || path[si] == ' '; si++) {} + // Not 8.3 if leading dot or space. + is83 = !si; + + // find last dot. + for (dot = len - 1; dot >= 0 && path[dot] != '.'; dot--) {} + for (; si < len; si++) { + c = path[si]; + if (c == ' ' || (c == '.' && dot != si)) { + is83 = false; + continue; + } + if (!legal83Char(c) && si != dot) { + is83 = false; + c = '_'; + } + if (si == dot || i > in) { + if (in == 10) { + // Done - extension longer than three characters. + is83 = false; + break; + } + if (si != dot) { + is83 = false; + } + // Break if no dot and base-name is longer than eight characters. + if (si > dot) { + break; + } + si = dot; + in = 10; // Max index for full 8.3 name. + i = 8; // Place for extension. + bit = DIR_NT_LC_EXT; // bit for extension. + } else { + if ('a' <= c && c <= 'z') { + c += 'A' - 'a'; + lc |= bit; + } else if ('A' <= c && c <= 'Z') { + uc |= bit; + } + fname->sfn[i++] = c; + if (i < 7) { + fname->seqPos = i; + } + } + } + if (fname->sfn[0] == ' ') { + return false; + } + + if (is83) { + fname->flags = lc & uc ? FNAME_FLAG_MIXED_CASE : lc; + } else { + fname->flags = FNAME_FLAG_LOST_CHARS; + fname->sfn[fname->seqPos] = '~'; + fname->sfn[fname->seqPos + 1] = '1'; + } + return true; +} +//------------------------------------------------------------------------------ +bool FatFile::open(FatFile* dirFile, fname_t* fname, uint8_t oflag) { + bool fnameFound = false; + uint8_t lfnOrd = 0; + uint8_t freeNeed; + uint8_t freeFound = 0; + uint8_t ord = 0; + uint8_t chksum = 0; + uint16_t freeIndex = 0; + uint16_t curIndex; + dir_t* dir; + ldir_t* ldir; + size_t len = fname->len; + + if (!dirFile->isDir() || isOpen()) { + DBG_FAIL_MACRO; + goto fail; + } + // Number of directory entries needed. + freeNeed = fname->flags & FNAME_FLAG_NEED_LFN ? 1 + (len + 12)/13 : 1; + + dirFile->rewind(); + while (1) { + curIndex = dirFile->m_curPosition/32; + dir = dirFile->readDirCache(true); + if (!dir) { + if (dirFile->getError()) { + DBG_FAIL_MACRO; + goto fail; + } + // At EOF + goto create; + } + if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == DIR_NAME_FREE) { + if (freeFound == 0) { + freeIndex = curIndex; + } + if (freeFound < freeNeed) { + freeFound++; + } + if (dir->name[0] == DIR_NAME_FREE) { + goto create; + } + } else { + if (freeFound < freeNeed) { + freeFound = 0; + } + } + // skip empty slot or '.' or '..' + if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') { + lfnOrd = 0; + } else if (DIR_IS_LONG_NAME(dir)) { + ldir_t *ldir = reinterpret_cast(dir); + if (!lfnOrd) { + if ((ldir->ord & LDIR_ORD_LAST_LONG_ENTRY) == 0) { + continue; + } + lfnOrd = ord = ldir->ord & 0X1F; + chksum = ldir->chksum; + } else if (ldir->ord != --ord || chksum != ldir->chksum) { + lfnOrd = 0; + continue; + } + size_t k = 13*(ord - 1); + if (k >= len) { + // Not found. + lfnOrd = 0; + continue; + } + for (uint8_t i = 0; i < 13; i++) { + uint16_t u = lfnGetChar(ldir, i); + if (k == len) { + if (u != 0) { + // Not found. + lfnOrd = 0; + } + break; + } + if (u > 255 || lfnToLower(u) != lfnToLower(fname->lfn[k++])) { + // Not found. + lfnOrd = 0; + break; + } + } + } else if (DIR_IS_FILE_OR_SUBDIR(dir)) { + if (lfnOrd) { + if (1 == ord && lfnChecksum(dir->name) == chksum) { + goto found; + } + DBG_FAIL_MACRO; + goto fail; + } + if (!memcmp(dir->name, fname->sfn, sizeof(fname->sfn))) { + if (!(fname->flags & FNAME_FLAG_LOST_CHARS)) { + goto found; + } + fnameFound = true; + } + } else { + lfnOrd = 0; + } + } + +found: + // Don't open if create only. + if (oflag & O_EXCL) { + DBG_FAIL_MACRO; + goto fail; + } + goto open; + +create: + // don't create unless O_CREAT and O_WRITE + if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + // If at EOF start in next cluster. + if (freeFound == 0) { + freeIndex = curIndex; + } + + while (freeFound < freeNeed) { + dir = dirFile->readDirCache(); + if (!dir) { + if (dirFile->getError()) { + DBG_FAIL_MACRO; + goto fail; + } + // EOF if no error. + break; + } + freeFound++; + } + while (freeFound < freeNeed) { + // Will fail if FAT16 root. + if (!dirFile->addDirCluster()) { + DBG_FAIL_MACRO; + goto fail; + } + // Done if more than one block per cluster. Max freeNeed is 21. + if (dirFile->m_vol->blocksPerCluster() > 1) { + break; + } + freeFound += 16; + } + if (fnameFound) { + if (!dirFile->lfnUniqueSfn(fname)) { + goto fail; + } + } + if (!dirFile->seekSet(32UL*freeIndex)) { + DBG_FAIL_MACRO; + goto fail; + } + lfnOrd = freeNeed - 1; + for (uint8_t ord = lfnOrd ; ord ; ord--) { + ldir = reinterpret_cast(dirFile->readDirCache()); + if (!ldir) { + DBG_FAIL_MACRO; + goto fail; + } + dirFile->m_vol->cacheDirty(); + ldir->ord = ord == lfnOrd ? LDIR_ORD_LAST_LONG_ENTRY | ord : ord; + ldir->attr = DIR_ATT_LONG_NAME; + ldir->type = 0; + ldir->chksum = lfnChecksum(fname->sfn); + ldir->mustBeZero = 0; + lfnPutName(ldir, fname->lfn, len); + } + curIndex = dirFile->m_curPosition/32; + dir = dirFile->readDirCache(); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + // initialize as empty file + memset(dir, 0, sizeof(dir_t)); + memcpy(dir->name, fname->sfn, 11); + + // Set base-name and extension lower case bits. + dir->reservedNT = (DIR_NT_LC_BASE | DIR_NT_LC_EXT) & fname->flags; + + // set timestamps + if (m_dateTime) { + // call user date/time function + m_dateTime(&dir->creationDate, &dir->creationTime); + } else { + // use default date/time + dir->creationDate = FAT_DEFAULT_DATE; + dir->creationTime = FAT_DEFAULT_TIME; + } + dir->lastAccessDate = dir->creationDate; + dir->lastWriteDate = dir->creationDate; + dir->lastWriteTime = dir->creationTime; + + // Force write of entry to device. + dirFile->m_vol->cacheDirty(); + +open: + // open entry in cache. + if (!openCachedEntry(dirFile, curIndex, oflag, lfnOrd)) { + DBG_FAIL_MACRO; + goto fail; + } + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +size_t FatFile::printName(print_t* pr) { + FatFile dirFile; + uint16_t u; + size_t n = 0; + ldir_t* ldir; + + if (!isLFN()) { + return printSFN(pr); + } + if (!dirFile.openCluster(this)) { + DBG_FAIL_MACRO; + goto fail; + } + for (uint8_t ord = 1; ord <= m_lfnOrd; ord++) { + if (!dirFile.seekSet(32UL*(m_dirIndex - ord))) { + DBG_FAIL_MACRO; + goto fail; + } + ldir = reinterpret_cast(dirFile.readDirCache()); + if (!ldir) { + DBG_FAIL_MACRO; + goto fail; + } + if (ldir->attr != DIR_ATT_LONG_NAME || + ord != (ldir->ord & 0X1F)) { + DBG_FAIL_MACRO; + goto fail; + } + for (uint8_t i = 0; i < 13; i++) { + u = lfnGetChar(ldir, i); + if (u == 0) { + // End of name. + break; + } + if (u > 0X7E) { + u = '?'; + } + pr->write(static_cast(u)); + n++; + } + if (ldir->ord & LDIR_ORD_LAST_LONG_ENTRY) { + return n; + } + } + // Fall into fail; + DBG_FAIL_MACRO; + +fail: + return 0; +} +//------------------------------------------------------------------------------ +bool FatFile::remove() { + bool last; + uint8_t chksum; + uint8_t ord; + FatFile dirFile; + dir_t* dir; + ldir_t* ldir; + + // Cant' remove not open for write. + if (!isFile() || !(m_flags & O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + // Free any clusters. + if (m_firstCluster && !m_vol->freeChain(m_firstCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + // Cache directory entry. + dir = cacheDirEntry(FatCache::CACHE_FOR_WRITE); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + chksum = lfnChecksum(dir->name); + + // Mark entry deleted. + dir->name[0] = DIR_NAME_DELETED; + + // Set this file closed. + m_attr = FILE_ATTR_CLOSED; + + // Write entry to device. + if (!m_vol->cacheSync()) { + DBG_FAIL_MACRO; + goto fail; + } + if (!isLFN()) { + // Done, no LFN entries. + return true; + } + if (!dirFile.openCluster(this)) { + DBG_FAIL_MACRO; + goto fail; + } + for (ord = 1; ord <= m_lfnOrd; ord++) { + if (!dirFile.seekSet(32UL*(m_dirIndex - ord))) { + DBG_FAIL_MACRO; + goto fail; + } + ldir = reinterpret_cast(dirFile.readDirCache()); + if (!ldir) { + DBG_FAIL_MACRO; + goto fail; + } + if (ldir->attr != DIR_ATT_LONG_NAME || + ord != (ldir->ord & 0X1F) || + chksum != ldir->chksum) { + DBG_FAIL_MACRO; + goto fail; + } + last = ldir->ord & LDIR_ORD_LAST_LONG_ENTRY; + ldir->ord = DIR_NAME_DELETED; + m_vol->cacheDirty(); + if (last) { + if (!m_vol->cacheSync()) { + DBG_FAIL_MACRO; + goto fail; + } + return true; + } + } + // Fall into fail. + DBG_FAIL_MACRO; + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatFile::lfnUniqueSfn(fname_t* fname) { + const uint8_t FIRST_HASH_SEQ = 2; // min value is 2 + uint8_t pos = fname->seqPos;; + dir_t *dir; + uint16_t hex; + + DBG_HALT_IF(!(fname->flags & FNAME_FLAG_LOST_CHARS)); + DBG_HALT_IF(fname->sfn[pos] != '~' && fname->sfn[pos + 1] != '1'); + + for (uint8_t seq = 2; seq < 100; seq++) { + if (seq < FIRST_HASH_SEQ) { + fname->sfn[pos + 1] = '0' + seq; + } else { + DBG_PRINT_IF(seq > FIRST_HASH_SEQ); + hex = Bernstein(seq + fname->len, fname->lfn, fname->len); + if (pos > 3) { + // Make space in name for ~HHHH. + pos = 3; + } + for (uint8_t i = pos + 4 ; i > pos; i--) { + uint8_t h = hex & 0XF; + fname->sfn[i] = h < 10 ? h + '0' : h + 'A' - 10; + hex >>= 4; + } + } + fname->sfn[pos] = '~'; + rewind(); + while (1) { + dir = readDirCache(true); + if (!dir) { + if (!getError()) { + // At EOF and name not found if no error. + goto done; + } + DBG_FAIL_MACRO; + goto fail; + } + if (dir->name[0] == DIR_NAME_FREE) { + goto done; + } + if (DIR_IS_FILE_OR_SUBDIR(dir) && !memcmp(fname->sfn, dir->name, 11)) { + // Name found - try another. + break; + } + } + } + // fall inti fail - too many tries. + DBG_FAIL_MACRO; + +fail: + return false; + +done: + return true; +} +#endif // #if USE_LONG_FILE_NAMES diff --git a/libraries/SdFat/src/FatLib/FatFilePrint.cpp b/libraries/SdFat/src/FatLib/FatFilePrint.cpp new file mode 100644 index 0000000..137ac7b --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatFilePrint.cpp @@ -0,0 +1,247 @@ +/* FatLib Library + * Copyright (C) 2012 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#include +#include "FatFile.h" +#include "FmtNumber.h" +//------------------------------------------------------------------------------ +// print uint8_t with width 2 +static void print2u(print_t* pr, uint8_t v) { + char c0 = '?'; + char c1 = '?'; + if (v < 100) { + c1 = v/10; + c0 = v - 10*c1 + '0'; + c1 += '0'; + } + pr->write(c1); + pr->write(c0); +} +//------------------------------------------------------------------------------ +static void printU32(print_t* pr, uint32_t v) { + char buf[11]; + char* ptr = buf + sizeof(buf); + *--ptr = 0; + pr->write(fmtDec(v, ptr)); +} +//------------------------------------------------------------------------------ +static void printHex(print_t* pr, uint8_t w, uint16_t h) { + char buf[5]; + char* ptr = buf + sizeof(buf); + *--ptr = 0; + for (uint8_t i = 0; i < w; i++) { + char c = h & 0XF; + *--ptr = c < 10 ? c + '0' : c + 'A' - 10; + h >>= 4; + } + pr->write(ptr); +} +//------------------------------------------------------------------------------ +void FatFile::dmpFile(print_t* pr, uint32_t pos, size_t n) { + char text[17]; + text[16] = 0; + if (n >= 0XFFF0) { + n = 0XFFF0; + } + if (!seekSet(pos)) { + return; + } + for (size_t i = 0; i <= n; i++) { + if ((i & 15) == 0) { + if (i) { + pr->write(' '); + pr->write(text); + if (i == n) { + break; + } + } + pr->write('\r'); + pr->write('\n'); + if (i >= n) { + break; + } + printHex(pr, 4, i); + pr->write(' '); + } + int16_t h = read(); + if (h < 0) { + break; + } + pr->write(' '); + printHex(pr, 2, h); + text[i&15] = ' ' <= h && h < 0X7F ? h : '.'; + } + pr->write('\r'); + pr->write('\n'); +} +//------------------------------------------------------------------------------ +void FatFile::ls(print_t* pr, uint8_t flags, uint8_t indent) { + FatFile file; + rewind(); + while (file.openNext(this, O_READ)) { + // indent for dir level + if (!file.isHidden() || (flags & LS_A)) { + for (uint8_t i = 0; i < indent; i++) { + pr->write(' '); + } + if (flags & LS_DATE) { + file.printModifyDateTime(pr); + pr->write(' '); + } + if (flags & LS_SIZE) { + file.printFileSize(pr); + pr->write(' '); + } + file.printName(pr); + if (file.isDir()) { + pr->write('/'); + } + pr->write('\r'); + pr->write('\n'); + if ((flags & LS_R) && file.isDir()) { + file.ls(pr, flags, indent + 2); + } + } + file.close(); + } +} +//------------------------------------------------------------------------------ +bool FatFile::printCreateDateTime(print_t* pr) { + dir_t dir; + if (!dirEntry(&dir)) { + DBG_FAIL_MACRO; + goto fail; + } + printFatDate(pr, dir.creationDate); + pr->write(' '); + printFatTime(pr, dir.creationTime); + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +void FatFile::printFatDate(print_t* pr, uint16_t fatDate) { + printU32(pr, FAT_YEAR(fatDate)); + pr->write('-'); + print2u(pr, FAT_MONTH(fatDate)); + pr->write('-'); + print2u(pr, FAT_DAY(fatDate)); +} +//------------------------------------------------------------------------------ +void FatFile::printFatTime(print_t* pr, uint16_t fatTime) { + print2u(pr, FAT_HOUR(fatTime)); + pr->write(':'); + print2u(pr, FAT_MINUTE(fatTime)); + pr->write(':'); + print2u(pr, FAT_SECOND(fatTime)); +} +//------------------------------------------------------------------------------ +/** Template for FatFile::printField() */ +template +static int printFieldT(FatFile* file, char sign, Type value, char term) { + char buf[3*sizeof(Type) + 3]; + char* str = &buf[sizeof(buf)]; + + if (term) { + *--str = term; + if (term == '\n') { + *--str = '\r'; + } + } +#ifdef OLD_FMT + do { + Type m = value; + value /= 10; + *--str = '0' + m - 10*value; + } while (value); +#else // OLD_FMT + str = fmtDec(value, str); +#endif // OLD_FMT + if (sign) { + *--str = sign; + } + return file->write(str, &buf[sizeof(buf)] - str); +} +//------------------------------------------------------------------------------ + +int FatFile::printField(float value, char term, uint8_t prec) { + char buf[24]; + char* str = &buf[sizeof(buf)]; + if (term) { + *--str = term; + if (term == '\n') { + *--str = '\r'; + } + } + str = fmtFloat(value, str, prec); + return write(str, buf + sizeof(buf) - str); +} +//------------------------------------------------------------------------------ +int FatFile::printField(uint16_t value, char term) { + return printFieldT(this, 0, value, term); +} +//------------------------------------------------------------------------------ +int FatFile::printField(int16_t value, char term) { + char sign = 0; + if (value < 0) { + sign = '-'; + value = -value; + } + return printFieldT(this, sign, (uint16_t)value, term); +} +//------------------------------------------------------------------------------ +int FatFile::printField(uint32_t value, char term) { + return printFieldT(this, 0, value, term); +} +//------------------------------------------------------------------------------ +int FatFile::printField(int32_t value, char term) { + char sign = 0; + if (value < 0) { + sign = '-'; + value = -value; + } + return printFieldT(this, sign, (uint32_t)value, term); +} +//------------------------------------------------------------------------------ +bool FatFile::printModifyDateTime(print_t* pr) { + dir_t dir; + if (!dirEntry(&dir)) { + DBG_FAIL_MACRO; + goto fail; + } + printFatDate(pr, dir.lastWriteDate); + pr->write(' '); + printFatTime(pr, dir.lastWriteTime); + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +size_t FatFile::printFileSize(print_t* pr) { + char buf[11]; + char *ptr = buf + sizeof(buf); + *--ptr = 0; + ptr = fmtDec(fileSize(), ptr); + while (ptr > buf) { + *--ptr = ' '; + } + return pr->write(buf); +} diff --git a/libraries/SdFat/src/FatLib/FatFileSFN.cpp b/libraries/SdFat/src/FatLib/FatFileSFN.cpp new file mode 100644 index 0000000..4b89f09 --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatFileSFN.cpp @@ -0,0 +1,273 @@ +/* FatLib Library + * Copyright (C) 2012 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#include "FatFile.h" +#include "FatFileSystem.h" +//------------------------------------------------------------------------------ +bool FatFile::getSFN(char* name) { + dir_t* dir; + if (!isOpen()) { + DBG_FAIL_MACRO; + goto fail; + } + if (isRoot()) { + name[0] = '/'; + name[1] = '\0'; + return true; + } + // cache entry + dir = cacheDirEntry(FatCache::CACHE_FOR_READ); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + // format name + dirName(dir, name); + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +size_t FatFile::printSFN(print_t* pr) { + char name[13]; + if (!getSFN(name)) { + DBG_FAIL_MACRO; + goto fail; + } + return pr->write(name); + +fail: + return 0; +} +#if !USE_LONG_FILE_NAMES +//------------------------------------------------------------------------------ +bool FatFile::getName(char* name, size_t size) { + return size < 13 ? 0 : getSFN(name); +} +//------------------------------------------------------------------------------ +// format directory name field from a 8.3 name string +bool FatFile::parsePathName(const char* path, fname_t* fname, + const char** ptr) { + uint8_t uc = 0; + uint8_t lc = 0; + uint8_t bit = FNAME_FLAG_LC_BASE; + // blank fill name and extension + for (uint8_t i = 0; i < 11; i++) { + fname->sfn[i] = ' '; + } + + for (uint8_t i = 0, n = 7;; path++) { + uint8_t c = *path; + if (c == 0 || isDirSeparator(c)) { + // Done. + break; + } + if (c == '.' && n == 7) { + n = 10; // max index for full 8.3 name + i = 8; // place for extension + + // bit for extension. + bit = FNAME_FLAG_LC_EXT; + } else { + if (!legal83Char(c) || i > n) { + DBG_FAIL_MACRO; + goto fail; + } + if ('a' <= c && c <= 'z') { + c += 'A' - 'a'; + lc |= bit; + } else if ('A' <= c && c <= 'Z') { + uc |= bit; + } + fname->sfn[i++] = c; + } + } + // must have a file name, extension is optional + if (fname->sfn[0] == ' ') { + DBG_FAIL_MACRO; + goto fail; + } + // Set base-name and extension bits. + fname->flags = lc & uc ? 0 : lc; + while (isDirSeparator(*path)) { + path++; + } + *ptr = path; + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +// open with filename in fname +#define SFN_OPEN_USES_CHKSUM 0 +bool FatFile::open(FatFile* dirFile, fname_t* fname, uint8_t oflag) { + bool emptyFound = false; +#if SFN_OPEN_USES_CHKSUM + uint8_t chksum; +#endif + uint8_t lfnOrd = 0; + uint16_t emptyIndex; + uint16_t index = 0; + dir_t* dir; + ldir_t* ldir; + + dirFile->rewind(); + while (1) { + if (!emptyFound) { + emptyIndex = index; + } + dir = dirFile->readDirCache(true); + if (!dir) { + if (dirFile->getError()) { + DBG_FAIL_MACRO; + goto fail; + } + // At EOF if no error. + break; + } + if (dir->name[0] == DIR_NAME_FREE) { + emptyFound = true; + break; + } + if (dir->name[0] == DIR_NAME_DELETED) { + lfnOrd = 0; + emptyFound = true; + } else if (DIR_IS_FILE_OR_SUBDIR(dir)) { + if (!memcmp(fname->sfn, dir->name, 11)) { + // don't open existing file if O_EXCL + if (oflag & O_EXCL) { + DBG_FAIL_MACRO; + goto fail; + } +#if SFN_OPEN_USES_CHKSUM + if (lfnOrd && chksum != lfnChecksum(dir->name)) { + DBG_FAIL_MACRO; + goto fail; + } +#endif // SFN_OPEN_USES_CHKSUM + if (!openCachedEntry(dirFile, index, oflag, lfnOrd)) { + DBG_FAIL_MACRO; + goto fail; + } + return true; + } else { + lfnOrd = 0; + } + } else if (DIR_IS_LONG_NAME(dir)) { + ldir = reinterpret_cast(dir); + if (ldir->ord & LDIR_ORD_LAST_LONG_ENTRY) { + lfnOrd = ldir->ord & 0X1F; +#if SFN_OPEN_USES_CHKSUM + chksum = ldir->chksum; +#endif // SFN_OPEN_USES_CHKSUM + } + } else { + lfnOrd = 0; + } + index++; + } + // don't create unless O_CREAT and O_WRITE + if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + if (emptyFound) { + index = emptyIndex; + } else { + if (!dirFile->addDirCluster()) { + DBG_FAIL_MACRO; + goto fail; + } + } + if (!dirFile->seekSet(32UL*index)) { + DBG_FAIL_MACRO; + goto fail; + } + dir = dirFile->readDirCache(); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + // initialize as empty file + memset(dir, 0, sizeof(dir_t)); + memcpy(dir->name, fname->sfn, 11); + + // Set base-name and extension lower case bits. + dir->reservedNT = (DIR_NT_LC_BASE | DIR_NT_LC_EXT) & fname->flags; + + // set timestamps + if (m_dateTime) { + // call user date/time function + m_dateTime(&dir->creationDate, &dir->creationTime); + } else { + // use default date/time + dir->creationDate = FAT_DEFAULT_DATE; + dir->creationTime = FAT_DEFAULT_TIME; + } + dir->lastAccessDate = dir->creationDate; + dir->lastWriteDate = dir->creationDate; + dir->lastWriteTime = dir->creationTime; + + // Force write of entry to device. + dirFile->m_vol->cacheDirty(); + + // open entry in cache. + return openCachedEntry(dirFile, index, oflag, 0); + +fail: + return false; +} +//------------------------------------------------------------------------------ +size_t FatFile::printName(print_t* pr) { + return printSFN(pr); +} +//------------------------------------------------------------------------------ +bool FatFile::remove() { + dir_t* dir; + // Can't remove if LFN or not open for write. + if (!isFile() || isLFN() || !(m_flags & O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + // Free any clusters. + if (m_firstCluster && !m_vol->freeChain(m_firstCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + // Cache directory entry. + dir = cacheDirEntry(FatCache::CACHE_FOR_WRITE); + if (!dir) { + DBG_FAIL_MACRO; + goto fail; + } + // Mark entry deleted. + dir->name[0] = DIR_NAME_DELETED; + + // Set this file closed. + m_attr = FILE_ATTR_CLOSED; + + // Write entry to device. + return m_vol->cacheSync(); + +fail: + return false; +} +#endif // !USE_LONG_FILE_NAMES diff --git a/libraries/SdFat/src/FatLib/FatFileSystem.h b/libraries/SdFat/src/FatLib/FatFileSystem.h new file mode 100644 index 0000000..16977b7 --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatFileSystem.h @@ -0,0 +1,321 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef FatFileSystem_h +#define FatFileSystem_h +#include "FatVolume.h" +#include "FatFile.h" +#include "ArduinoStream.h" +#include "ArduinoFiles.h" +/** + * \file + * \brief FatFileSystem class + */ +//------------------------------------------------------------------------------ +/** + * \class FatFileSystem + * \brief Integration class for the FatLib library. + */ +class FatFileSystem : public FatVolume { + public: + /** + * Initialize an FatFileSystem object. + * \param[in] blockDev Device block driver. + * \param[in] part partition to initialize. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool begin(BlockDriver* blockDev, uint8_t part = 0) { + m_blockDev = blockDev; + vwd()->close(); + return (part ? init(part) : init(1) || init(0)) + && vwd()->openRoot(this) && FatFile::setCwd(vwd()); + } +#if ENABLE_ARDUINO_FEATURES + /** List the directory contents of the volume working directory to Serial. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + */ + void ls(uint8_t flags = 0) { + ls(&Serial, flags); + } + /** List the directory contents of a directory to Serial. + * + * \param[in] path directory to list. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + */ + void ls(const char* path, uint8_t flags = 0) { + ls(&Serial, path, flags); + } + /** open a file + * + * \param[in] path location of file to be opened. + * \param[in] mode open mode flags. + * \return a File object. + */ + File open(const char *path, uint8_t mode = FILE_READ) { + File tmpFile; + tmpFile.open(vwd(), path, mode); + return tmpFile; + } + /** open a file + * + * \param[in] path location of file to be opened. + * \param[in] mode open mode flags. + * \return a File object. + */ + File open(const String &path, uint8_t mode = FILE_READ) { + return open(path.c_str(), mode ); + } +#endif // ENABLE_ARDUINO_FEATURES + /** Change a volume's working directory to root + * + * Changes the volume's working directory to the SD's root directory. + * Optionally set the current working directory to the volume's + * working directory. + * + * \param[in] set_cwd Set the current working directory to this volume's + * working directory if true. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool chdir(bool set_cwd = false) { + vwd()->close(); + return vwd()->openRoot(this) && (set_cwd ? FatFile::setCwd(vwd()) : true); + } + /** Change a volume's working directory + * + * Changes the volume working directory to the \a path subdirectory. + * Optionally set the current working directory to the volume's + * working directory. + * + * Example: If the volume's working directory is "/DIR", chdir("SUB") + * will change the volume's working directory from "/DIR" to "/DIR/SUB". + * + * If path is "/", the volume's working directory will be changed to the + * root directory + * + * \param[in] path The name of the subdirectory. + * + * \param[in] set_cwd Set the current working directory to this volume's + * working directory if true. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + //---------------------------------------------------------------------------- + bool chdir(const char *path, bool set_cwd = false) { + FatFile dir; + if (path[0] == '/' && path[1] == '\0') { + return chdir(set_cwd); + } + if (!dir.open(vwd(), path, O_READ)) { + goto fail; + } + if (!dir.isDir()) { + goto fail; + } + m_vwd = dir; + if (set_cwd) { + FatFile::setCwd(vwd()); + } + return true; + +fail: + return false; + } + //---------------------------------------------------------------------------- + /** Set the current working directory to a volume's working directory. + * + * This is useful with multiple SD cards. + * + * The current working directory is changed to this + * volume's working directory. + * + * This is like the Windows/DOS \: command. + */ + void chvol() { + FatFile::setCwd(vwd()); + } + //---------------------------------------------------------------------------- + /** + * Test for the existence of a file. + * + * \param[in] path Path of the file to be tested for. + * + * \return true if the file exists else false. + */ + bool exists(const char* path) { + return vwd()->exists(path); + } + //---------------------------------------------------------------------------- + /** List the directory contents of the volume working directory. + * + * \param[in] pr Print stream for list. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + */ + void ls(print_t* pr, uint8_t flags = 0) { + vwd()->ls(pr, flags); + } + //---------------------------------------------------------------------------- + /** List the directory contents of a directory. + * + * \param[in] pr Print stream for list. + * + * \param[in] path directory to list. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + */ + void ls(print_t* pr, const char* path, uint8_t flags) { + FatFile dir; + dir.open(vwd(), path, O_READ); + dir.ls(pr, flags); + } + //---------------------------------------------------------------------------- + /** Make a subdirectory in the volume working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the subdirectory. + * + * \param[in] pFlag Create missing parent directories if true. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool mkdir(const char* path, bool pFlag = true) { + FatFile sub; + return sub.mkdir(vwd(), path, pFlag); + } + //---------------------------------------------------------------------------- + /** Remove a file from the volume working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the file. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool remove(const char* path) { + return FatFile::remove(vwd(), path); + } + //---------------------------------------------------------------------------- + /** Rename a file or subdirectory. + * + * \param[in] oldPath Path name to the file or subdirectory to be renamed. + * + * \param[in] newPath New path name of the file or subdirectory. + * + * The \a newPath object must not exist before the rename call. + * + * The file to be renamed must not be open. The directory entry may be + * moved and file system corruption could occur if the file is accessed by + * a file object that was opened before the rename() call. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool rename(const char *oldPath, const char *newPath) { + FatFile file; + if (!file.open(vwd(), oldPath, O_READ)) { + return false; + } + return file.rename(vwd(), newPath); + } + //---------------------------------------------------------------------------- + /** Remove a subdirectory from the volume's working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the subdirectory. + * + * The subdirectory file will be removed only if it is empty. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool rmdir(const char* path) { + FatFile sub; + if (!sub.open(vwd(), path, O_READ)) { + return false; + } + return sub.rmdir(); + } + //---------------------------------------------------------------------------- + /** Truncate a file to a specified length. The current file position + * will be maintained if it is less than or equal to \a length otherwise + * it will be set to end of file. + * + * \param[in] path A path with a valid 8.3 DOS name for the file. + * \param[in] length The desired length for the file. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool truncate(const char* path, uint32_t length) { + FatFile file; + if (!file.open(vwd(), path, O_WRITE)) { + return false; + } + return file.truncate(length); + } + /** \return a pointer to the FatVolume object. */ + FatVolume* vol() { + return this; + } + /** \return a pointer to the volume working directory. */ + FatFile* vwd() { + return &m_vwd; + } + /** Wipe all data from the volume. You must reinitialize the volume before + * accessing it again. + * \param[in] pr print stream for status dots. + * \return true for success else false. + */ + bool wipe(print_t* pr = 0) { + vwd()->close(); + return FatVolume::wipe(pr); + } + + private: + FatFile m_vwd; +}; +#endif // FatFileSystem_h diff --git a/libraries/SdFat/src/FatLib/FatLib.h b/libraries/SdFat/src/FatLib/FatLib.h new file mode 100644 index 0000000..425a92b --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatLib.h @@ -0,0 +1,33 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef FatLib_h +#define FatLib_h +#include "ArduinoFiles.h" +#include "ArduinoStream.h" +#include "FatFileSystem.h" +#include "FatLibConfig.h" +#include "FatVolume.h" +#include "FatFile.h" +#include "StdioStream.h" +#include "fstream.h" +//------------------------------------------------------------------------------ +/** FatFileSystem version YYYYMMDD */ +#define FAT_LIB_VERSION 20150131 +#endif // FatLib_h diff --git a/libraries/SdFat/src/FatLib/FatLibConfig.h b/libraries/SdFat/src/FatLib/FatLibConfig.h new file mode 100644 index 0000000..736c62c --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatLibConfig.h @@ -0,0 +1,141 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +/** + * \file + * \brief configuration definitions + */ +#ifndef FatLibConfig_h +#define FatLibConfig_h +#include +// Allow this file to override defaults. +#include "SdFatConfig.h" + +#ifdef __AVR__ +#include +#endif // __AVR__ +//------------------------------------------------------------------------------ +/** + * Set USE_LONG_FILE_NAMES nonzero to use long file names (LFN). + * Long File Name are limited to a maximum length of 255 characters. + * + * This implementation allows 7-bit characters in the range + * 0X20 to 0X7E. The following characters are not allowed: + * + * < (less than) + * > (greater than) + * : (colon) + * " (double quote) + * / (forward slash) + * \ (backslash) + * | (vertical bar or pipe) + * ? (question mark) + * * (asterisk) + * + */ +#ifndef USE_LONG_FILE_NAMES +#define USE_LONG_FILE_NAMES 1 +#endif // USE_LONG_FILE_NAMES +//------------------------------------------------------------------------------ +/** + * Set USE_SEPARATE_FAT_CACHE non-zero to use a second 512 byte cache + * for FAT table entries. Improves performance for large writes that + * are not a multiple of 512 bytes. + */ +#ifndef USE_SEPARATE_FAT_CACHE +#ifdef __arm__ +#define USE_SEPARATE_FAT_CACHE 1 +#else // __arm__ +#define USE_SEPARATE_FAT_CACHE 0 +#endif // __arm__ +#endif // USE_SEPARATE_FAT_CACHE +//------------------------------------------------------------------------------ +/** + * Set USE_MULTI_BLOCK_IO non-zero to use multi-block SD read/write. + * + * Don't use mult-block read/write on small AVR boards. + */ +#ifndef USE_MULTI_BLOCK_IO +#if defined(RAMEND) && RAMEND < 3000 +#define USE_MULTI_BLOCK_IO 0 +#else // RAMEND +#define USE_MULTI_BLOCK_IO 1 +#endif // RAMEND +#endif // USE_MULTI_BLOCK_IO +//------------------------------------------------------------------------------ +/** + * Set MAINTAIN_FREE_CLUSTER_COUNT nonzero to keep the count of free clusters + * updated. This will increase the speed of the freeClusterCount() call + * after the first call. Extra flash will be required. + */ +#ifndef MAINTAIN_FREE_CLUSTER_COUNT +#define MAINTAIN_FREE_CLUSTER_COUNT 0 +#endif // MAINTAIN_FREE_CLUSTER_COUNT +//------------------------------------------------------------------------------ +/** + * Set DESTRUCTOR_CLOSES_FILE non-zero to close a file in its destructor. + * + * Causes use of lots of heap in ARM. + */ +#ifndef DESTRUCTOR_CLOSES_FILE +#define DESTRUCTOR_CLOSES_FILE 0 +#endif // DESTRUCTOR_CLOSES_FILE +//------------------------------------------------------------------------------ +/** + * Call flush for endl if ENDL_CALLS_FLUSH is non-zero + * + * The standard for iostreams is to call flush. This is very costly for + * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. + * + * SdFat has a single 512 byte buffer for I/O so it must write the current + * data block to the SD, read the directory block from the SD, update the + * directory entry, write the directory block to the SD and read the data + * block back into the buffer. + * + * The SD flash memory controller is not designed for this many rewrites + * so performance may be reduced by more than a factor of 100. + * + * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force + * all data to be written to the SD. + */ +#ifndef ENDL_CALLS_FLUSH +#define ENDL_CALLS_FLUSH 0 +#endif // ENDL_CALLS_FLUSH +//------------------------------------------------------------------------------ +/** + * Allow FAT12 volumes if FAT12_SUPPORT is non-zero. + * FAT12 has not been well tested. + */ +#ifndef FAT12_SUPPORT +#define FAT12_SUPPORT 0 +#endif // FAT12_SUPPORT +//------------------------------------------------------------------------------ +/** + * Enable Extra features for Arduino. + */ +// #define ENABLE_ARDUINO_FEATURES 0 ////////////////////////FIX THIS ///////////////// +#ifndef ENABLE_ARDUINO_FEATURES +#include +#if defined(ARDUINO) || defined(PLATFORM_ID) || defined(DOXYGEN) +#define ENABLE_ARDUINO_FEATURES 1 +#else // #if defined(ARDUINO) || defined(DOXYGEN) +#define ENABLE_ARDUINO_FEATURES 0 +#endif // defined(ARDUINO) || defined(DOXYGEN) +#endif // ENABLE_ARDUINO_FEATURES +#endif // FatLibConfig_h diff --git a/libraries/SdFat/src/FatLib/FatStructs.h b/libraries/SdFat/src/FatLib/FatStructs.h new file mode 100644 index 0000000..dd13db1 --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatStructs.h @@ -0,0 +1,877 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef FatStructs_h +#define FatStructs_h +/** + * \file + * \brief FAT file structures + */ +/* + * mostly from Microsoft document fatgen103.doc + * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + */ +//------------------------------------------------------------------------------ +/** Value for byte 510 of boot block or MBR */ +const uint8_t BOOTSIG0 = 0X55; +/** Value for byte 511 of boot block or MBR */ +const uint8_t BOOTSIG1 = 0XAA; +/** Value for bootSignature field int FAT/FAT32 boot sector */ +const uint8_t EXTENDED_BOOT_SIG = 0X29; +//------------------------------------------------------------------------------ +/** + * \struct partitionTable + * \brief MBR partition table entry + * + * A partition table entry for a MBR formatted storage device. + * The MBR partition table has four entries. + */ +struct partitionTable { + /** + * Boot Indicator . Indicates whether the volume is the active + * partition. Legal values include: 0X00. Do not use for booting. + * 0X80 Active partition. + */ + uint8_t boot; + /** + * Head part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t beginHead; + /** + * Sector part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + unsigned beginSector : 6; + /** High bits cylinder for first block in partition. */ + unsigned beginCylinderHigh : 2; + /** + * Combine beginCylinderLow with beginCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t beginCylinderLow; + /** + * Partition type. See defines that begin with PART_TYPE_ for + * some Microsoft partition types. + */ + uint8_t type; + /** + * head part of cylinder-head-sector address of the last sector in the + * partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t endHead; + /** + * Sector part of cylinder-head-sector address of the last sector in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + unsigned endSector : 6; + /** High bits of end cylinder */ + unsigned endCylinderHigh : 2; + /** + * Combine endCylinderLow with endCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t endCylinderLow; + /** Logical block address of the first block in the partition. */ + uint32_t firstSector; + /** Length of the partition, in blocks. */ + uint32_t totalSectors; +} __attribute__((packed)); +/** Type name for partitionTable */ +typedef struct partitionTable part_t; +//------------------------------------------------------------------------------ +/** + * \struct masterBootRecord + * + * \brief Master Boot Record + * + * The first block of a storage device that is formatted with a MBR. + */ +struct masterBootRecord { + /** Code Area for master boot program. */ + uint8_t codeArea[440]; + /** Optional Windows NT disk signature. May contain boot code. */ + uint32_t diskSignature; + /** Usually zero but may be more boot code. */ + uint16_t usuallyZero; + /** Partition tables. */ + part_t part[4]; + /** First MBR signature byte. Must be 0X55 */ + uint8_t mbrSig0; + /** Second MBR signature byte. Must be 0XAA */ + uint8_t mbrSig1; +} __attribute__((packed)); +/** Type name for masterBootRecord */ +typedef struct masterBootRecord mbr_t; +//------------------------------------------------------------------------------ +/** + * \struct biosParmBlock + * + * \brief BIOS parameter block + * + * The BIOS parameter block describes the physical layout of a FAT volume. + */ +struct biosParmBlock { + /** + * Count of bytes per sector. This value may take on only the + * following values: 512, 1024, 2048 or 4096 + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. + */ + uint8_t sectorsPerCluster; + /** + * Number of sectors before the first FAT. + * This value must not be zero. + */ + uint16_t reservedSectorCount; + /** The count of FAT data structures on the volume. This field should + * always contain the value 2 for any FAT volume of any type. + */ + uint8_t fatCount; + /** + * For FAT12 and FAT16 volumes, this field contains the count of + * 32-byte directory entries in the root directory. For FAT32 volumes, + * this field must be set to 0. For FAT12 and FAT16 volumes, this + * value should always specify a count that when multiplied by 32 + * results in a multiple of bytesPerSector. FAT16 volumes should + * use the value 512. + */ + uint16_t rootDirEntryCount; + /** + * This field is the old 16-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then totalSectors32 + * must be nonzero. For FAT32 volumes, this field must be 0. For + * FAT12 and FAT16 volumes, this field contains the sector count, and + * totalSectors32 is 0 if the total sector count fits + * (is less than 0x10000). + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrtack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * This field is the new 32-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then + * totalSectors16 must be nonzero. + */ + uint32_t totalSectors32; + /** + * Count of sectors occupied by one FAT on FAT32 volumes. + */ + uint32_t sectorsPerFat32; + /** + * This field is only defined for FAT32 media and does not exist on + * FAT12 and FAT16 media. + * Bits 0-3 -- Zero-based number of active FAT. + * Only valid if mirroring is disabled. + * Bits 4-6 -- Reserved. + * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. + * -- 1 means only one FAT is active; it is the one referenced in bits 0-3. + * Bits 8-15 -- Reserved. + */ + uint16_t fat32Flags; + /** + * FAT32 version. High byte is major revision number. + * Low byte is minor revision number. Only 0.0 define. + */ + uint16_t fat32Version; + /** + * Cluster number of the first cluster of the root directory for FAT32. + * This usually 2 but not required to be 2. + */ + uint32_t fat32RootCluster; + /** + * Sector number of FSINFO structure in the reserved area of the + * FAT32 volume. Usually 1. + */ + uint16_t fat32FSInfo; + /** + * If nonzero, indicates the sector number in the reserved area + * of the volume of a copy of the boot record. Usually 6. + * No value other than 6 is recommended. + */ + uint16_t fat32BackBootBlock; + /** + * Reserved for future expansion. Code that formats FAT32 volumes + * should always set all of the bytes of this field to 0. + */ + uint8_t fat32Reserved[12]; +} __attribute__((packed)); +/** Type name for biosParmBlock */ +typedef struct biosParmBlock bpb_t; +//------------------------------------------------------------------------------ +/** + * \struct fat_boot + * + * \brief Boot sector for a FAT12/FAT16 volume. + * + */ +struct fat_boot { + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next non-executable bytes. + */ + uint8_t jump[3]; + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ + char oemId[8]; + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ + uint8_t sectorsPerCluster; + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. The value of this field is always 1. + */ + uint16_t reservedSectorCount; + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ + uint8_t fatCount; + /** + * For FAT12 and FAT16 volumes, this field contains the count of + * 32-byte directory entries in the root directory. For FAT32 volumes, + * this field must be set to 0. For FAT12 and FAT16 volumes, this + * value should always specify a count that when multiplied by 32 + * results in a multiple of bytesPerSector. FAT16 volumes should + * use the value 512. + */ + uint16_t rootDirEntryCount; + /** + * This field is the old 16-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then totalSectors32 + * must be non-zero. For FAT32 volumes, this field must be 0. For + * FAT12 and FAT16 volumes, this field contains the sector count, and + * totalSectors32 is 0 if the total sector count fits + * (is less than 0x10000). + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (non-removable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * This field is the new 32-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then + * totalSectors16 must be non-zero. + */ + uint32_t totalSectors32; + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0X29 if next three fields are valid */ + uint8_t bootSignature; + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ + uint32_t volumeSerialNumber; + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ + char volumeLabel[11]; + /** + * A field with a value of either FAT, FAT12 or FAT16, + * depending on the disk format. + */ + char fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[448]; + /** must be 0X55 */ + uint8_t bootSectorSig0; + /** must be 0XAA */ + uint8_t bootSectorSig1; +} __attribute__((packed)); +/** Type name for FAT Boot Sector */ +typedef struct fat_boot fat_boot_t; +//------------------------------------------------------------------------------ +/** + * \struct fat32_boot + * + * \brief Boot sector for a FAT32 volume. + * + */ +struct fat32_boot { + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next non-executable bytes. + */ + uint8_t jump[3]; + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ + char oemId[8]; + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ + uint8_t sectorsPerCluster; + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. Must not be zero + */ + uint16_t reservedSectorCount; + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ + uint8_t fatCount; + /** + * FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0. + */ + uint16_t rootDirEntryCount; + /** + * For FAT32 volumes, this field must be 0. + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (non-removable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * Contains the total number of sectors in the FAT32 volume. + */ + uint32_t totalSectors32; + /** + * Count of sectors occupied by one FAT on FAT32 volumes. + */ + uint32_t sectorsPerFat32; + /** + * This field is only defined for FAT32 media and does not exist on + * FAT12 and FAT16 media. + * Bits 0-3 -- Zero-based number of active FAT. + * Only valid if mirroring is disabled. + * Bits 4-6 -- Reserved. + * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. + * -- 1 means only one FAT is active; it is the one referenced + * in bits 0-3. + * Bits 8-15 -- Reserved. + */ + uint16_t fat32Flags; + /** + * FAT32 version. High byte is major revision number. + * Low byte is minor revision number. Only 0.0 define. + */ + uint16_t fat32Version; + /** + * Cluster number of the first cluster of the root directory for FAT32. + * This usually 2 but not required to be 2. + */ + uint32_t fat32RootCluster; + /** + * Sector number of FSINFO structure in the reserved area of the + * FAT32 volume. Usually 1. + */ + uint16_t fat32FSInfo; + /** + * If non-zero, indicates the sector number in the reserved area + * of the volume of a copy of the boot record. Usually 6. + * No value other than 6 is recommended. + */ + uint16_t fat32BackBootBlock; + /** + * Reserved for future expansion. Code that formats FAT32 volumes + * should always set all of the bytes of this field to 0. + */ + uint8_t fat32Reserved[12]; + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0X29 if next three fields are valid */ + uint8_t bootSignature; + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ + uint32_t volumeSerialNumber; + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ + char volumeLabel[11]; + /** + * A text field with a value of FAT32. + */ + char fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[420]; + /** must be 0X55 */ + uint8_t bootSectorSig0; + /** must be 0XAA */ + uint8_t bootSectorSig1; +} __attribute__((packed)); +/** Type name for FAT32 Boot Sector */ +typedef struct fat32_boot fat32_boot_t; +//------------------------------------------------------------------------------ +/** Lead signature for a FSINFO sector */ +const uint32_t FSINFO_LEAD_SIG = 0x41615252; +/** Struct signature for a FSINFO sector */ +const uint32_t FSINFO_STRUCT_SIG = 0x61417272; +/** + * \struct fat32_fsinfo + * + * \brief FSINFO sector for a FAT32 volume. + * + */ +struct fat32_fsinfo { + /** must be 0X52, 0X52, 0X61, 0X41 */ + uint32_t leadSignature; + /** must be zero */ + uint8_t reserved1[480]; + /** must be 0X72, 0X72, 0X41, 0X61 */ + uint32_t structSignature; + /** + * Contains the last known free cluster count on the volume. + * If the value is 0xFFFFFFFF, then the free count is unknown + * and must be computed. Any other value can be used, but is + * not necessarily correct. It should be range checked at least + * to make sure it is <= volume cluster count. + */ + uint32_t freeCount; + /** + * This is a hint for the FAT driver. It indicates the cluster + * number at which the driver should start looking for free clusters. + * If the value is 0xFFFFFFFF, then there is no hint and the driver + * should start looking at cluster 2. + */ + uint32_t nextFree; + /** must be zero */ + uint8_t reserved2[12]; + /** must be 0X00, 0X00, 0X55, 0XAA */ + uint8_t tailSignature[4]; +} __attribute__((packed)); +/** Type name for FAT32 FSINFO Sector */ +typedef struct fat32_fsinfo fat32_fsinfo_t; +//------------------------------------------------------------------------------ +// End Of Chain values for FAT entries +/** FAT12 end of chain value used by Microsoft. */ +const uint16_t FAT12EOC = 0XFFF; +/** Minimum value for FAT12 EOC. Use to test for EOC. */ +const uint16_t FAT12EOC_MIN = 0XFF8; +/** FAT16 end of chain value used by Microsoft. */ +const uint16_t FAT16EOC = 0XFFFF; +/** Minimum value for FAT16 EOC. Use to test for EOC. */ +const uint16_t FAT16EOC_MIN = 0XFFF8; +/** FAT32 end of chain value used by Microsoft. */ +const uint32_t FAT32EOC = 0X0FFFFFFF; +/** Minimum value for FAT32 EOC. Use to test for EOC. */ +const uint32_t FAT32EOC_MIN = 0X0FFFFFF8; +/** Mask a for FAT32 entry. Entries are 28 bits. */ +const uint32_t FAT32MASK = 0X0FFFFFFF; +//------------------------------------------------------------------------------ +/** + * \struct directoryEntry + * \brief FAT short directory entry + * + * Short means short 8.3 name, not the entry size. + * + * Date Format. A FAT directory entry date stamp is a 16-bit field that is + * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the + * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the + * 16-bit word): + * + * Bits 9-15: Count of years from 1980, valid value range 0-127 + * inclusive (1980-2107). + * + * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. + * + * Bits 0-4: Day of month, valid value range 1-31 inclusive. + * + * Time Format. A FAT directory entry time stamp is a 16-bit field that has + * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the + * 16-bit word, bit 15 is the MSB of the 16-bit word). + * + * Bits 11-15: Hours, valid value range 0-23 inclusive. + * + * Bits 5-10: Minutes, valid value range 0-59 inclusive. + * + * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). + * + * The valid time range is from Midnight 00:00:00 to 23:59:58. + */ +struct directoryEntry { + /** Short 8.3 name. + * + * The first eight bytes contain the file name with blank fill. + * The last three bytes contain the file extension with blank fill. + */ + uint8_t name[11]; + /** Entry attributes. + * + * The upper two bits of the attribute byte are reserved and should + * always be set to 0 when a file is created and never modified or + * looked at after that. See defines that begin with DIR_ATT_. + */ + uint8_t attributes; + /** + * Reserved for use by Windows NT. Set value to 0 when a file is + * created and never modify or look at it after that. + */ + uint8_t reservedNT; + /** + * The granularity of the seconds part of creationTime is 2 seconds + * so this field is a count of tenths of a second and its valid + * value range is 0-199 inclusive. (WHG note - seems to be hundredths) + */ + uint8_t creationTimeTenths; + /** Time file was created. */ + uint16_t creationTime; + /** Date file was created. */ + uint16_t creationDate; + /** + * Last access date. Note that there is no last access time, only + * a date. This is the date of last read or write. In the case of + * a write, this should be set to the same date as lastWriteDate. + */ + uint16_t lastAccessDate; + /** + * High word of this entry's first cluster number (always 0 for a + * FAT12 or FAT16 volume). + */ + uint16_t firstClusterHigh; + /** Time of last write. File creation is considered a write. */ + uint16_t lastWriteTime; + /** Date of last write. File creation is considered a write. */ + uint16_t lastWriteDate; + /** Low word of this entry's first cluster number. */ + uint16_t firstClusterLow; + /** 32-bit unsigned holding this file's size in bytes. */ + uint32_t fileSize; +} __attribute__((packed)); +/** Type name for directoryEntry */ +typedef struct directoryEntry dir_t; +//------------------------------------------------------------------------------ +// Definitions for directory entries +// +/** escape for name[0] = 0XE5 */ +const uint8_t DIR_NAME_0XE5 = 0X05; +/** name[0] value for entry that is free after being "deleted" */ +const uint8_t DIR_NAME_DELETED = 0XE5; +/** name[0] value for entry that is free and no allocated entries follow */ +const uint8_t DIR_NAME_FREE = 0X00; +/** file is read-only */ +const uint8_t DIR_ATT_READ_ONLY = 0X01; +/** File should e hidden in directory listings */ +const uint8_t DIR_ATT_HIDDEN = 0X02; +/** Entry is for a system file */ +const uint8_t DIR_ATT_SYSTEM = 0X04; +/** Directory entry contains the volume label */ +const uint8_t DIR_ATT_VOLUME_ID = 0X08; +/** Entry is for a directory */ +const uint8_t DIR_ATT_DIRECTORY = 0X10; +/** Old DOS archive bit for backup support */ +const uint8_t DIR_ATT_ARCHIVE = 0X20; +/** Test value for long name entry. Test is + (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ +const uint8_t DIR_ATT_LONG_NAME = 0X0F; +/** Test mask for long name entry */ +const uint8_t DIR_ATT_LONG_NAME_MASK = 0X3F; +/** defined attribute bits */ +const uint8_t DIR_ATT_DEFINED_BITS = 0X3F; + +/** Mask for file/subdirectory tests */ +const uint8_t DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); + +/** Filename base-name is all lower case */ +const uint8_t DIR_NT_LC_BASE = 0X08; +/** Filename extension is all lower case.*/ +const uint8_t DIR_NT_LC_EXT = 0X10; + + +/** Directory entry is for a file + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a normal file else false. + */ +static inline uint8_t DIR_IS_FILE(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; +} +/** Directory entry is for a file or subdirectory + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a normal file or subdirectory else false. + */ +static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; +} +/** Directory entry is part of a long name + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for part of a long name else false. + */ +static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { + return dir->attributes == DIR_ATT_LONG_NAME; +} +/** Directory entry is hidden + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is hidden else false. + */ +static inline uint8_t DIR_IS_HIDDEN(const dir_t* dir) { + return dir->attributes & DIR_ATT_HIDDEN; +} +/** Directory entry is for a subdirectory + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a subdirectory else false. + */ +static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; +} +/** Directory entry is system type + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is system else false. + */ +static inline uint8_t DIR_IS_SYSTEM(const dir_t* dir) { + return dir->attributes & DIR_ATT_SYSTEM; +} +/** date field for FAT directory entry + * \param[in] year [1980,2107] + * \param[in] month [1,12] + * \param[in] day [1,31] + * + * \return Packed date for dir_t entry. + */ +static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { + return (year - 1980) << 9 | month << 5 | day; +} +/** year part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted year [1980,2107] + */ +static inline uint16_t FAT_YEAR(uint16_t fatDate) { + return 1980 + (fatDate >> 9); +} +/** month part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted month [1,12] + */ +static inline uint8_t FAT_MONTH(uint16_t fatDate) { + return (fatDate >> 5) & 0XF; +} +/** day part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted day [1,31] + */ +static inline uint8_t FAT_DAY(uint16_t fatDate) { + return fatDate & 0X1F; +} +/** time field for FAT directory entry + * \param[in] hour [0,23] + * \param[in] minute [0,59] + * \param[in] second [0,59] + * + * \return Packed time for dir_t entry. + */ +static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { + return hour << 11 | minute << 5 | second >> 1; +} +/** hour part of FAT directory time field + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted hour [0,23] + */ +static inline uint8_t FAT_HOUR(uint16_t fatTime) { + return fatTime >> 11; +} +/** minute part of FAT directory time field + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted minute [0,59] + */ +static inline uint8_t FAT_MINUTE(uint16_t fatTime) { + return (fatTime >> 5) & 0X3F; +} +/** second part of FAT directory time field + * Note second/2 is stored in packed time. + * + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted second [0,58] + */ +static inline uint8_t FAT_SECOND(uint16_t fatTime) { + return 2*(fatTime & 0X1F); +} +/** Default date for file timestamps is 1 Jan 2000 */ +const uint16_t FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; +/** Default time for file timestamp is 1 am */ +const uint16_t FAT_DEFAULT_TIME = (1 << 11); +//------------------------------------------------------------------------------ +/** Dimension of first name field in long directory entry */ +const uint8_t LDIR_NAME1_DIM = 5; +/** Dimension of first name field in long directory entry */ +const uint8_t LDIR_NAME2_DIM = 6; +/** Dimension of first name field in long directory entry */ +const uint8_t LDIR_NAME3_DIM = 2; +/** + * \struct longDirectoryEntry + * \brief FAT long directory entry + */ +struct longDirectoryEntry { + /** + * The order of this entry in the sequence of long dir entries + * associated with the short dir entry at the end of the long dir set. + * + * If masked with 0X40 (LAST_LONG_ENTRY), this indicates the + * entry is the last long dir entry in a set of long dir entries. + * All valid sets of long dir entries must begin with an entry having + * this mask. + */ + uint8_t ord; + /** Characters 1-5 of the long-name sub-component in this entry. */ + uint16_t name1[LDIR_NAME1_DIM]; + /** Attributes - must be ATTR_LONG_NAME */ + uint8_t attr; + /** + * If zero, indicates a directory entry that is a sub-component of a + * long name. NOTE: Other values reserved for future extensions. + * + * Non-zero implies other directory entry types. + */ + uint8_t type; + /** + * Checksum of name in the short dir entry at the end of the + * long dir set. + */ + uint8_t chksum; + /** Characters 6-11 of the long-name sub-component in this entry. */ + uint16_t name2[LDIR_NAME2_DIM]; + /** Must be ZERO. This is an artifact of the FAT "first cluster" */ + uint16_t mustBeZero; + /** Characters 12 and 13 of the long-name sub-component in this entry. */ + uint16_t name3[LDIR_NAME3_DIM]; +} __attribute__((packed)); +/** Type name for longDirectoryEntry */ +typedef struct longDirectoryEntry ldir_t; +/** + * Ord mast that indicates the entry is the last long dir entry in a + * set of long dir entries. All valid sets of long dir entries must + * begin with an entry having this mask. + */ +const uint8_t LDIR_ORD_LAST_LONG_ENTRY = 0X40; +#endif // FatStructs_h diff --git a/libraries/SdFat/src/FatLib/FatVolume.cpp b/libraries/SdFat/src/FatLib/FatVolume.cpp new file mode 100644 index 0000000..ea01af5 --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatVolume.cpp @@ -0,0 +1,596 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#include +#include "FatVolume.h" +//------------------------------------------------------------------------------ +cache_t* FatCache::read(uint32_t lbn, uint8_t option) { + if (m_lbn != lbn) { + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + if (!(option & CACHE_OPTION_NO_READ)) { + if (!m_vol->readBlock(lbn, m_block.data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + m_status = 0; + m_lbn = lbn; + } + m_status |= option & CACHE_STATUS_MASK; + return &m_block; + +fail: + + return 0; +} +//------------------------------------------------------------------------------ +bool FatCache::sync() { + if (m_status & CACHE_STATUS_DIRTY) { + if (!m_vol->writeBlock(m_lbn, m_block.data)) { + DBG_FAIL_MACRO; + goto fail; + } + // mirror second FAT + if (m_status & CACHE_STATUS_MIRROR_FAT) { + uint32_t lbn = m_lbn + m_vol->blocksPerFat(); + if (!m_vol->writeBlock(lbn, m_block.data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + m_status &= ~CACHE_STATUS_DIRTY; + } + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatVolume::allocateCluster(uint32_t current, uint32_t* next) { + uint32_t find = current ? current : m_allocSearchStart; + uint32_t start = find; + while (1) { + find++; + // If at end of FAT go to beginning of FAT. + if (find > m_lastCluster) { + find = 2; + } + uint32_t f; + int8_t fg = fatGet(find, &f); + if (fg < 0) { + DBG_FAIL_MACRO; + goto fail; + } + if (fg && f == 0) { + break; + } + if (find == start) { + // Can't find space checked all clusters. + DBG_FAIL_MACRO; + goto fail; + } + } + // mark end of chain + if (!fatPutEOC(find)) { + DBG_FAIL_MACRO; + goto fail; + } + if (current) { + // link clusters + if (!fatPut(current, find)) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + // Remember place for search start. + m_allocSearchStart = find; + } + updateFreeClusterCount(-1); + *next = find; + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +// find a contiguous group of clusters +bool FatVolume::allocContiguous(uint32_t count, uint32_t* firstCluster) { + // flag to save place to start next search + bool setStart = true; + // start of group + uint32_t bgnCluster; + // end of group + uint32_t endCluster; + // Start at cluster after last allocated cluster. + uint32_t startCluster = m_allocSearchStart; + endCluster = bgnCluster = startCluster + 1; + + // search the FAT for free clusters + while (1) { + // If past end - start from beginning of FAT. + if (endCluster > m_lastCluster) { + bgnCluster = endCluster = 2; + } + uint32_t f; + int8_t fg = fatGet(endCluster, &f); + if (fg < 0) { + DBG_FAIL_MACRO; + goto fail; + } + if (f || fg == 0) { + // cluster in use try next cluster as bgnCluster + bgnCluster = endCluster + 1; + + // don't update search start if unallocated clusters before endCluster. + if (bgnCluster != endCluster) { + setStart = false; + } + } else if ((endCluster - bgnCluster + 1) == count) { + // done - found space + break; + } + // Can't find space if all clusters checked. + if (startCluster == endCluster) { + DBG_FAIL_MACRO; + goto fail; + } + endCluster++; + } + // remember possible next free cluster + if (setStart) { + m_allocSearchStart = endCluster + 1; + } + + // mark end of chain + if (!fatPutEOC(endCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + // link clusters + while (endCluster > bgnCluster) { + if (!fatPut(endCluster - 1, endCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + endCluster--; + } + // Maintain count of free clusters. + updateFreeClusterCount(-count); + + // return first cluster number to caller + *firstCluster = bgnCluster; + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +uint32_t FatVolume::clusterFirstBlock(uint32_t cluster) const { + return m_dataStartBlock + ((cluster - 2) << m_clusterSizeShift); +} +//------------------------------------------------------------------------------ +// Fetch a FAT entry - return -1 error, 0 EOC, else 1. +int8_t FatVolume::fatGet(uint32_t cluster, uint32_t* value) { + uint32_t lba; + uint32_t next; + cache_t* pc; + + // error if reserved cluster of beyond FAT + DBG_HALT_IF(cluster < 2 || cluster > m_lastCluster); + + if (fatType() == 32) { + lba = m_fatStartBlock + (cluster >> 7); + pc = cacheFetchFat(lba, FatCache::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + next = pc->fat32[cluster & 0X7F] & FAT32MASK; + goto done; + } + if (fatType() == 16) { + lba = m_fatStartBlock + ((cluster >> 8) & 0XFF); + pc = cacheFetchFat(lba, FatCache::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + next = pc->fat16[cluster & 0XFF]; + goto done; + } + if (FAT12_SUPPORT && fatType() == 12) { + uint16_t index = cluster; + index += index >> 1; + lba = m_fatStartBlock + (index >> 9); + pc = cacheFetchFat(lba, FatCache::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + index &= 0X1FF; + uint16_t tmp = pc->data[index]; + index++; + if (index == 512) { + pc = cacheFetchFat(lba + 1, FatCache::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + index = 0; + } + tmp |= pc->data[index] << 8; + next = cluster & 1 ? tmp >> 4 : tmp & 0XFFF; + goto done; + } else { + DBG_FAIL_MACRO; + goto fail; + } +done: + if (isEOC(next)) { + return 0; + } + *value = next; + return 1; + +fail: + return -1; +} +//------------------------------------------------------------------------------ +// Store a FAT entry +bool FatVolume::fatPut(uint32_t cluster, uint32_t value) { + uint32_t lba; + cache_t* pc; + + // error if reserved cluster of beyond FAT + DBG_HALT_IF(cluster < 2 || cluster > m_lastCluster); + + if (fatType() == 32) { + lba = m_fatStartBlock + (cluster >> 7); + pc = cacheFetchFat(lba, FatCache::CACHE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + pc->fat32[cluster & 0X7F] = value; + return true; + } + + if (fatType() == 16) { + lba = m_fatStartBlock + ((cluster >> 8) & 0XFF); + pc = cacheFetchFat(lba, FatCache::CACHE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + pc->fat16[cluster & 0XFF] = value; + return true; + } + + if (FAT12_SUPPORT && fatType() == 12) { + uint16_t index = cluster; + index += index >> 1; + lba = m_fatStartBlock + (index >> 9); + pc = cacheFetchFat(lba, FatCache::CACHE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + index &= 0X1FF; + uint8_t tmp = value; + if (cluster & 1) { + tmp = (pc->data[index] & 0XF) | tmp << 4; + } + pc->data[index] = tmp; + + index++; + if (index == 512) { + lba++; + index = 0; + pc = cacheFetchFat(lba, FatCache::CACHE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + } + tmp = value >> 4; + if (!(cluster & 1)) { + tmp = ((pc->data[index] & 0XF0)) | tmp >> 4; + } + pc->data[index] = tmp; + return true; + } else { + DBG_FAIL_MACRO; + goto fail; + } + +fail: + return false; +} +//------------------------------------------------------------------------------ +// free a cluster chain +bool FatVolume::freeChain(uint32_t cluster) { + uint32_t next; + int8_t fg; + do { + fg = fatGet(cluster, &next); + if (fg < 0) { + DBG_FAIL_MACRO; + goto fail; + } + // free cluster + if (!fatPut(cluster, 0)) { + DBG_FAIL_MACRO; + goto fail; + } + // Add one to count of free clusters. + updateFreeClusterCount(1); + + if (cluster < m_allocSearchStart) { + m_allocSearchStart = cluster; + } + cluster = next; + } while (fg); + + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +int32_t FatVolume::freeClusterCount() { +#if MAINTAIN_FREE_CLUSTER_COUNT + if (m_freeClusterCount >= 0) { + return m_freeClusterCount; + } +#endif // MAINTAIN_FREE_CLUSTER_COUNT + uint32_t free = 0; + uint32_t lba; + uint32_t todo = m_lastCluster + 1; + uint16_t n; + + if (FAT12_SUPPORT && fatType() == 12) { + for (unsigned i = 2; i < todo; i++) { + uint32_t c; + int8_t fg = fatGet(i, &c); + if (fg < 0) { + DBG_FAIL_MACRO; + goto fail; + } + if (fg && c == 0) { + free++; + } + } + } else if (fatType() == 16 || fatType() == 32) { + lba = m_fatStartBlock; + while (todo) { + cache_t* pc = cacheFetchFat(lba++, FatCache::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + n = fatType() == 16 ? 256 : 128; + if (todo < n) { + n = todo; + } + if (fatType() == 16) { + for (uint16_t i = 0; i < n; i++) { + if (pc->fat16[i] == 0) { + free++; + } + } + } else { + for (uint16_t i = 0; i < n; i++) { + if (pc->fat32[i] == 0) { + free++; + } + } + } + todo -= n; + } + } else { + // invalid FAT type + DBG_FAIL_MACRO; + goto fail; + } + setFreeClusterCount(free); + return free; + +fail: + return -1; +} +//------------------------------------------------------------------------------ +bool FatVolume::init(uint8_t part) { + uint32_t clusterCount; + uint32_t totalBlocks; + uint32_t volumeStartBlock = 0; + fat32_boot_t* fbs; + cache_t* pc; + uint8_t tmp; + m_fatType = 0; + m_allocSearchStart = 1; + m_cache.init(this); +#if USE_SEPARATE_FAT_CACHE + m_fatCache.init(this); +#endif // USE_SEPARATE_FAT_CACHE + // if part == 0 assume super floppy with FAT boot sector in block zero + // if part > 0 assume mbr volume with partition table + if (part) { + if (part > 4) { + DBG_FAIL_MACRO; + goto fail; + } + pc = cacheFetchData(0, FatCache::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + part_t* p = &pc->mbr.part[part - 1]; + if ((p->boot & 0X7F) != 0 || p->firstSector == 0) { + // not a valid partition + DBG_FAIL_MACRO; + goto fail; + } + volumeStartBlock = p->firstSector; + } + pc = cacheFetchData(volumeStartBlock, FatCache::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + fbs = &(pc->fbs32); + if (fbs->bytesPerSector != 512 || + fbs->fatCount != 2 || + fbs->reservedSectorCount == 0) { + // not valid FAT volume + DBG_FAIL_MACRO; + goto fail; + } + m_blocksPerCluster = fbs->sectorsPerCluster; + m_clusterBlockMask = m_blocksPerCluster - 1; + // determine shift that is same as multiply by m_blocksPerCluster + m_clusterSizeShift = 0; + for (tmp = 1; m_blocksPerCluster != tmp; tmp <<= 1, m_clusterSizeShift++) { + if (tmp == 0) { + DBG_FAIL_MACRO; + goto fail; + } + } + m_blocksPerFat = fbs->sectorsPerFat16 ? + fbs->sectorsPerFat16 : fbs->sectorsPerFat32; + + m_fatStartBlock = volumeStartBlock + fbs->reservedSectorCount; + + // count for FAT16 zero for FAT32 + m_rootDirEntryCount = fbs->rootDirEntryCount; + + // directory start for FAT16 dataStart for FAT32 + m_rootDirStart = m_fatStartBlock + 2 * m_blocksPerFat; + // data start for FAT16 and FAT32 + m_dataStartBlock = m_rootDirStart + ((32 * fbs->rootDirEntryCount + 511)/512); + + // total blocks for FAT16 or FAT32 + totalBlocks = fbs->totalSectors16 ? + fbs->totalSectors16 : fbs->totalSectors32; + // total data blocks + clusterCount = totalBlocks - (m_dataStartBlock - volumeStartBlock); + + // divide by cluster size to get cluster count + clusterCount >>= m_clusterSizeShift; + m_lastCluster = clusterCount + 1; + + // Indicate unknown number of free clusters. + setFreeClusterCount(-1); + // FAT type is determined by cluster count + if (clusterCount < 4085) { + m_fatType = 12; + if (!FAT12_SUPPORT) { + DBG_FAIL_MACRO; + goto fail; + } + } else if (clusterCount < 65525) { + m_fatType = 16; + } else { + m_rootDirStart = fbs->fat32RootCluster; + m_fatType = 32; + } + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool FatVolume::wipe(print_t* pr) { + cache_t* cache; + uint16_t count; + uint32_t lbn; + if (!fatType()) { + DBG_FAIL_MACRO; + goto fail; + } + cache = cacheClear(); + if (!cache) { + DBG_FAIL_MACRO; + goto fail; + } + memset(cache->data, 0, 512); + // Zero root. + if (fatType() == 32) { + lbn = clusterFirstBlock(m_rootDirStart); + count = m_blocksPerCluster; + } else { + lbn = m_rootDirStart; + count = m_rootDirEntryCount/16; + } + for (uint32_t n = 0; n < count; n++) { + if (!writeBlock(lbn + n, cache->data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + // Clear FATs. + count = 2*m_blocksPerFat; + lbn = m_fatStartBlock; + for (uint32_t nb = 0; nb < count; nb++) { + if (pr && (nb & 0XFF) == 0) { + pr->write('.'); + } + if (!writeBlock(lbn + nb, cache->data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + // Reserve first two clusters. + if (fatType() == 32) { + cache->fat32[0] = 0x0FFFFFF8; + cache->fat32[1] = 0x0FFFFFFF; + } else if (fatType() == 16) { + cache->fat16[0] = 0XFFF8; + cache->fat16[1] = 0XFFFF; + } else if (FAT12_SUPPORT && fatType() == 12) { + cache->fat32[0] = 0XFFFFF8; + } else { + DBG_FAIL_MACRO; + goto fail; + } + if (!writeBlock(m_fatStartBlock, cache->data) || + !writeBlock(m_fatStartBlock + m_blocksPerFat, cache->data)) { + DBG_FAIL_MACRO; + goto fail; + } + if (fatType() == 32) { + // Reserve root cluster. + if (!fatPutEOC(m_rootDirStart) || !cacheSync()) { + DBG_FAIL_MACRO; + goto fail; + } + } + if (pr) { + pr->write('\r'); + pr->write('\n'); + } + m_fatType = 0; + return true; + +fail: + m_fatType = 0; + return false; +} diff --git a/libraries/SdFat/src/FatLib/FatVolume.h b/libraries/SdFat/src/FatLib/FatVolume.h new file mode 100644 index 0000000..859f5c3 --- /dev/null +++ b/libraries/SdFat/src/FatLib/FatVolume.h @@ -0,0 +1,370 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef FatVolume_h +#define FatVolume_h +/** + * \file + * \brief FatVolume class + */ +#include +#include "FatLibConfig.h" +#include "FatStructs.h" +#include "BlockDriver.h" +//------------------------------------------------------------------------------ +#ifndef DOXYGEN_SHOULD_SKIP_THIS +/** Macro for debug. */ +#define DEBUG_MODE 0 +#if DEBUG_MODE +#define DBG_FAIL_MACRO Serial.print(F(__FILE__)); Serial.println(__LINE__); +#define DBG_PRINT_IF(b) if (b) {Serial.println(F(#b)); DBG_FAIL_MACRO;} +#define DBG_HALT_IF(b) if (b) {Serial.println(F(#b));\ + DBG_FAIL_MACRO; while (1);} +#else // DEBUG_MODE +#define DBG_FAIL_MACRO +#define DBG_PRINT_IF(b) +#define DBG_HALT_IF(b) +#endif // DEBUG_MODE +#endif // DOXYGEN_SHOULD_SKIP_THIS +//------------------------------------------------------------------------------ +#if ENABLE_ARDUINO_FEATURES +/** Use Print for Arduino */ +typedef Print print_t; +#else // ENABLE_ARDUINO_FEATURES +/** + * \class CharWriter + * \brief Character output - often serial port. + */ +class CharWriter { + public: + virtual size_t write(char c) = 0; + virtual size_t write(const char* s) = 0; +}; +typedef CharWriter print_t; +#endif // ENABLE_ARDUINO_FEATURES +//------------------------------------------------------------------------------ +// Forward declaration of FatVolume. +class FatVolume; +//------------------------------------------------------------------------------ +/** + * \brief Cache for an raw data block. + */ +union cache_t { + /** Used to access cached file data blocks. */ + uint8_t data[512]; + /** Used to access cached FAT16 entries. */ + uint16_t fat16[256]; + /** Used to access cached FAT32 entries. */ + uint32_t fat32[128]; + /** Used to access cached directory entries. */ + dir_t dir[16]; + /** Used to access a cached Master Boot Record. */ + mbr_t mbr; + /** Used to access to a cached FAT boot sector. */ + fat_boot_t fbs; + /** Used to access to a cached FAT32 boot sector. */ + fat32_boot_t fbs32; + /** Used to access to a cached FAT32 FSINFO sector. */ + fat32_fsinfo_t fsinfo; +}; +//============================================================================== +/** + * \class FatCache + * \brief Block cache. + */ +class FatCache { + public: + /** Cached block is dirty */ + static const uint8_t CACHE_STATUS_DIRTY = 1; + /** Cashed block is FAT entry and must be mirrored in second FAT. */ + static const uint8_t CACHE_STATUS_MIRROR_FAT = 2; + /** Cache block status bits */ + static const uint8_t CACHE_STATUS_MASK + = CACHE_STATUS_DIRTY | CACHE_STATUS_MIRROR_FAT; + /** Sync existing block but do not read new block. */ + static const uint8_t CACHE_OPTION_NO_READ = 4; + /** Cache block for read. */ + static const uint8_t CACHE_FOR_READ = 0; + /** Cache block for write. */ + static const uint8_t CACHE_FOR_WRITE = CACHE_STATUS_DIRTY; + /** Reserve cache block for write - do not read from block device. */ + static const uint8_t CACHE_RESERVE_FOR_WRITE + = CACHE_STATUS_DIRTY | CACHE_OPTION_NO_READ; + /** \return Cache block address. */ + cache_t* block() { + return &m_block; + } + /** Set current block dirty. */ + void dirty() { + m_status |= CACHE_STATUS_DIRTY; + } + /** Initialize the cache. + * \param[in] vol FatVolume that owns this FatCache. + */ + void init(FatVolume *vol) { + m_vol = vol; + invalidate(); + } + /** Invalidate current cache block. */ + void invalidate() { + m_status = 0; + m_lbn = 0XFFFFFFFF; + } + /** \return dirty status */ + bool isDirty() { + return m_status & CACHE_STATUS_DIRTY; + } + /** \return Logical block number for cached block. */ + uint32_t lbn() { + return m_lbn; + } + /** Read a block into the cache. + * \param[in] lbn Block to read. + * \param[in] option mode for cached block. + * \return Address of cached block. */ + cache_t* read(uint32_t lbn, uint8_t option); + /** Write current block if dirty. + * \return true for success else false. + */ + bool sync(); + + private: + uint8_t m_status; + FatVolume* m_vol; + uint32_t m_lbn; + cache_t m_block; +}; +//============================================================================== +/** + * \class FatVolume + * \brief Access FAT16 and FAT32 volumes on raw file devices. + */ +class FatVolume { + public: + /** Create an instance of FatVolume + */ + FatVolume() : m_fatType(0) {} + + /** \return The volume's cluster size in blocks. */ + uint8_t blocksPerCluster() const { + return m_blocksPerCluster; + } + /** \return The number of blocks in one FAT. */ + uint32_t blocksPerFat() const { + return m_blocksPerFat; + } + /** Clear the cache and returns a pointer to the cache. Not for normal apps. + * \return A pointer to the cache buffer or zero if an error occurs. + */ + cache_t* cacheClear() { + if (!cacheSync()) { + return 0; + } + m_cache.invalidate(); + return m_cache.block(); + } + /** \return The total number of clusters in the volume. */ + uint32_t clusterCount() const { + return m_lastCluster - 1; + } + /** \return The shift count required to multiply by blocksPerCluster. */ + uint8_t clusterSizeShift() const { + return m_clusterSizeShift; + } + /** \return The logical block number for the start of file data. */ + uint32_t dataStartBlock() const { + return m_dataStartBlock; + } + /** \return The number of File Allocation Tables. */ + uint8_t fatCount() { + return 2; + } + /** \return The logical block number for the start of the first FAT. */ + uint32_t fatStartBlock() const { + return m_fatStartBlock; + } + /** \return The FAT type of the volume. Values are 12, 16 or 32. */ + uint8_t fatType() const { + return m_fatType; + } + /** Volume free space in clusters. + * + * \return Count of free clusters for success or -1 if an error occurs. + */ + int32_t freeClusterCount(); + /** Initialize a FAT volume. Try partition one first then try super + * floppy format. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool init() { + return init(1) || init(0); + } + /** Initialize a FAT volume. + + * \param[in] part The partition to be used. Legal values for \a part are + * 1-4 to use the corresponding partition on a device formatted with + * a MBR, Master Boot Record, or zero if the device is formatted as + * a super floppy with the FAT boot sector in block zero. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool init(uint8_t part); + /** \return The number of entries in the root directory for FAT16 volumes. */ + uint16_t rootDirEntryCount() const { + return m_rootDirEntryCount; + } + /** \return The logical block number for the start of the root directory + on FAT16 volumes or the first cluster number on FAT32 volumes. */ + uint32_t rootDirStart() const { + return m_rootDirStart; + } + /** \return The number of blocks in the volume */ + uint32_t volumeBlockCount() const { + return blocksPerCluster()*clusterCount(); + } + /** Wipe all data from the volume. + * \param[in] pr print stream for status dots. + * \return true for success else false. + */ + bool wipe(print_t* pr = 0); + /** Debug access to FAT table + * + * \param[in] n cluster number. + * \param[out] v value of entry + * \return true for success or false for failure + */ + int8_t dbgFat(uint32_t n, uint32_t* v) { + return fatGet(n, v); + } +//------------------------------------------------------------------------------ + private: + // Allow FatFile and FatCache access to FatVolume private functions. + friend class FatCache; + friend class FatFile; + friend class FatFileSystem; +//------------------------------------------------------------------------------ + BlockDriver* m_blockDev; // block device + uint8_t m_blocksPerCluster; // Cluster size in blocks. + uint8_t m_clusterBlockMask; // Mask to extract block of cluster. + uint8_t m_clusterSizeShift; // Cluster count to block count shift. + uint8_t m_fatType; // Volume type (12, 16, OR 32). + uint16_t m_rootDirEntryCount; // Number of entries in FAT16 root dir. + uint32_t m_allocSearchStart; // Start cluster for alloc search. + uint32_t m_blocksPerFat; // FAT size in blocks + uint32_t m_dataStartBlock; // First data block number. + uint32_t m_fatStartBlock; // Start block for first FAT. + uint32_t m_lastCluster; // Last cluster number in FAT. + uint32_t m_rootDirStart; // Start block for FAT16, cluster for FAT32. +//------------------------------------------------------------------------------ + // block I/O functions. + bool readBlock(uint32_t block, uint8_t* dst) { + return m_blockDev->readBlock(block, dst); + } + bool syncBlocks() { + return m_blockDev->syncBlocks(); + } + bool writeBlock(uint32_t block, const uint8_t* src) { + return m_blockDev->writeBlock(block, src); + } +#if USE_MULTI_BLOCK_IO + bool readBlocks(uint32_t block, uint8_t* dst, size_t nb) { + return m_blockDev->readBlocks(block, dst, nb); + } + bool writeBlocks(uint32_t block, const uint8_t* src, size_t nb) { + return m_blockDev->writeBlocks(block, src, nb); + } +#endif // USE_MULTI_BLOCK_IO +#if MAINTAIN_FREE_CLUSTER_COUNT + int32_t m_freeClusterCount; // Count of free clusters in volume. + void setFreeClusterCount(int32_t value) { + m_freeClusterCount = value; + } + void updateFreeClusterCount(int32_t change) { + if (m_freeClusterCount >= 0) { + m_freeClusterCount += change; + } + } +#else // MAINTAIN_FREE_CLUSTER_COUNT + void setFreeClusterCount(int32_t value) { + (void)value; + } + void updateFreeClusterCount(int32_t change) { + (void)change; + } +#endif // MAINTAIN_FREE_CLUSTER_COUNT + +// block caches + FatCache m_cache; +#if USE_SEPARATE_FAT_CACHE + FatCache m_fatCache; + cache_t* cacheFetchFat(uint32_t blockNumber, uint8_t options) { + return m_fatCache.read(blockNumber, + options | FatCache::CACHE_STATUS_MIRROR_FAT); + } + bool cacheSync() { + return m_cache.sync() && m_fatCache.sync() && syncBlocks(); + } +#else // + cache_t* cacheFetchFat(uint32_t blockNumber, uint8_t options) { + return cacheFetchData(blockNumber, + options | FatCache::CACHE_STATUS_MIRROR_FAT); + } + bool cacheSync() { + return m_cache.sync() && syncBlocks(); + } +#endif // USE_SEPARATE_FAT_CACHE + cache_t* cacheFetchData(uint32_t blockNumber, uint8_t options) { + return m_cache.read(blockNumber, options); + } + void cacheInvalidate() { + m_cache.invalidate(); + } + bool cacheSyncData() { + return m_cache.sync(); + } + cache_t *cacheAddress() { + return m_cache.block(); + } + uint32_t cacheBlockNumber() { + return m_cache.lbn(); + } + void cacheDirty() { + m_cache.dirty(); + } +//------------------------------------------------------------------------------ + bool allocateCluster(uint32_t current, uint32_t* next); + bool allocContiguous(uint32_t count, uint32_t* firstCluster); + uint8_t blockOfCluster(uint32_t position) const { + return (position >> 9) & m_clusterBlockMask; + } + uint32_t clusterFirstBlock(uint32_t cluster) const; + int8_t fatGet(uint32_t cluster, uint32_t* value); + bool fatPut(uint32_t cluster, uint32_t value); + bool fatPutEOC(uint32_t cluster) { + return fatPut(cluster, 0x0FFFFFFF); + } + bool freeChain(uint32_t cluster); + bool isEOC(uint32_t cluster) const { + return cluster > m_lastCluster; + } +}; +#endif // FatVolume diff --git a/libraries/SdFat/src/FatLib/FmtNumber.cpp b/libraries/SdFat/src/FatLib/FmtNumber.cpp new file mode 100644 index 0000000..3aa5bec --- /dev/null +++ b/libraries/SdFat/src/FatLib/FmtNumber.cpp @@ -0,0 +1,455 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#include "FmtNumber.h" +// Use Stimmer div/mod 10 on avr +#ifdef __AVR__ +#include +#define USE_STIMMER +#endif // __AVR__ +//------------------------------------------------------------------------------ +// Stimmer div/mod 10 for AVR +// this code fragment works out i/10 and i%10 by calculating +// i*(51/256)*(256/255)/2 == i*51/510 == i/10 +// by "j.k" I mean 32.8 fixed point, j is integer part, k is fractional part +// j.k = ((j+1.0)*51.0)/256.0 +// (we add 1 because we will be using the floor of the result later) +// divmod10_asm16 and divmod10_asm32 are public domain code by Stimmer. +// http://forum.arduino.cc/index.php?topic=167414.msg1293679#msg1293679 +#define divmod10_asm16(in32, mod8, tmp8) \ +asm volatile( \ + " ldi %2,51 \n\t" \ + " mul %A0,%2 \n\t" \ + " clr %A0 \n\t" \ + " add r0,%2 \n\t" \ + " adc %A0,r1 \n\t" \ + " mov %1,r0 \n\t" \ + " mul %B0,%2 \n\t" \ + " clr %B0 \n\t" \ + " add %A0,r0 \n\t" \ + " adc %B0,r1 \n\t" \ + " clr r1 \n\t" \ + " add %1,%A0 \n\t" \ + " adc %A0,%B0 \n\t" \ + " adc %B0,r1 \n\t" \ + " add %1,%B0 \n\t" \ + " adc %A0,r1 \n\t" \ + " adc %B0,r1 \n\t" \ + " lsr %B0 \n\t" \ + " ror %A0 \n\t" \ + " ror %1 \n\t" \ + " ldi %2,10 \n\t" \ + " mul %1,%2 \n\t" \ + " mov %1,r1 \n\t" \ + " clr r1 \n\t" \ + :"+r"(in32), "=d"(mod8), "=d"(tmp8) : : "r0") + +#define divmod10_asm32(in32, mod8, tmp8) \ +asm volatile( \ + " ldi %2,51 \n\t" \ + " mul %A0,%2 \n\t" \ + " clr %A0 \n\t" \ + " add r0,%2 \n\t" \ + " adc %A0,r1 \n\t" \ + " mov %1,r0 \n\t" \ + " mul %B0,%2 \n\t" \ + " clr %B0 \n\t" \ + " add %A0,r0 \n\t" \ + " adc %B0,r1 \n\t" \ + " mul %C0,%2 \n\t" \ + " clr %C0 \n\t" \ + " add %B0,r0 \n\t" \ + " adc %C0,r1 \n\t" \ + " mul %D0,%2 \n\t" \ + " clr %D0 \n\t" \ + " add %C0,r0 \n\t" \ + " adc %D0,r1 \n\t" \ + " clr r1 \n\t" \ + " add %1,%A0 \n\t" \ + " adc %A0,%B0 \n\t" \ + " adc %B0,%C0 \n\t" \ + " adc %C0,%D0 \n\t" \ + " adc %D0,r1 \n\t" \ + " add %1,%B0 \n\t" \ + " adc %A0,%C0 \n\t" \ + " adc %B0,%D0 \n\t" \ + " adc %C0,r1 \n\t" \ + " adc %D0,r1 \n\t" \ + " add %1,%D0 \n\t" \ + " adc %A0,r1 \n\t" \ + " adc %B0,r1 \n\t" \ + " adc %C0,r1 \n\t" \ + " adc %D0,r1 \n\t" \ + " lsr %D0 \n\t" \ + " ror %C0 \n\t" \ + " ror %B0 \n\t" \ + " ror %A0 \n\t" \ + " ror %1 \n\t" \ + " ldi %2,10 \n\t" \ + " mul %1,%2 \n\t" \ + " mov %1,r1 \n\t" \ + " clr r1 \n\t" \ + :"+r"(in32), "=d"(mod8), "=d"(tmp8) : : "r0") +//------------------------------------------------------------------------------ +/* +// C++ code is based on this version of divmod10 by robtillaart. +// http://forum.arduino.cc/index.php?topic=167414.msg1246851#msg1246851 +// from robtillaart post: +// The code is based upon the divu10() code from the book Hackers Delight1. +// My insight was that the error formula in divu10() was in fact modulo 10 +// but not always. Sometimes it was 10 more. +void divmod10(uint32_t in, uint32_t &div, uint32_t &mod) +{ + // q = in * 0.8; + uint32_t q = (in >> 1) + (in >> 2); + q = q + (q >> 4); + q = q + (q >> 8); + q = q + (q >> 16); // not needed for 16 bit version + + // q = q / 8; ==> q = in *0.1; + q = q >> 3; + + // determine error + uint32_t r = in - ((q << 3) + (q << 1)); // r = in - q*10; + div = q + (r > 9); + if (r > 9) mod = r - 10; + else mod = r; +} +// Hackers delight function is here: +// http://www.hackersdelight.org/hdcodetxt/divuc.c.txt +// Code below uses 8/10 = 0.1100 1100 1100 1100 1100 1100 1100 1100. +// 15 ops including the multiply, or 17 elementary ops. +unsigned divu10(unsigned n) { + unsigned q, r; + + q = (n >> 1) + (n >> 2); + q = q + (q >> 4); + q = q + (q >> 8); + q = q + (q >> 16); + q = q >> 3; + r = n - q*10; + return q + ((r + 6) >> 4); +// return q + (r > 9); +} +*/ +//------------------------------------------------------------------------------ +#ifndef DOXYGEN_SHOULD_SKIP_THIS +#ifdef __AVR__ +static const float m[] PROGMEM = {1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32}; +static const float p[] PROGMEM = {1e+1, 1e+2, 1e+4, 1e+8, 1e+16, 1e+32}; +#else // __AVR__ +static const float m[] = {1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32}; +static const float p[] = {1e+1, 1e+2, 1e+4, 1e+8, 1e+16, 1e+32}; +#endif // __AVR__ +#endif // DOXYGEN_SHOULD_SKIP_THIS +// scale float v by power of ten. return v*10^n +float scale10(float v, int8_t n) { + const float *s; + if (n < 0) { + n = -n; + s = m; + } else { + s = p; + } + n &= 63; + for (uint8_t i = 0; n; n >>= 1, i++) { +#ifdef __AVR__ + if (n & 1) { + v *= pgm_read_float(&s[i]); + } +#else // __AVR__ + if (n & 1) { + v *= s[i]; + } +#endif // __AVR__ + } + return v; +} +//------------------------------------------------------------------------------ +// Format 16-bit unsigned +char* fmtDec(uint16_t n, char* p) { + while (n > 9) { +#ifdef USE_STIMMER + uint8_t tmp8, r; + divmod10_asm16(n, r, tmp8); +#else // USE_STIMMER + uint16_t t = n; + n = (n >> 1) + (n >> 2); + n = n + (n >> 4); + n = n + (n >> 8); + // n = n + (n >> 16); // no code for 16-bit n + n = n >> 3; + uint8_t r = t - (((n << 2) + n) << 1); + if (r > 9) { + n++; + r -= 10; + } +#endif // USE_STIMMER + *--p = r + '0'; + } + *--p = n + '0'; + return p; +} +//------------------------------------------------------------------------------ +// format 32-bit unsigned +char* fmtDec(uint32_t n, char* p) { + while (n >> 16) { +#ifdef USE_STIMMER + uint8_t tmp8, r; + divmod10_asm32(n, r, tmp8); +#else // USE_STIMMER + uint32_t t = n; + n = (n >> 1) + (n >> 2); + n = n + (n >> 4); + n = n + (n >> 8); + n = n + (n >> 16); + n = n >> 3; + uint8_t r = t - (((n << 2) + n) << 1); + if (r > 9) { + n++; + r -= 10; + } +#endif // USE_STIMMER + *--p = r + '0'; + } + return fmtDec((uint16_t)n, p); +} +//------------------------------------------------------------------------------ +char* fmtFloat(float value, char* p, uint8_t prec) { + char sign = value < 0 ? '-' : 0; + if (sign) { + value = -value; + } + + if (isnan(value)) { + *--p = 'n'; + *--p = 'a'; + *--p = 'n'; + return p; + } + if (isinf(value)) { + *--p = 'f'; + *--p = 'n'; + *--p = 'i'; + return p; + } + if (value > 4294967040.0) { + *--p = 'f'; + *--p = 'v'; + *--p = 'o'; + return p; + } + if (prec > 9) { + prec = 9; + } + value += scale10(0.5, -prec); + + uint32_t whole = value; + if (prec) { + char* tmp = p - prec; + uint32_t fraction = scale10(value - whole, prec); + p = fmtDec(fraction, p); + while (p > tmp) { + *--p = '0'; + } + *--p = '.'; + } + p = fmtDec(whole, p); + if (sign) { + *--p = sign; + } + return p; +} +//------------------------------------------------------------------------------ +/** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] ptr Pointer to last char in buffer. + * \param[in] prec Number of digits after decimal point. + * \param[in] expChar Use exp format if non zero. + * \return Pointer to first character of result. + */ +char* fmtFloat(float value, char* ptr, uint8_t prec, char expChar) { + bool neg = value < 0; + if (neg) { + value = -value; + } + + // check for nan inf ovf + if (isnan(value)) { + *--ptr = 'n'; + *--ptr = 'a'; + *--ptr = 'n'; + return ptr; + } + if (isinf(value)) { + *--ptr = 'f'; + *--ptr = 'n'; + *--ptr = 'i'; + return ptr; + } + if (!expChar && value > 4294967040.0) { + *--ptr = 'f'; + *--ptr = 'v'; + *--ptr = 'o'; + return ptr; + } + if (prec > 9) { + prec = 9; + } + float round = scale10(0.5, -prec); + if (expChar) { + int8_t exp = 0; + bool expNeg = false; + if (value) { + while (value > 10.0) { + value *= 0.1; + exp++; + } + while (value < 1.0) { + value *= 10.0; + exp--; + } + value += round; + if (value > 10.0) { + value *= 0.1; + exp++; + } + expNeg = exp < 0; + if (expNeg) { + exp = -exp; + } + } + ptr = fmtDec((uint16_t)exp, ptr); + if (exp < 10) { + *--ptr = '0'; + } + *--ptr = expNeg ? '-' : '+'; + *--ptr = expChar; + } else { + // round value + value += round; + } + uint32_t whole = value; + if (prec) { + char* tmp = ptr - prec; + uint32_t fraction = scale10(value - whole, prec); + ptr = fmtDec(fraction, ptr); + while (ptr > tmp) { + *--ptr = '0'; + } + *--ptr = '.'; + } + ptr = fmtDec(whole, ptr); + if (neg) { + *--ptr = '-'; + } + return ptr; +} +//------------------------------------------------------------------------------ +char* fmtHex(uint32_t n, char* p) { + do { + uint8_t h = n & 0XF; + *--p = h + (h < 10 ? '0' : 'A' - 10); + n >>= 4; + } while (n); + return p; +} +//------------------------------------------------------------------------------ +float scanFloat(const char* str, char** ptr) { + int16_t const EXP_LIMIT = 100; + bool digit = false; + bool dot = false; + uint32_t fract = 0; + int fracExp = 0; + uint8_t nd = 0; + bool neg; + int c; + float v; + const char* successPtr = str; + + if (ptr) { + *ptr = const_cast(str); + } + + while (isSpace((c = *str++))) {} + neg = c == '-'; + if (c == '-' || c == '+') { + c = *str++; + } + // Skip leading zeros + while (c == '0') { + c = *str++; + digit = true; + } + for (;;) { + if (isDigit(c)) { + digit = true; + if (nd < 9) { + fract = 10*fract + c - '0'; + nd++; + if (dot) { + fracExp--; + } + } else { + if (!dot) { + fracExp++; + } + } + } else if (c == '.') { + if (dot) { + goto fail; + } + dot = true; + } else { + if (!digit) { + goto fail; + } + break; + } + successPtr = str; + c = *str++; + } + if (c == 'e' || c == 'E') { + int exp = 0; + c = *str++; + bool expNeg = c == '-'; + if (c == '-' || c == '+') { + c = *str++; + } + while (isDigit(c)) { + if (exp > EXP_LIMIT) { + goto fail; + } + exp = 10*exp + c - '0'; + successPtr = str; + c = *str++; + } + fracExp += expNeg ? -exp : exp; + } + if (ptr) { + *ptr = const_cast(successPtr); + } + v = scale10(static_cast(fract), fracExp); + return neg ? -v : v; + +fail: + return 0; +} + + diff --git a/libraries/SdFat/src/FatLib/FmtNumber.h b/libraries/SdFat/src/FatLib/FmtNumber.h new file mode 100644 index 0000000..2bb97dc --- /dev/null +++ b/libraries/SdFat/src/FatLib/FmtNumber.h @@ -0,0 +1,38 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef FmtNumber_h +#define FmtNumber_h +// #include +inline bool isDigit(char c) { + return '0' <= c && c <= '9'; +} +inline bool isSpace(char c) { + return c == ' ' || (0X9 <= c && c <= 0XD); +} +#include +#include +char* fmtDec(uint16_t n, char* p); +char* fmtDec(uint32_t n, char* p); +char* fmtFloat(float value, char* p, uint8_t prec); +char* fmtFloat(float value, char* ptr, uint8_t prec, char expChar); +char* fmtHex(uint32_t n, char* p); +float scale10(float v, int8_t n); +float scanFloat(const char* str, char** ptr); +#endif // FmtNumber_h diff --git a/libraries/SdFat/src/FatLib/StdioStream.cpp b/libraries/SdFat/src/FatLib/StdioStream.cpp new file mode 100644 index 0000000..40ad093 --- /dev/null +++ b/libraries/SdFat/src/FatLib/StdioStream.cpp @@ -0,0 +1,522 @@ +/* Arduino RamDisk Library + * Copyright (C) 2014 by William Greiman + * + * This file is part of the Arduino RamDisk 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 RamDisk Library. If not, see + * . + */ +#include "StdioStream.h" +#include "FmtNumber.h" +//------------------------------------------------------------------------------ +int StdioStream::fclose() { + int rtn = 0; + if (!m_flags) { + return EOF; + } + if (m_flags & F_SWR) { + if (!flushBuf()) { + rtn = EOF; + } + } + if (!FatFile::close()) { + rtn = EOF; + } + m_r = 0; + m_w = 0; + m_flags = 0; + return rtn; +} +//------------------------------------------------------------------------------ +int StdioStream::fflush() { + if ((m_flags & (F_SWR | F_SRW)) && !(m_flags & F_SRD)) { + if (flushBuf() && FatFile::sync()) { + return 0; + } + } + return EOF; +} +//------------------------------------------------------------------------------ +char* StdioStream::fgets(char* str, size_t num, size_t* len) { + char* s = str; + size_t n; + if (num-- == 0) { + return 0; + } + while (num) { + if ((n = m_r) == 0) { + if (!fillBuf()) { + if (s == str) { + return 0; + } + break; + } + n = m_r; + } + if (n > num) { + n = num; + } + uint8_t* end = reinterpret_cast(memchr(m_p, '\n', n)); + if (end != 0) { + n = ++end - m_p; + memcpy(s, m_p, n); + m_r -= n; + m_p = end; + s += n; + break; + } + memcpy(s, m_p, n); + m_r -= n; + m_p += n; + s += n; + num -= n; + } + *s = 0; + if (len) { + *len = s - str; + } + return str; +} +//------------------------------------------------------------------------------ +bool StdioStream::fopen(const char* path, const char* mode) { + uint8_t oflag; + switch (*mode++) { + case 'a': + m_flags = F_SWR; + oflag = O_WRITE | O_CREAT | O_APPEND | O_AT_END; + break; + + case 'r': + m_flags = F_SRD; + oflag = O_READ; + break; + + case 'w': + m_flags = F_SWR; + oflag = O_WRITE | O_CREAT | O_TRUNC; + break; + + default: + goto fail; + } + while (*mode) { + switch (*mode++) { + case '+': + m_flags |= F_SRW; + oflag |= O_RDWR; + break; + + case 'b': + break; + + case 'x': + oflag |= O_EXCL; + break; + + default: + goto fail; + } + } + if ((oflag & O_EXCL) && !(oflag & O_WRITE)) { + goto fail; + } + if (!FatFile::open(path, oflag)) { + goto fail; + } + m_r = 0; + m_w = 0; + m_p = m_buf; + return true; + +fail: + m_flags = 0; + return false; +} +//------------------------------------------------------------------------------ +int StdioStream::fputs(const char* str) { + size_t len = strlen(str); + return fwrite(str, 1, len) == len ? len : EOF; +} +//------------------------------------------------------------------------------ +size_t StdioStream::fread(void* ptr, size_t size, size_t count) { + uint8_t* dst = reinterpret_cast(ptr); + size_t total = size*count; + if (total == 0) { + return 0; + } + size_t need = total; + while (need > m_r) { + memcpy(dst, m_p, m_r); + dst += m_r; + m_p += m_r; + need -= m_r; + if (!fillBuf()) { + return (total - need)/size; + } + } + memcpy(dst, m_p, need); + m_r -= need; + m_p += need; + return count; +} +//------------------------------------------------------------------------------ +int StdioStream::fseek(int32_t offset, int origin) { + int32_t pos; + if (m_flags & F_SWR) { + if (!flushBuf()) { + goto fail; + } + } + switch (origin) { + case SEEK_CUR: + pos = ftell(); + if (pos < 0) { + goto fail; + } + pos += offset; + if (!FatFile::seekCur(pos)) { + goto fail; + } + break; + + case SEEK_SET: + if (!FatFile::seekSet(offset)) { + goto fail; + } + break; + + case SEEK_END: + if (!FatFile::seekEnd(offset)) { + goto fail; + } + break; + + default: + goto fail; + } + m_r = 0; + m_p = m_buf; + return 0; + +fail: + return EOF; +} +//------------------------------------------------------------------------------ +int32_t StdioStream::ftell() { + uint32_t pos = FatFile::curPosition(); + if (m_flags & F_SRD) { + if (m_r > pos) { + return -1L; + } + pos -= m_r; + } else if (m_flags & F_SWR) { + pos += m_p - m_buf; + } + return pos; +} +//------------------------------------------------------------------------------ +size_t StdioStream::fwrite(const void* ptr, size_t size, size_t count) { + return write(ptr, count*size) < 0 ? EOF : count; +#if 0 //////////////////////////////////////////////////////////////////////////////////// + const uint8_t* src = static_cast(ptr); + size_t total = count*size; + if (total == 0) { + return 0; + } + size_t todo = total; + + while (todo > m_w) { + memcpy(m_p, src, m_w); + m_p += m_w; + src += m_w; + todo -= m_w; + if (!flushBuf()) { + return (total - todo)/size; + } + } + memcpy(m_p, src, todo); + m_p += todo; + m_w -= todo; + return count; +#endif ////////////////////////////////////////////////////////////////////////////////// +} +//------------------------------------------------------------------------------ +int StdioStream::write(const void* buf, size_t count) { + const uint8_t* src = static_cast(buf); + size_t todo = count; + + while (todo > m_w) { + memcpy(m_p, src, m_w); + m_p += m_w; + src += m_w; + todo -= m_w; + if (!flushBuf()) { + return EOF; + } + } + memcpy(m_p, src, todo); + m_p += todo; + m_w -= todo; + return count; +} +//------------------------------------------------------------------------------ +#if (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) +size_t StdioStream::print(const __FlashStringHelper *str) { + const char *p = (const char*)str; + uint8_t c; + while ((c = pgm_read_byte(p))) { + if (putc(c) < 0) { + return 0; + } + p++; + } + return p - (const char*)str; +} +#endif // (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) +//------------------------------------------------------------------------------ +int StdioStream::printDec(float value, uint8_t prec) { + char buf[24]; + char *ptr = fmtFloat(value, buf + sizeof(buf), prec); + return write(ptr, buf + sizeof(buf) - ptr); +} +//------------------------------------------------------------------------------ +int StdioStream::printDec(signed char n) { + if (n < 0) { + if (fputc('-') < 0) { + return -1; + } + n = -n; + } + return printDec((unsigned char)n); +} +//------------------------------------------------------------------------------ +int StdioStream::printDec(int16_t n) { + int s; + uint8_t rtn = 0; + if (n < 0) { + if (fputc('-') < 0) { + return -1; + } + n = -n; + rtn++; + } + if ((s = printDec((uint16_t)n)) < 0) { + return s; + } + return rtn; +} +//------------------------------------------------------------------------------ +int StdioStream::printDec(uint16_t n) { +#define NEW_WAY +#ifdef NEW_WAY + char buf[5]; + char *ptr = fmtDec(n, buf + sizeof(buf)); + uint8_t len = buf + sizeof(buf) - ptr; + return write(ptr, len); +#else + uint8_t len; + if (n < 100) { + len = n < 10 ? 1 : 2; + } else { + len = n < 1000 ? 3 : n < 10000 ? 4 : 5; + } + char* str = fmtSpace(len); + if (!str) { + return -1; + } + fmtDec(n, str); + return len; +#endif +} +//------------------------------------------------------------------------------ +int StdioStream::printDec(int32_t n) { + uint8_t s = 0; + if (n < 0) { + if (fputc('-') < 0) { + return -1; + } + n = -n; + s = 1; + } + int rtn = printDec((uint32_t)n); + return rtn > 0 ? rtn + s : -1; +} +//------------------------------------------------------------------------------ +int StdioStream::printDec(uint32_t n) { +#ifdef NEW_WAY + char buf[10]; + char *ptr = fmtDec(n, buf + sizeof(buf)); + uint8_t len = buf + sizeof(buf) - ptr; + return write(ptr, len); +#else + uint8_t len; + if (n < 0X10000) { + return printDec((uint16_t)n); + } + if (n < 10000000) { + len = n < 100000 ? 5 : n < 1000000 ? 6 : 7; + } else { + len = n < 100000000 ? 8 : n < 1000000000 ? 9 : 10; + } + + char* str = fmtSpace(len); + if (!str) { + return -1; + } + fmtDec(n, str); + return len; +#endif +} +//------------------------------------------------------------------------------ +int StdioStream::printHex(uint32_t n) { +#ifdef NEW_WAY + char buf[8]; + char *ptr = fmtHex(n, buf + sizeof(buf)); + uint8_t len = buf + sizeof(buf) - ptr; + return write(ptr, len); +#else + size_t len; + if (n < 0X10000) { + len = n < 0X10 ? 1 : n < 0X100 ? 2 : n < 0X1000 ? 3 : 4; + } else { + len = n < 0X100000 ? 5 : n < 0X1000000 ? 6 : n < 0X10000000 ? 7 : 8; + } + char* str = fmtSpace(len); + if (!str) { + return -1; + } + + do { + uint8_t h = n & 0XF; + *str-- = h + (h < 10 ? '0' : 'A' - 10); + n >>= 4; + } while (n); + return len; +#endif +} +//------------------------------------------------------------------------------ +bool StdioStream::rewind() { + if (m_flags & F_SWR) { + if (!flushBuf()) { + return false; + } + } + FatFile::seekSet(0); + m_r = 0; + return true; +} +//------------------------------------------------------------------------------ +int StdioStream::ungetc(int c) { + // error if EOF. + if (c == EOF) { + return EOF; + } + // error if not reading. + if ((m_flags & F_SRD) == 0) { + return EOF; + } + // error if no space. + if (m_p == m_buf) { + return EOF; + } + m_r++; + m_flags &= ~F_EOF; + return *--m_p = (uint8_t)c; +} +//============================================================================== +// private +//------------------------------------------------------------------------------ +int StdioStream::fillGet() { + if (!fillBuf()) { + return EOF; + } + m_r--; + return *m_p++; +} +//------------------------------------------------------------------------------ +// private +bool StdioStream::fillBuf() { + if (!(m_flags & + F_SRD)) { // check for F_ERR and F_EOF ??///////////////// + if (!(m_flags & F_SRW)) { + m_flags |= F_ERR; + return false; + } + if (m_flags & F_SWR) { + if (!flushBuf()) { + return false; + } + m_flags &= ~F_SWR; + m_flags |= F_SRD; + m_w = 0; + } + } + m_p = m_buf + UNGETC_BUF_SIZE; + int nr = FatFile::read(m_p, sizeof(m_buf) - UNGETC_BUF_SIZE); + if (nr <= 0) { + m_flags |= nr < 0 ? F_ERR : F_EOF; + m_r = 0; + return false; + } + m_r = nr; + return true; +} +//------------------------------------------------------------------------------ +// private +bool StdioStream::flushBuf() { + if (!(m_flags & + F_SWR)) { // check for F_ERR ??//////////////////////// + if (!(m_flags & F_SRW)) { + m_flags |= F_ERR; + return false; + } + m_flags &= ~F_SRD; + m_flags |= F_SWR; + m_r = 0; + m_w = sizeof(m_buf); + m_p = m_buf; + return true; + } + uint8_t n = m_p - m_buf; + m_p = m_buf; + m_w = sizeof(m_buf); + if (FatFile::write(m_buf, n) == n) { + return true; + } + m_flags |= F_ERR; + return false; +} +//------------------------------------------------------------------------------ +int StdioStream::flushPut(uint8_t c) { + if (!flushBuf()) { + return EOF; + } + m_w--; + return *m_p++ = c; +} +//------------------------------------------------------------------------------ +char* StdioStream::fmtSpace(uint8_t len) { + if (m_w < len) { + if (!flushBuf() || m_w < len) { + return 0; + } + } + if (len > m_w) { + return 0; + } + m_p += len; + m_w -= len; + return reinterpret_cast(m_p); +} + diff --git a/libraries/SdFat/src/FatLib/StdioStream.h b/libraries/SdFat/src/FatLib/StdioStream.h new file mode 100644 index 0000000..8909abd --- /dev/null +++ b/libraries/SdFat/src/FatLib/StdioStream.h @@ -0,0 +1,662 @@ +/* Arduino RamDisk Library + * Copyright (C) 2014 by William Greiman + * + * This file is part of the Arduino RamDisk 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 RamDisk Library. If not, see + * . + */ +#ifndef StdioStream_h +#define StdioStream_h +/** + * \file + * \brief StdioStream class + */ +#include +#include "FatFile.h" +//------------------------------------------------------------------------------ +/** Total size of stream buffer. The entire buffer is used for output. + * During input UNGETC_BUF_SIZE of this space is reserved for ungetc. + */ +const uint8_t STREAM_BUF_SIZE = 64; +/** Amount of buffer allocated for ungetc during input. */ +const uint8_t UNGETC_BUF_SIZE = 2; +//------------------------------------------------------------------------------ +// Get rid of any macros defined in . +#include +#undef clearerr +#undef fclose +#undef feof +#undef ferror +#undef fflush +#undef fgetc +#undef fgetpos +#undef fgets +#undef fopen +#undef fprintf +#undef fputc +#undef fputs +#undef fread +#undef freopen +#undef fscanf +#undef fseek +#undef fsetpos +#undef ftell +#undef fwrite +#undef getc +#undef getchar +#undef gets +#undef perror +//#undef printf // NOLINT +#undef putc +#undef putchar +#undef puts +#undef remove +#undef rename +#undef rewind +#undef scanf +#undef setbuf +#undef setvbuf +//#undef sprintf // NOLINT +#undef sscanf +#undef tmpfile +#undef tmpnam +#undef ungetc +#undef vfprintf +#undef vprintf +#undef vsprintf + +// make sure needed macros are defined +#ifndef EOF +/** End-of-file return value. */ +#define EOF (-1) +#endif // EOF +#ifndef NULL +/** Null pointer */ +#define NULL 0 +#endif // NULL +#ifndef SEEK_CUR +/** Seek relative to current position. */ +#define SEEK_CUR 1 +#endif // SEEK_CUR +#ifndef SEEK_END +/** Seek relative to end-of-file. */ +#define SEEK_END 2 +#endif // SEEK_END +#ifndef SEEK_SET +/** Seek relative to start-of-file. */ +#define SEEK_SET 0 +#endif // SEEK_SET +//------------------------------------------------------------------------------ +/** \class StdioStream + * \brief StdioStream implements a minimal stdio stream. + * + * StdioStream does not support subdirectories or long file names. + */ +class StdioStream : private FatFile { + public: + /** Constructor + * + */ + StdioStream() { + m_w = m_r = 0; + m_p = m_buf; + m_flags = 0; + } + //---------------------------------------------------------------------------- + /** Clear the stream's end-of-file and error indicators. */ + void clearerr() { + m_flags &= ~(F_ERR | F_EOF); + } + //---------------------------------------------------------------------------- + /** Close a stream. + * + * A successful call to the fclose function causes the stream to be + * flushed and the associated file to be closed. Any unwritten buffered + * data is written to the file; any unread buffered data is discarded. + * Whether or not the call succeeds, the stream is disassociated from + * the file. + * + * \return zero if the stream was successfully closed, or EOF if any any + * errors are detected. + */ + int fclose(); + //---------------------------------------------------------------------------- + /** Test the stream's end-of-file indicator. + * \return non-zero if and only if the end-of-file indicator is set. + */ + int feof() { + return (m_flags & F_EOF) != 0; + } + //---------------------------------------------------------------------------- + /** Test the stream's error indicator. + * \return return non-zero if and only if the error indicator is set. + */ + int ferror() { + return (m_flags & F_ERR) != 0; + } + //---------------------------------------------------------------------------- + /** Flush the stream. + * + * If stream is an output stream or an update stream in which the most + * recent operation was not input, any unwritten data is written to the + * file; otherwise the call is an error since any buffered input data + * would be lost. + * + * \return sets the error indicator for the stream and returns EOF if an + * error occurs, otherwise it returns zero. + */ + int fflush(); + //---------------------------------------------------------------------------- + /** Get a byte from the stream. + * + * \return If the end-of-file indicator for the stream is set, or if the + * stream is at end-of-file, the end-of-file indicator for the stream is + * set and the fgetc function returns EOF. Otherwise, the fgetc function + * returns the next character from the input stream. + */ + int fgetc() { + return m_r-- == 0 ? fillGet() : *m_p++; + } + //---------------------------------------------------------------------------- + /** Get a string from a stream. + * + * The fgets function reads at most one less than the number of + * characters specified by num from the stream into the array pointed + * to by str. No additional characters are read after a new-line + * character (which is retained) or after end-of-file. A null character + * is written immediately after the last character read into the array. + * + * \param[out] str Pointer to an array of where the string is copied. + * + * \param[in] num Maximum number of characters including the null + * character. + * + * \param[out] len If len is not null and fgets is successful, the + * length of the string is returned. + * + * \return str if successful. If end-of-file is encountered and no + * characters have been read into the array, the contents of the array + * remain unchanged and a null pointer is returned. If a read error + * occurs during the operation, the array contents are indeterminate + * and a null pointer is returned. + */ + char* fgets(char* str, size_t num, size_t* len = 0); + //---------------------------------------------------------------------------- + /** Open a stream. + * + * Open a file and associates the stream with it. + * + * \param[in] path file to be opened. + * + * \param[in] mode a string that indicates the open mode. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
"r" or "rb"Open a file for reading. The file must exist.
"w" or "wb"Truncate an existing to zero length or create an empty file + * for writing.
"wx" or "wbx"Create a file for writing. Fails if the file already exists.
"a" or "ab"Append; open or create file for writing at end-of-file.
"r+" or "rb+" or "r+b"Open a file for update (reading and writing).
"w+" or "w+b" or "wb+"Truncate an existing to zero length or create a file for update.
"w+x" or "w+bx" or "wb+x"Create a file for update. Fails if the file already exists.
"a+" or "a+b" or "ab+"Append; open or create a file for update, writing at end-of-file.
+ * The character 'b' shall have no effect, but is allowed for ISO C + * standard conformance. + * + * Opening a file with append mode causes all subsequent writes to the + * file to be forced to the then current end-of-file, regardless of + * intervening calls to the fseek function. + * + * When a file is opened with update mode, both input and output may be + * performed on the associated stream. However, output shall not be + * directly followed by input without an intervening call to the fflush + * function or to a file positioning function (fseek, or rewind), and + * input shall not be directly followed by output without an intervening + * call to a file positioning function, unless the input operation + * encounters end-of-file. + * + * \return true for success or false for failure. + */ + bool fopen(const char* path, const char * mode); + //---------------------------------------------------------------------------- + /** Write a byte to a stream. + * + * \param[in] c the byte to be written (converted to an unsigned char). + * + * \return Upon successful completion, fputc() returns the value it + * has written. Otherwise, it returns EOF and sets the error indicator for + * the stream. + */ + int fputc(int c) { + return m_w-- == 0 ? flushPut(c) : *m_p++ = c; + } + //---------------------------------------------------------------------------- + /** Write a string to a stream. + * + * \param[in] str a pointer to the string to be written. + * + * \return for success, fputs() returns a non-negative + * number. Otherwise, it returns EOF and sets the error indicator for + * the stream. + */ + int fputs(const char* str); + //---------------------------------------------------------------------------- + /** Binary input. + * + * Reads an array of up to count elements, each one with a size of size + * bytes. + * \param[out] ptr pointer to area of at least (size*count) bytes where + * the data will be stored. + * + * \param[in] size the size, in bytes, of each element to be read. + * + * \param[in] count the number of elements to be read. + * + * \return number of elements successfully read, which may be less than + * count if a read error or end-of-file is encountered. If size or count + * is zero, fread returns zero and the contents of the array and the + * state of the stream remain unchanged. + */ + size_t fread(void* ptr, size_t size, size_t count); + //---------------------------------------------------------------------------- + /** Set the file position for the stream. + * + * \param[in] offset number of offset from the origin. + * + * \param[in] origin position used as reference for the offset. It is + * specified by one of the following constants. + * + * SEEK_SET - Beginning of file. + * + * SEEK_CUR - Current position of the file pointer. + * + * SEEK_END - End of file. + * + * \return zero for success. Otherwise, it returns non-zero and sets the + * error indicator for the stream. + */ + int fseek(int32_t offset, int origin); + //---------------------------------------------------------------------------- + /** Get the current position in a stream. + * + * \return If successful, ftell return the current value of the position + * indicator. On failure, ftell returns −1L. + */ + int32_t ftell(); + //---------------------------------------------------------------------------- + /** Binary output. + * + * Writes an array of up to count elements, each one with a size of size + * bytes. + * \param[in] ptr pointer to (size*count) bytes of data to be written. + * + * \param[in] size the size, in bytes, of each element to be written. + * + * \param[in] count the number of elements to be written. + * + * \return number of elements successfully written. if this number is + * less than count, an error has occurred. If size or count is zero, + * fwrite returns zero. + */ + size_t fwrite(const void * ptr, size_t size, size_t count); + //---------------------------------------------------------------------------- + /** Get a byte from the stream. + * + * getc and fgetc are equivalent but getc is in-line so it is faster but + * require more flash memory. + * + * \return If the end-of-file indicator for the stream is set, or if the + * stream is at end-of-file, the end-of-file indicator for the stream is + * set and the fgetc function returns EOF. Otherwise, the fgetc function + * returns the next character from the input stream. + */ + inline __attribute__((always_inline)) + int getc() { + return m_r-- == 0 ? fillGet() : *m_p++; + } + //---------------------------------------------------------------------------- + /** Write a byte to a stream. + * + * putc and fputc are equivalent but putc is in-line so it is faster but + * require more flash memory. + * + * \param[in] c the byte to be written (converted to an unsigned char). + * + * \return Upon successful completion, fputc() returns the value it + * has written. Otherwise, it returns EOF and sets the error indicator for + * the stream. + */ + inline __attribute__((always_inline)) + int putc(int c) { + return m_w-- == 0 ? flushPut(c) : *m_p++ = c; + } + //---------------------------------------------------------------------------- + /** Write a CR/LF. + * + * \return two, the number of bytes written, for success or -1 for failure. + */ + inline __attribute__((always_inline)) + int putCRLF() { + if (m_w < 2) { + if (!flushBuf()) { + return -1; + } + } + *m_p++ = '\r'; + *m_p++ = '\n'; + m_w -= 2; + return 2; + } + //---------------------------------------------------------------------------- + /** Write a character. + * \param[in] c the character to write. + * \return the number of bytes written. + */ + size_t print(char c) { + return putc(c) < 0 ? 0 : 1; + } + //---------------------------------------------------------------------------- + /** Write a string. + * + * \param[in] str the string to be written. + * + * \return the number of bytes written. + */ + size_t print(const char* str) { + int n = fputs(str); + return n < 0 ? 0 : n; + } + //---------------------------------------------------------------------------- +#if (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) + /** Print a string stored in flash memory. + * + * \param[in] str the string to print. + * + * \return the number of bytes written. + */ + size_t print(const __FlashStringHelper *str); +#endif // (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) + //---------------------------------------------------------------------------- + /** Print a floating point number. + * + * \param[in] prec Number of digits after decimal point. + * + * \param[in] val the number to be printed. + * + * \return the number of bytes written. + */ + size_t print(double val, uint8_t prec = 2) { + return print(static_cast(val), prec); + } + //---------------------------------------------------------------------------- + /** Print a floating point number. + * + * \param[in] prec Number of digits after decimal point. + * + * \param[in] val the number to be printed. + * + * \return the number of bytes written. + */ + size_t print(float val, uint8_t prec = 2) { + int n = printDec(val, prec); + return n > 0 ? n : 0; + } + //---------------------------------------------------------------------------- + /** Print a number. + * + * \param[in] val the number to be printed. + * + * \return the number of bytes written. + */ + template + size_t print(T val) { + int n = printDec(val); + return n > 0 ? n : 0; + } + //---------------------------------------------------------------------------- + /** Write a CR/LF. + * + * \return two, the number of bytes written, for success or zero for failure. + */ + size_t println() { + return putCRLF() > 0 ? 2 : 0; + } + //---------------------------------------------------------------------------- + /** Print a floating point number followed by CR/LF. + * + * \param[in] val the number to be printed. + * + * \param[in] prec Number of digits after decimal point. + * + * \return the number of bytes written. + */ + size_t println(double val, uint8_t prec = 2) { + return println(static_cast(val), prec); + } + //---------------------------------------------------------------------------- + /** Print a floating point number followed by CR/LF. + * + * \param[in] val the number to be printed. + * + * \param[in] prec Number of digits after decimal point. + * + * \return the number of bytes written. + */ + size_t println(float val, uint8_t prec = 2) { + int n = printDec(val, prec); + return n > 0 && putCRLF() > 0 ? n + 2 : 0; + } + //---------------------------------------------------------------------------- + /** Print an item followed by CR/LF + * + * \param[in] val the item to be printed. + * + * \return the number of bytes written. + */ + template + size_t println(T val) { + int n = print(val); + return putCRLF() > 0 ? n + 2 : 0; + } + //---------------------------------------------------------------------------- + /** Print a char as a number. + * \param[in] n number to be printed. + * \return The number of bytes written or -1 if an error occurs. + */ + int printDec(char n) { + if (CHAR_MIN == 0) { + return printDec((unsigned char)n); + } else { + return printDec((signed char)n); + } + } + //---------------------------------------------------------------------------- + /** print a signed 8-bit integer + * \param[in] n number to be printed. + * \return The number of bytes written or -1 if an error occurs. + */ + int printDec(signed char n); + //---------------------------------------------------------------------------- + /** Print an unsigned 8-bit number. + * \param[in] n number to be print. + * \return The number of bytes written or -1 if an error occurs. + */ + int printDec(unsigned char n) { + return printDec((uint16_t)n); + } + //---------------------------------------------------------------------------- + /** Print a int16_t + * \param[in] n number to be printed. + * \return The number of bytes written or -1 if an error occurs. + */ + int printDec(int16_t n); + //---------------------------------------------------------------------------- + /** print a uint16_t. + * \param[in] n number to be printed. + * \return The number of bytes written or -1 if an error occurs. + */ + int printDec(uint16_t n); + //---------------------------------------------------------------------------- + /** Print a signed 32-bit integer. + * \param[in] n number to be printed. + * \return The number of bytes written or -1 if an error occurs. + */ + int printDec(int32_t n); + //---------------------------------------------------------------------------- + /** Write an unsigned 32-bit number. + * \param[in] n number to be printed. + * \return The number of bytes written or -1 if an error occurs. + */ + int printDec(uint32_t n); + //---------------------------------------------------------------------------- + /** Print a double. + * \param[in] value The number to be printed. + * \param[in] prec Number of digits after decimal point. + * \return The number of bytes written or -1 if an error occurs. + */ + int printDec(double value, uint8_t prec) { + return printDec(static_cast(value), prec); + } + //---------------------------------------------------------------------------- + /** Print a float. + * \param[in] value The number to be printed. + * \param[in] prec Number of digits after decimal point. + * \return The number of bytes written or -1 if an error occurs. + */ + int printDec(float value, uint8_t prec); + //---------------------------------------------------------------------------- + /** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. + * \param[in] prec Number of digits after decimal point. + * \return The number of bytes written or -1 if an error occurs. + */ + int printField(double value, char term, uint8_t prec = 2) { + return printField(static_cast(value), term, prec) > 0; + } + //---------------------------------------------------------------------------- + /** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. + * \param[in] prec Number of digits after decimal point. + * \return The number of bytes written or -1 if an error occurs. + */ + int printField(float value, char term, uint8_t prec = 2) { + int rtn = printDec(value, prec); + return rtn < 0 || putc(term) < 0 ? -1 : rtn + 1; + } + //---------------------------------------------------------------------------- + /** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. + * \return The number of bytes written or -1 if an error occurs. + */ + template + int printField(T value, char term) { + int rtn = printDec(value); + return rtn < 0 || putc(term) < 0 ? -1 : rtn + 1; + } + //---------------------------------------------------------------------------- + /** Print HEX + * \param[in] n number to be printed as HEX. + * + * \return The number of bytes written or -1 if an error occurs. + */ + int printHex(uint32_t n); + //---------------------------------------------------------------------------- + /** Print HEX with CRLF + * \param[in] n number to be printed as HEX. + * + * \return The number of bytes written or -1 if an error occurs. + */ + int printHexln(uint32_t n) { + int rtn = printHex(n); + return rtn < 0 || putCRLF() != 2 ? -1 : rtn + 2; + } + //---------------------------------------------------------------------------- + /** Set position of a stream to the beginning. + * + * The rewind function sets the file position to the beginning of the + * file. It is equivalent to fseek(0L, SEEK_SET) except that the error + * indicator for the stream is also cleared. + * + * \return true for success or false for failure. + */ + bool rewind(); + //---------------------------------------------------------------------------- + /** Push a byte back into an input stream. + * + * \param[in] c the byte (converted to an unsigned char) to be pushed back. + * + * One character of push-back is guaranteed. If the ungetc function is + * called too many times without an intervening read or file positioning + * operation on that stream, the operation may fail. + * + * A successful intervening call to a file positioning function (fseek, + * fsetpos, or rewind) discards any pushed-back characters for the stream. + * + * \return Upon successful completion, ungetc() returns the byte pushed + * back after conversion. Otherwise it returns EOF. + */ + int ungetc(int c); + //============================================================================ + private: + bool fillBuf(); + int fillGet(); + bool flushBuf(); + int flushPut(uint8_t c); + char* fmtSpace(uint8_t len); + int write(const void* buf, size_t count); + //---------------------------------------------------------------------------- + // F_SRD and F_WR are never simultaneously asserted + static const uint8_t F_SRD = 0x01; // OK to read + static const uint8_t F_SWR = 0x02; // OK to write + static const uint8_t F_SRW = 0x04; // open for reading & writing + static const uint8_t F_EOF = 0x10; // found EOF + static const uint8_t F_ERR = 0x20; // found error + //---------------------------------------------------------------------------- + uint8_t m_flags; + uint8_t* m_p; + uint8_t m_r; + uint8_t m_w; + uint8_t m_buf[STREAM_BUF_SIZE]; +}; +//------------------------------------------------------------------------------ +#endif // StdioStream_h diff --git a/libraries/SdFat/src/FatLib/bufstream.h b/libraries/SdFat/src/FatLib/bufstream.h new file mode 100644 index 0000000..8b49701 --- /dev/null +++ b/libraries/SdFat/src/FatLib/bufstream.h @@ -0,0 +1,167 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef bufstream_h +#define bufstream_h +/** + * \file + * \brief \ref ibufstream and \ref obufstream classes + */ +#include +#include "iostream.h" +//============================================================================== +/** + * \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) { + (void)off; + (void)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) { + (void)off; + (void)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/libraries/SdFat/src/FatLib/fstream.cpp b/libraries/SdFat/src/FatLib/fstream.cpp new file mode 100644 index 0000000..505f083 --- /dev/null +++ b/libraries/SdFat/src/FatLib/fstream.cpp @@ -0,0 +1,167 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#include "fstream.h" +//============================================================================== +/// @cond SHOW_PROTECTED +int16_t FatStreamBase::getch() { + uint8_t c; + int8_t s = read(&c, 1); + if (s != 1) { + if (s < 0) { + setstate(badbit); + } else { + setstate(eofbit); + } + return -1; + } + if (c != '\r' || (getmode() & ios::binary)) { + return c; + } + s = read(&c, 1); + if (s == 1 && c == '\n') { + return c; + } + if (s == 1) { + seekCur(-1); + } + return '\r'; +} +//------------------------------------------------------------------------------ +void FatStreamBase::open(const char* path, ios::openmode mode) { + uint8_t flags; + switch (mode & (app | in | out | trunc)) { + case app | in: + case app | in | out: + flags = O_RDWR | O_APPEND | O_CREAT; + break; + + case app: + case app | out: + flags = O_WRITE | O_APPEND | O_CREAT; + break; + + case in: + flags = O_READ; + break; + + case in | out: + flags = O_RDWR; + break; + + case in | out | trunc: + flags = O_RDWR | O_TRUNC | O_CREAT; + break; + + case out: + case out | trunc: + flags = O_WRITE | O_TRUNC | O_CREAT; + break; + + default: + goto fail; + } + if (mode & ios::ate) { + flags |= O_AT_END; + } + if (!FatFile::open(path, flags)) { + goto fail; + } + setmode(mode); + clear(); + return; + +fail: + FatFile::close(); + setstate(failbit); + return; +} +//------------------------------------------------------------------------------ +void FatStreamBase::putch(char c) { + if (c == '\n' && !(getmode() & ios::binary)) { + write('\r'); + } + write(c); + if (getWriteError()) { + setstate(badbit); + } +} +//------------------------------------------------------------------------------ +void FatStreamBase::putstr(const char* str) { + size_t n = 0; + while (1) { + char c = str[n]; + if (c == '\0' || (c == '\n' && !(getmode() & ios::binary))) { + if (n > 0) { + write(str, n); + } + if (c == '\0') { + break; + } + write('\r'); + str += n; + n = 0; + } + n++; + } + if (getWriteError()) { + setstate(badbit); + } +} +//------------------------------------------------------------------------------ +/** Internal do not use + * \param[in] off + * \param[in] way + */ +bool FatStreamBase::seekoff(off_type off, seekdir way) { + pos_type pos; + switch (way) { + case beg: + pos = off; + break; + + case cur: + pos = curPosition() + off; + break; + + case end: + pos = fileSize() + off; + break; + + default: + return false; + } + return seekpos(pos); +} +//------------------------------------------------------------------------------ +/** Internal do not use + * \param[in] pos + */ +bool FatStreamBase::seekpos(pos_type pos) { + return seekSet(pos); +} +//------------------------------------------------------------------------------ +int FatStreamBase::write(const void* buf, size_t n) { + return FatFile::write(buf, n); +} +//------------------------------------------------------------------------------ +void FatStreamBase::write(char c) { + write(&c, 1); +} +/// @endcond diff --git a/libraries/SdFat/src/FatLib/fstream.h b/libraries/SdFat/src/FatLib/fstream.h new file mode 100644 index 0000000..5410c38 --- /dev/null +++ b/libraries/SdFat/src/FatLib/fstream.h @@ -0,0 +1,315 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef fstream_h +#define fstream_h +/** + * \file + * \brief \ref fstream, \ref ifstream, and \ref ofstream classes + */ +#include "FatFile.h" +#include "iostream.h" +//============================================================================== +/** + * \class FatStreamBase + * \brief Base class for C++ style streams + */ +class FatStreamBase : protected FatFile, virtual public ios { + protected: + /// @cond SHOW_PROTECTED + int16_t getch(); + void putch(char c); + void putstr(const char *str); + void open(const char* path, ios::openmode mode); + /** Internal do not use + * \return mode + */ + ios::openmode getmode() { + return m_mode; + } + /** Internal do not use + * \param[in] mode + */ + void setmode(ios::openmode mode) { + m_mode = mode; + } + bool seekoff(off_type off, seekdir way); + bool seekpos(pos_type pos); + int write(const void* buf, size_t n); + void write(char c); + /// @endcond + private: + ios::openmode m_mode; +}; +//============================================================================== +/** + * \class fstream + * \brief file input/output stream. + */ +class fstream : public iostream, FatStreamBase { + public: + using iostream::peek; + fstream() {} + /** Constructor with open + * + * \param[in] path path to open + * \param[in] mode open mode + */ + explicit fstream(const char* path, openmode mode = in | out) { + open(path, mode); + } +#if DESTRUCTOR_CLOSES_FILE + ~fstream() {} +#endif // DESTRUCTOR_CLOSES_FILE + /** Clear state and writeError + * \param[in] state new state for stream + */ + void clear(iostate state = goodbit) { + ios::clear(state); + FatFile::clearWriteError(); + } + /** Close a file and force cached data and directory information + * to be written to the storage device. + */ + void close() { + FatFile::close(); + } + /** Open a fstream + * \param[in] path file to open + * \param[in] mode open mode + * + * Valid open modes are (at end, ios::ate, and/or ios::binary may be added): + * + * ios::in - Open file for reading. + * + * ios::out or ios::out | ios::trunc - Truncate to 0 length, if existent, + * or create a file for writing only. + * + * ios::app or ios::out | ios::app - Append; open or create file for + * writing at end-of-file. + * + * ios::in | ios::out - Open file for update (reading and writing). + * + * ios::in | ios::out | ios::trunc - Truncate to zero length, if existent, + * or create file for update. + * + * ios::in | ios::app or ios::in | ios::out | ios::app - Append; open or + * create text file for update, writing at end of file. + */ + void open(const char* path, openmode mode = in | out) { + FatStreamBase::open(path, mode); + } + /** \return True if stream is open else false. */ + bool is_open() { + return FatFile::isOpen(); + } + + protected: + /// @cond SHOW_PROTECTED + /** Internal - do not use + * \return + */ + int16_t getch() { + return FatStreamBase::getch(); + } + /** Internal - do not use + * \param[out] pos + */ + void getpos(FatPos_t* pos) { + FatFile::getpos(pos); + } + /** Internal - do not use + * \param[in] c + */ + void putch(char c) { + FatStreamBase::putch(c); + } + /** Internal - do not use + * \param[in] str + */ + void putstr(const char *str) { + FatStreamBase::putstr(str); + } + /** Internal - do not use + * \param[in] pos + */ + bool seekoff(off_type off, seekdir way) { + return FatStreamBase::seekoff(off, way); + } + bool seekpos(pos_type pos) { + return FatStreamBase::seekpos(pos); + } + void setpos(FatPos_t* pos) { + FatFile::setpos(pos); + } + bool sync() { + return FatStreamBase::sync(); + } + pos_type tellpos() { + return FatStreamBase::curPosition(); + } + /// @endcond +}; +//============================================================================== +/** + * \class ifstream + * \brief file input stream. + */ +class ifstream : public istream, FatStreamBase { + public: + using istream::peek; + ifstream() {} + /** Constructor with open + * \param[in] path file to open + * \param[in] mode open mode + */ + explicit ifstream(const char* path, openmode mode = in) { + open(path, mode); + } +#if DESTRUCTOR_CLOSES_FILE + ~ifstream() {} +#endif // DESTRUCTOR_CLOSES_FILE + /** Close a file and force cached data and directory information + * to be written to the storage device. + */ + void close() { + FatFile::close(); + } + /** \return True if stream is open else false. */ + bool is_open() { + return FatFile::isOpen(); + } + /** Open an ifstream + * \param[in] path file to open + * \param[in] mode open mode + * + * \a mode See fstream::open() for valid modes. + */ + void open(const char* path, openmode mode = in) { + FatStreamBase::open(path, mode | in); + } + + protected: + /// @cond SHOW_PROTECTED + /** Internal - do not use + * \return + */ + int16_t getch() { + return FatStreamBase::getch(); + } + /** Internal - do not use + * \param[out] pos + */ + void getpos(FatPos_t* pos) { + FatFile::getpos(pos); + } + /** Internal - do not use + * \param[in] pos + */ + bool seekoff(off_type off, seekdir way) { + return FatStreamBase::seekoff(off, way); + } + bool seekpos(pos_type pos) { + return FatStreamBase::seekpos(pos); + } + void setpos(FatPos_t* pos) { + FatFile::setpos(pos); + } + pos_type tellpos() { + return FatStreamBase::curPosition(); + } + /// @endcond +}; +//============================================================================== +/** + * \class ofstream + * \brief file output stream. + */ +class ofstream : public ostream, FatStreamBase { + public: + ofstream() {} + /** Constructor with open + * \param[in] path file to open + * \param[in] mode open mode + */ + explicit ofstream(const char* path, ios::openmode mode = out) { + open(path, mode); + } +#if DESTRUCTOR_CLOSES_FILE + ~ofstream() {} +#endif // DESTRUCTOR_CLOSES_FILE + /** Clear state and writeError + * \param[in] state new state for stream + */ + void clear(iostate state = goodbit) { + ios::clear(state); + FatFile::clearWriteError(); + } + /** Close a file and force cached data and directory information + * to be written to the storage device. + */ + void close() { + FatFile::close(); + } + /** Open an ofstream + * \param[in] path file to open + * \param[in] mode open mode + * + * \a mode See fstream::open() for valid modes. + */ + void open(const char* path, openmode mode = out) { + FatStreamBase::open(path, mode | out); + } + /** \return True if stream is open else false. */ + bool is_open() { + return FatFile::isOpen(); + } + + protected: + /// @cond SHOW_PROTECTED + /** + * Internal do not use + * \param[in] c + */ + void putch(char c) { + FatStreamBase::putch(c); + } + void putstr(const char* str) { + FatStreamBase::putstr(str); + } + bool seekoff(off_type off, seekdir way) { + return FatStreamBase::seekoff(off, way); + } + bool seekpos(pos_type pos) { + return FatStreamBase::seekpos(pos); + } + /** + * Internal do not use + * \param[in] b + */ + bool sync() { + return FatStreamBase::sync(); + } + pos_type tellpos() { + return FatStreamBase::curPosition(); + } + /// @endcond +}; +//------------------------------------------------------------------------------ +#endif // fstream_h diff --git a/libraries/SdFat/src/FatLib/ios.h b/libraries/SdFat/src/FatLib/ios.h new file mode 100644 index 0000000..d89d96c --- /dev/null +++ b/libraries/SdFat/src/FatLib/ios.h @@ -0,0 +1,418 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#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(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/libraries/SdFat/src/FatLib/iostream.h b/libraries/SdFat/src/FatLib/iostream.h new file mode 100644 index 0000000..deeae6e --- /dev/null +++ b/libraries/SdFat/src/FatLib/iostream.h @@ -0,0 +1,153 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef iostream_h +#define iostream_h +/** + * \file + * \brief \ref iostream class + */ +#include "istream.h" +#include "ostream.h" +/** 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 diff --git a/libraries/SdFat/src/FatLib/istream.cpp b/libraries/SdFat/src/FatLib/istream.cpp new file mode 100644 index 0000000..9485099 --- /dev/null +++ b/libraries/SdFat/src/FatLib/istream.cpp @@ -0,0 +1,391 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +// #include +#include +#include +#include "istream.h" +//------------------------------------------------------------------------------ +int istream::get() { + int c; + m_gcount = 0; + c = getch(); + if (c < 0) { + setstate(failbit); + } else { + m_gcount = 1; + } + return c; +} +//------------------------------------------------------------------------------ +istream& istream::get(char& c) { + int tmp = get(); + if (tmp >= 0) { + c = tmp; + } + return *this; +} +//------------------------------------------------------------------------------ +istream& istream::get(char *str, streamsize n, char delim) { + int c; + FatPos_t pos; + m_gcount = 0; + while ((m_gcount + 1) < n) { + c = getch(&pos); + if (c < 0) { + break; + } + if (c == delim) { + setpos(&pos); + break; + } + str[m_gcount++] = c; + } + if (n > 0) { + str[m_gcount] = '\0'; + } + if (m_gcount == 0) { + setstate(failbit); + } + return *this; +} +//------------------------------------------------------------------------------ +void istream::getBool(bool *b) { + if ((flags() & boolalpha) == 0) { + getNumber(b); + return; + } +#ifdef __AVR__ + PGM_P truePtr = PSTR("true"); + PGM_P falsePtr = PSTR("false"); +#else // __AVR__ + const char* truePtr = "true"; + const char* falsePtr = "false"; +#endif // __AVR + const uint8_t true_len = 4; + const uint8_t false_len = 5; + bool trueOk = true; + bool falseOk = true; + uint8_t i = 0; + int c = readSkip(); + while (1) { +#ifdef __AVR__ + falseOk = falseOk && c == pgm_read_byte(falsePtr + i); + trueOk = trueOk && c == pgm_read_byte(truePtr + i); +#else // __AVR__ + falseOk = falseOk && c == falsePtr[i]; + trueOk = trueOk && c == truePtr[i]; +#endif // __AVR__ + if (trueOk == false && falseOk == false) { + break; + } + i++; + if (trueOk && i == true_len) { + *b = true; + return; + } + if (falseOk && i == false_len) { + *b = false; + return; + } + c = getch(); + } + setstate(failbit); +} +//------------------------------------------------------------------------------ +void istream::getChar(char* ch) { + int16_t c = readSkip(); + if (c < 0) { + setstate(failbit); + } else { + *ch = c; + } +} +//------------------------------------------------------------------------------ +// +// http://www.exploringbinary.com/category/numbers-in-computers/ +// +int16_t const EXP_LIMIT = 100; +static const uint32_t uint32_max = (uint32_t)-1; +bool istream::getDouble(double* value) { + bool got_digit = false; + bool got_dot = false; + bool neg; + int16_t c; + bool expNeg = false; + int16_t exp = 0; + int16_t fracExp = 0; + uint32_t frac = 0; + FatPos_t endPos; + double pow10; + double v; + + getpos(&endPos); + c = readSkip(); + neg = c == '-'; + if (c == '-' || c == '+') { + c = getch(); + } + while (1) { + if (isdigit(c)) { + got_digit = true; + if (frac < uint32_max/10) { + frac = frac * 10 + (c - '0'); + if (got_dot) { + fracExp--; + } + } else { + if (!got_dot) { + fracExp++; + } + } + } else if (!got_dot && c == '.') { + got_dot = true; + } else { + break; + } + if (fracExp < -EXP_LIMIT || fracExp > EXP_LIMIT) { + goto fail; + } + c = getch(&endPos); + } + if (!got_digit) { + goto fail; + } + if (c == 'e' || c == 'E') { + c = getch(); + expNeg = c == '-'; + if (c == '-' || c == '+') { + c = getch(); + } + while (isdigit(c)) { + if (exp > EXP_LIMIT) { + goto fail; + } + exp = exp * 10 + (c - '0'); + c = getch(&endPos); + } + } + v = static_cast(frac); + exp = expNeg ? fracExp - exp : fracExp + exp; + expNeg = exp < 0; + if (expNeg) { + exp = -exp; + } + pow10 = 10.0; + while (exp) { + if (exp & 1) { + if (expNeg) { + // check for underflow + if (v < FLT_MIN * pow10 && frac != 0) { + goto fail; + } + v /= pow10; + } else { + // check for overflow + if (v > FLT_MAX / pow10) { + goto fail; + } + v *= pow10; + } + } + pow10 *= pow10; + exp >>= 1; + } + setpos(&endPos); + *value = neg ? -v : v; + return true; + +fail: + // error restore position to last good place + setpos(&endPos); + setstate(failbit); + return false; +} +//------------------------------------------------------------------------------ + +istream& istream::getline(char *str, streamsize n, char delim) { + FatPos_t pos; + int c; + m_gcount = 0; + if (n > 0) { + str[0] = '\0'; + } + while (1) { + c = getch(&pos); + if (c < 0) { + break; + } + if (c == delim) { + m_gcount++; + break; + } + if ((m_gcount + 1) >= n) { + setpos(&pos); + setstate(failbit); + break; + } + str[m_gcount++] = c; + str[m_gcount] = '\0'; + } + if (m_gcount == 0) { + setstate(failbit); + } + return *this; +} +//------------------------------------------------------------------------------ +bool istream::getNumber(uint32_t posMax, uint32_t negMax, uint32_t* num) { + int16_t c; + int8_t any = 0; + int8_t have_zero = 0; + uint8_t neg; + uint32_t val = 0; + uint32_t cutoff; + uint8_t cutlim; + FatPos_t endPos; + uint8_t f = flags() & basefield; + uint8_t base = f == oct ? 8 : f != hex ? 10 : 16; + getpos(&endPos); + c = readSkip(); + + neg = c == '-' ? 1 : 0; + if (c == '-' || c == '+') { + c = getch(); + } + + if (base == 16 && c == '0') { // TESTSUITE + c = getch(&endPos); + if (c == 'X' || c == 'x') { + c = getch(); + // remember zero in case no hex digits follow x/X + have_zero = 1; + } else { + any = 1; + } + } + // set values for overflow test + cutoff = neg ? negMax : posMax; + cutlim = cutoff % base; + cutoff /= base; + + while (1) { + if (isdigit(c)) { + c -= '0'; + } else if (isalpha(c)) { + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + } else { + break; + } + if (c >= base) { + break; + } + if (val > cutoff || (val == cutoff && c > cutlim)) { + // indicate overflow error + any = -1; + break; + } + val = val * base + c; + c = getch(&endPos); + any = 1; + } + setpos(&endPos); + if (any > 0 || (have_zero && any >= 0)) { + *num = neg ? -val : val; + return true; + } + setstate(failbit); + return false; +} +//------------------------------------------------------------------------------ +void istream::getStr(char *str) { + FatPos_t pos; + uint16_t i = 0; + uint16_t m = width() ? width() - 1 : 0XFFFE; + if (m != 0) { + getpos(&pos); + int c = readSkip(); + + while (i < m) { + if (c < 0) { + break; + } + if (isspace(c)) { + setpos(&pos); + break; + } + str[i++] = c; + c = getch(&pos); + } + } + str[i] = '\0'; + if (i == 0) { + setstate(failbit); + } + width(0); +} +//------------------------------------------------------------------------------ +istream& istream::ignore(streamsize n, int delim) { + int c; + m_gcount = 0; + while (m_gcount < n) { + c = getch(); + if (c < 0) { + break; + } + m_gcount++; + if (c == delim) { + break; + } + } + return *this; +} +//------------------------------------------------------------------------------ +int istream::peek() { + int16_t c; + FatPos_t pos; + m_gcount = 0; + getpos(&pos); + c = getch(); + if (c < 0) { + if (!bad()) { + setstate(eofbit); + } + } else { + setpos(&pos); + } + return c; +} +//------------------------------------------------------------------------------ +int16_t istream::readSkip() { + int16_t c; + do { + c = getch(); + } while (isspace(c) && (flags() & skipws)); + return c; +} +//------------------------------------------------------------------------------ +/** used to implement ws() */ +void istream::skipWhite() { + int c; + FatPos_t pos; + do { + c = getch(&pos); + } while (isspace(c)); + setpos(&pos); +} diff --git a/libraries/SdFat/src/FatLib/istream.h b/libraries/SdFat/src/FatLib/istream.h new file mode 100644 index 0000000..4075507 --- /dev/null +++ b/libraries/SdFat/src/FatLib/istream.h @@ -0,0 +1,379 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef istream_h +#define istream_h +/** + * \file + * \brief \ref istream class + */ +#include "ios.h" + +/** + * \class istream + * \brief Input Stream + */ +class istream : public virtual ios { + public: + istream() {} + /** call manipulator + * \param[in] pf function to call + * \return the stream + */ + istream& operator>>(istream& (*pf)(istream& str)) { + return pf(*this); + } + /** call manipulator + * \param[in] pf function to call + * \return the stream + */ + istream& operator>>(ios_base& (*pf)(ios_base& str)) { + pf(*this); + return *this; + } + /** call manipulator + * \param[in] pf function to call + * \return the stream + */ + istream& operator>>(ios& (*pf)(ios& str)) { + pf(*this); + return *this; + } + /** + * Extract a character string + * \param[out] str location to store the string. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream& operator>>(char *str) { + getStr(str); + return *this; + } + /** + * Extract a character + * \param[out] ch location to store the character. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream& operator>>(char& ch) { + getChar(&ch); + return *this; + } + /** + * Extract a character string + * \param[out] str location to store the string. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream& operator>>(signed char *str) { + getStr(reinterpret_cast(str)); + return *this; + } + /** + * Extract a character + * \param[out] ch location to store the character. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream& operator>>(signed char& ch) { + getChar(reinterpret_cast(&ch)); + return *this; + } + /** + * Extract a character string + * \param[out] str location to store the string. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream& operator>>(unsigned char *str) { + getStr(reinterpret_cast(str)); + return *this; + } + /** + * Extract a character + * \param[out] ch location to store the character. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream& operator>>(unsigned char& ch) { + getChar(reinterpret_cast(&ch)); + return *this; + } + /** + * Extract a value of type bool. + * \param[out] arg location to store the value. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream& operator>>(bool& arg) { + getBool(&arg); + return *this; + } + /** + * Extract a value of type short. + * \param[out] arg location to store the value. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream &operator>>(short& arg) { // NOLINT + getNumber(&arg); + return *this; + } + /** + * Extract a value of type unsigned short. + * \param[out] arg location to store the value. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream &operator>>(unsigned short& arg) { // NOLINT + getNumber(&arg); + return *this; + } + /** + * Extract a value of type int. + * \param[out] arg location to store the value. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream &operator>>(int& arg) { + getNumber(&arg); + return *this; + } + /** + * Extract a value of type unsigned int. + * \param[out] arg location to store the value. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream &operator>>(unsigned int& arg) { + getNumber(&arg); + return *this; + } + /** + * Extract a value of type long. + * \param[out] arg location to store the value. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream &operator>>(long& arg) { // NOLINT + getNumber(&arg); + return *this; + } + /** + * Extract a value of type unsigned long. + * \param[out] arg location to store the value. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream &operator>>(unsigned long& arg) { // NOLINT + getNumber(&arg); + return *this; + } + /** + * Extract a value of type double. + * \param[out] arg location to store the value. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream &operator>> (double& arg) { + getDouble(&arg); + return *this; + } + /** + * Extract a value of type float. + * \param[out] arg location to store the value. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream &operator>> (float& arg) { + double v; + getDouble(&v); + arg = v; + return *this; + } + /** + * Extract a value of type void*. + * \param[out] arg location to store the value. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream& operator>> (void*& arg) { + uint32_t val; + getNumber(&val); + arg = reinterpret_cast(val); + return *this; + } + /** + * \return The number of characters extracted by the last unformatted + * input function. + */ + streamsize gcount() const { + return m_gcount; + } + /** + * Extract a character if one is available. + * + * \return The character or -1 if a failure occurs. A failure is indicated + * by the stream state. + */ + int get(); + /** + * Extract a character if one is available. + * + * \param[out] ch location to receive the extracted character. + * + * \return always returns *this. A failure is indicated by the stream state. + */ + istream& get(char& ch); + /** + * Extract characters. + * + * \param[out] str Location to receive extracted characters. + * \param[in] n Size of str. + * \param[in] delim Delimiter + * + * Characters are extracted until extraction fails, n is less than 1, + * n-1 characters are extracted, or the next character equals + * \a delim (delim is not extracted). If no characters are extracted + * failbit is set. If end-of-file occurs the eofbit is set. + * + * \return always returns *this. A failure is indicated by the stream state. + */ + istream& get(char *str, streamsize n, char delim = '\n'); + /** + * Extract characters + * + * \param[out] str Location to receive extracted characters. + * \param[in] n Size of str. + * \param[in] delim Delimiter + * + * Characters are extracted until extraction fails, + * the next character equals \a delim (delim is extracted), or n-1 + * characters are extracted. + * + * The failbit is set if no characters are extracted or n-1 characters + * are extracted. If end-of-file occurs the eofbit is set. + * + * \return always returns *this. A failure is indicated by the stream state. + */ + istream& getline(char *str, streamsize n, char delim = '\n'); + /** + * Extract characters and discard them. + * + * \param[in] n maximum number of characters to ignore. + * \param[in] delim Delimiter. + * + * Characters are extracted until extraction fails, \a n characters + * are extracted, or the next input character equals \a delim + * (the delimiter is extracted). If end-of-file occurs the eofbit is set. + * + * Failures are indicated by the state of the stream. + * + * \return *this + * + */ + istream& ignore(streamsize n = 1, int delim = -1); + /** + * Return the next available character without consuming it. + * + * \return The character if the stream state is good else -1; + * + */ + int peek(); +// istream& read(char *str, streamsize count); +// streamsize readsome(char *str, streamsize count); + /** + * \return the stream position + */ + pos_type tellg() { + return tellpos(); + } + /** + * Set the stream position + * \param[in] pos The absolute position in which to move the read pointer. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream& seekg(pos_type pos) { + if (!seekpos(pos)) { + setstate(failbit); + } + return *this; + } + /** + * Set the stream position. + * + * \param[in] off An offset to move the read pointer relative to way. + * \a off is a signed 32-bit int so the offset is limited to +- 2GB. + * \param[in] way One of ios::beg, ios::cur, or ios::end. + * \return Is always *this. Failure is indicated by the state of *this. + */ + istream& seekg(off_type off, seekdir way) { + if (!seekoff(off, way)) { + setstate(failbit); + } + return *this; + } + void skipWhite(); + + protected: + /// @cond SHOW_PROTECTED + /** + * Internal - do not use + * \return + */ + virtual int16_t getch() = 0; + /** + * Internal - do not use + * \param[out] pos + * \return + */ + int16_t getch(FatPos_t* pos) { + getpos(pos); + return getch(); + } + /** + * Internal - do not use + * \param[out] pos + */ + virtual void getpos(FatPos_t* pos) = 0; + /** + * Internal - do not use + * \param[in] pos + */ + virtual bool seekoff(off_type off, seekdir way) = 0; + virtual bool seekpos(pos_type pos) = 0; + virtual void setpos(FatPos_t* pos) = 0; + virtual pos_type tellpos() = 0; + + /// @endcond + private: + void getBool(bool *b); + void getChar(char* ch); + bool getDouble(double* value); + template void getNumber(T* value); + bool getNumber(uint32_t posMax, uint32_t negMax, uint32_t* num); + void getStr(char *str); + int16_t readSkip(); + + size_t m_gcount; +}; +//------------------------------------------------------------------------------ +template +void istream::getNumber(T* value) { + uint32_t tmp; + if ((T)-1 < 0) { + // number is signed, max positive value + uint32_t const m = ((uint32_t)-1) >> (33 - sizeof(T) * 8); + // max absolute value of negative number is m + 1. + if (getNumber(m, m + 1, &tmp)) { + *value = (T)tmp; + } + } else { + // max unsigned value for T + uint32_t const m = (T)-1; + if (getNumber(m, m, &tmp)) { + *value = (T)tmp; + } + } +} +#endif // istream_h diff --git a/libraries/SdFat/src/FatLib/ostream.cpp b/libraries/SdFat/src/FatLib/ostream.cpp new file mode 100644 index 0000000..230cda4 --- /dev/null +++ b/libraries/SdFat/src/FatLib/ostream.cpp @@ -0,0 +1,191 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#include +#include "ostream.h" +#ifndef PSTR +#define PSTR(x) x +#endif +//------------------------------------------------------------------------------ +void ostream::do_fill(unsigned len) { + for (; len < width(); len++) { + putch(fill()); + } + width(0); +} +//------------------------------------------------------------------------------ +void ostream::fill_not_left(unsigned len) { + if ((flags() & adjustfield) != left) { + do_fill(len); + } +} +//------------------------------------------------------------------------------ +char* ostream::fmtNum(uint32_t n, char *ptr, uint8_t base) { + char a = flags() & uppercase ? 'A' - 10 : 'a' - 10; + do { + uint32_t m = n; + n /= base; + char c = m - base * n; + *--ptr = c < 10 ? c + '0' : c + a; + } while (n); + return ptr; +} +//------------------------------------------------------------------------------ +void ostream::putBool(bool b) { + if (flags() & boolalpha) { + if (b) { + putPgm(PSTR("true")); + } else { + putPgm(PSTR("false")); + } + } else { + putChar(b ? '1' : '0'); + } +} +//------------------------------------------------------------------------------ +void ostream::putChar(char c) { + fill_not_left(1); + putch(c); + do_fill(1); +} +//------------------------------------------------------------------------------ +void ostream::putDouble(double n) { + uint8_t nd = precision(); + double round = 0.5; + char sign; + char buf[13]; // room for sign, 10 digits, '.', and zero byte + char *end = buf + sizeof(buf) - 1; + char *str = end; + // terminate string + *end = '\0'; + + // get sign and make nonnegative + if (n < 0.0) { + sign = '-'; + n = -n; + } else { + sign = flags() & showpos ? '+' : '\0'; + } + // check for larger than uint32_t + if (n > 4.0E9) { + putPgm(PSTR("BIG FLT")); + return; + } + // round up and separate int and fraction parts + for (uint8_t i = 0; i < nd; ++i) { + round *= 0.1; + } + n += round; + uint32_t intPart = n; + double fractionPart = n - intPart; + + // format intPart and decimal point + if (nd || (flags() & showpoint)) { + *--str = '.'; + } + str = fmtNum(intPart, str, 10); + + // calculate length for fill + uint8_t len = sign ? 1 : 0; + len += nd + end - str; + + // extract adjust field + fmtflags adj = flags() & adjustfield; + if (adj == internal) { + if (sign) { + putch(sign); + } + do_fill(len); + } else { + // do fill for internal or right + fill_not_left(len); + if (sign) { + *--str = sign; + } + } + putstr(str); + // output fraction + while (nd-- > 0) { + fractionPart *= 10.0; + int digit = static_cast(fractionPart); + putch(digit + '0'); + fractionPart -= digit; + } + // do fill if not done above + do_fill(len); +} +//------------------------------------------------------------------------------ +void ostream::putNum(int32_t n) { + bool neg = n < 0 && flagsToBase() == 10; + if (neg) { + n = -n; + } + putNum(n, neg); +} +//------------------------------------------------------------------------------ +void ostream::putNum(uint32_t n, bool neg) { + char buf[13]; + char* end = buf + sizeof(buf) - 1; + char* num; + char* str; + uint8_t base = flagsToBase(); + *end = '\0'; + str = num = fmtNum(n, end, base); + if (base == 10) { + if (neg) { + *--str = '-'; + } else if (flags() & showpos) { + *--str = '+'; + } + } else if (flags() & showbase) { + if (flags() & hex) { + *--str = flags() & uppercase ? 'X' : 'x'; + } + *--str = '0'; + } + uint8_t len = end - str; + fmtflags adj = flags() & adjustfield; + if (adj == internal) { + while (str < num) { + putch(*str++); + } + } + if (adj != left) { + do_fill(len); + } + putstr(str); + do_fill(len); +} +//------------------------------------------------------------------------------ +void ostream::putPgm(const char* str) { + int n; + for (n = 0; pgm_read_byte(&str[n]); n++) {} + fill_not_left(n); + for (uint8_t c; (c = pgm_read_byte(str)); str++) { + putch(c); + } + do_fill(n); +} +//------------------------------------------------------------------------------ +void ostream::putStr(const char *str) { + unsigned n = strlen(str); + fill_not_left(n); + putstr(str); + do_fill(n); +} diff --git a/libraries/SdFat/src/FatLib/ostream.h b/libraries/SdFat/src/FatLib/ostream.h new file mode 100644 index 0000000..e7c9163 --- /dev/null +++ b/libraries/SdFat/src/FatLib/ostream.h @@ -0,0 +1,271 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef ostream_h +#define ostream_h +/** + * \file + * \brief \ref ostream class + */ +#include "ios.h" +//============================================================================== +/** + * \class ostream + * \brief Output Stream + */ +class ostream : public virtual ios { + public: + ostream() {} + + /** call manipulator + * \param[in] pf function to call + * \return the stream + */ + ostream& operator<< (ostream& (*pf)(ostream& str)) { + return pf(*this); + } + /** call manipulator + * \param[in] pf function to call + * \return the stream + */ + ostream& operator<< (ios_base& (*pf)(ios_base& str)) { + pf(*this); + return *this; + } + /** Output bool + * \param[in] arg value to output + * \return the stream + */ + ostream &operator<< (bool arg) { + putBool(arg); + return *this; + } + /** Output string + * \param[in] arg string to output + * \return the stream + */ + ostream &operator<< (const char *arg) { + putStr(arg); + return *this; + } + /** Output string + * \param[in] arg string to output + * \return the stream + */ + ostream &operator<< (const signed char *arg) { + putStr((const char*)arg); + return *this; + } + /** Output string + * \param[in] arg string to output + * \return the stream + */ + ostream &operator<< (const unsigned char *arg) { + putStr((const char*)arg); + return *this; + } + /** Output character + * \param[in] arg character to output + * \return the stream + */ + ostream &operator<< (char arg) { + putChar(arg); + return *this; + } + /** Output character + * \param[in] arg character to output + * \return the stream + */ + ostream &operator<< (signed char arg) { + putChar(static_cast(arg)); + return *this; + } + /** Output character + * \param[in] arg character to output + * \return the stream + */ + ostream &operator<< (unsigned char arg) { + putChar(static_cast(arg)); + return *this; + } + /** Output double + * \param[in] arg value to output + * \return the stream + */ + ostream &operator<< (double arg) { + putDouble(arg); + return *this; + } + /** Output float + * \param[in] arg value to output + * \return the stream + */ + ostream &operator<< (float arg) { + putDouble(arg); + return *this; + } + /** Output signed short + * \param[in] arg value to output + * \return the stream + */ + ostream &operator<< (short arg) { // NOLINT + putNum((int32_t)arg); + return *this; + } + /** Output unsigned short + * \param[in] arg value to output + * \return the stream + */ + ostream &operator<< (unsigned short arg) { // NOLINT + putNum((uint32_t)arg); + return *this; + } + /** Output signed int + * \param[in] arg value to output + * \return the stream + */ + ostream &operator<< (int arg) { + putNum((int32_t)arg); + return *this; + } + /** Output unsigned int + * \param[in] arg value to output + * \return the stream + */ + ostream &operator<< (unsigned int arg) { + putNum((uint32_t)arg); + return *this; + } + /** Output signed long + * \param[in] arg value to output + * \return the stream + */ + ostream &operator<< (long arg) { // NOLINT + putNum((int32_t)arg); + return *this; + } + /** Output unsigned long + * \param[in] arg value to output + * \return the stream + */ + ostream &operator<< (unsigned long arg) { // NOLINT + putNum((uint32_t)arg); + return *this; + } + /** Output pointer + * \param[in] arg value to output + * \return the stream + */ + ostream& operator<< (const void* arg) { + putNum(reinterpret_cast(arg)); + return *this; + } +#if (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) + /** Output a string from flash using the Arduino F() macro. + * \param[in] arg pointing to flash string + * \return the stream + */ + ostream &operator<< (const __FlashStringHelper *arg) { + putPgm(reinterpret_cast(arg)); + return *this; + } +#endif // (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) + /** + * Puts a character in a stream. + * + * The unformatted output function inserts the element \a ch. + * It returns *this. + * + * \param[in] ch The character + * \return A reference to the ostream object. + */ + ostream& put(char ch) { + putch(ch); + return *this; + } +// ostream& write(char *str, streamsize count); + /** + * Flushes the buffer associated with this stream. The flush function + * calls the sync function of the associated file. + * \return A reference to the ostream object. + */ + ostream& flush() { + if (!sync()) { + setstate(badbit); + } + return *this; + } + /** + * \return the stream position + */ + pos_type tellp() { + return tellpos(); + } + /** + * Set the stream position + * \param[in] pos The absolute position in which to move the write pointer. + * \return Is always *this. Failure is indicated by the state of *this. + */ + ostream& seekp(pos_type pos) { + if (!seekpos(pos)) { + setstate(failbit); + } + return *this; + } + /** + * Set the stream position. + * + * \param[in] off An offset to move the write pointer relative to way. + * \a off is a signed 32-bit int so the offset is limited to +- 2GB. + * \param[in] way One of ios::beg, ios::cur, or ios::end. + * \return Is always *this. Failure is indicated by the state of *this. + */ + ostream& seekp(off_type off, seekdir way) { + if (!seekoff(off, way)) { + setstate(failbit); + } + return *this; + } + + protected: + /// @cond SHOW_PROTECTED + /** Put character with binary/text conversion + * \param[in] ch character to write + */ + virtual void putch(char ch) = 0; + virtual void putstr(const char *str) = 0; + virtual bool seekoff(off_type pos, seekdir way) = 0; + virtual bool seekpos(pos_type pos) = 0; + virtual bool sync() = 0; + + virtual pos_type tellpos() = 0; + /// @endcond + private: + void do_fill(unsigned len); + void fill_not_left(unsigned len); + char* fmtNum(uint32_t n, char *ptr, uint8_t base); + void putBool(bool b); + void putChar(char c); + void putDouble(double n); + void putNum(uint32_t n, bool neg = false); + void putNum(int32_t n); + void putPgm(const char* str); + void putStr(const char* str); +}; +#endif // ostream_h diff --git a/libraries/SdFat/src/FreeStack.h b/libraries/SdFat/src/FreeStack.h new file mode 100644 index 0000000..9a61bc8 --- /dev/null +++ b/libraries/SdFat/src/FreeStack.h @@ -0,0 +1,56 @@ +/* Arduino SdFat Library + * Copyright (C) 2015 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 FreeStack_h +#define FreeStack_h +/** + * \file + * \brief FreeStack() function. + */ +#if defined(__AVR__) || defined(DOXYGEN) +/** boundary between stack and heap. */ +extern char *__brkval; +/** End of bss section.*/ +extern char __bss_end; +/** Amount of free stack space. + * \return The number of free bytes. + */ +static int FreeStack() { + char* sp = reinterpret_cast(SP); + return __brkval ? sp - __brkval : sp - &__bss_end; +// char top; +// return __brkval ? &top - __brkval : &top - &__bss_end; +} +#elif defined(PLATFORM_ID) // Particle board +static int FreeStack() { + return System.freeMemory(); +} +#elif defined(__arm__) +extern "C" char* sbrk(int incr); +static int FreeStack() { + char top = 't'; + return &top - reinterpret_cast(sbrk(0)); +} +#else +#warning FreeStack is not defined for this system. +static int FreeStack() { + return 0; +} +#endif +#endif // FreeStack_h diff --git a/libraries/SdFat/src/MinimumSerial.cpp b/libraries/SdFat/src/MinimumSerial.cpp new file mode 100644 index 0000000..12f5137 --- /dev/null +++ b/libraries/SdFat/src/MinimumSerial.cpp @@ -0,0 +1,66 @@ +/* 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 + * . + */ +#include "SysCall.h" +#if defined(UDR0) || defined(DOXYGEN) +#include "MinimumSerial.h" +const uint16_t MIN_2X_BAUD = F_CPU/(4*(2*0XFFF + 1)) + 1; +//------------------------------------------------------------------------------ +int MinimumSerial::available() { + return UCSR0A & (1 << RXC0) ? 1 : 0; +} +//------------------------------------------------------------------------------ +void MinimumSerial::begin(uint32_t baud) { + uint16_t baud_setting; + // don't worry, the compiler will squeeze out F_CPU != 16000000UL + if ((F_CPU != 16000000UL || baud != 57600) && baud > MIN_2X_BAUD) { + // Double the USART Transmission Speed + UCSR0A = 1 << U2X0; + baud_setting = (F_CPU / 4 / baud - 1) / 2; + } else { + // hardcoded exception for compatibility with the bootloader shipped + // with the Duemilanove and previous boards and the firmware on the 8U2 + // on the Uno and Mega 2560. + UCSR0A = 0; + baud_setting = (F_CPU / 8 / baud - 1) / 2; + } + // assign the baud_setting + UBRR0H = baud_setting >> 8; + UBRR0L = baud_setting; + // enable transmit and receive + UCSR0B |= (1 << TXEN0) | (1 << RXEN0); +} +//------------------------------------------------------------------------------ +void MinimumSerial::flush() { + while (((1 << UDRIE0) & UCSR0B) || !(UCSR0A & (1 << UDRE0))) {} +} +//------------------------------------------------------------------------------ +int MinimumSerial::read() { + if (UCSR0A & (1 << RXC0)) { + return UDR0; + } + return -1; +} +//------------------------------------------------------------------------------ +size_t MinimumSerial::write(uint8_t b) { + while (((1 << UDRIE0) & UCSR0B) || !(UCSR0A & (1 << UDRE0))) {} + UDR0 = b; + return 1; +} +#endif // defined(UDR0) || defined(DOXYGEN) diff --git a/libraries/SdFat/src/MinimumSerial.h b/libraries/SdFat/src/MinimumSerial.h new file mode 100644 index 0000000..61b2f04 --- /dev/null +++ b/libraries/SdFat/src/MinimumSerial.h @@ -0,0 +1,62 @@ +/* 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 + * . + */ + /** + * \file + * \brief Minimal AVR Serial driver. + */ +#ifndef MinimumSerial_h +#define MinimumSerial_h +#include "SysCall.h" +//============================================================================== +/** + * \class MinimumSerial + * \brief mini serial class for the %SdFat library. + */ +class MinimumSerial : public Print { + public: + /** \return true for hardware serial */ + operator bool() { return true; } + /** + * \return one if data is available. + */ + int available(); + /** + * Set baud rate for serial port zero and enable in non interrupt mode. + * Do not call this function if you use another serial library. + * \param[in] baud rate + */ + void begin(uint32_t baud); + /** Wait for write done. */ + void flush(); + /** + * Unbuffered read + * \return -1 if no character is available or an available character. + */ + int read(); + /** + * Unbuffered write + * + * \param[in] b byte to write. + * \return 1 + */ + size_t write(uint8_t b); + using Print::write; +}; +#endif // MinimumSerial_h diff --git a/libraries/SdFat/src/SdCard/SdInfo.h b/libraries/SdFat/src/SdCard/SdInfo.h new file mode 100644 index 0000000..5bc6895 --- /dev/null +++ b/libraries/SdFat/src/SdCard/SdInfo.h @@ -0,0 +1,475 @@ +/* Arduino SdCard Library + * Copyright (C) 2016 by William Greiman + * + * This file is part of the Arduino SdSpiCard 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 SdSpiCard Library. If not, see + * . + */ +#ifndef SdInfo_h +#define SdInfo_h +#include +// Based on the document: +// +// SD Specifications +// Part 1 +// Physical Layer +// Simplified Specification +// Version 5.00 +// Aug 10, 2016 +// +// https://www.sdcard.org/downloads/pls/ +//------------------------------------------------------------------------------ +// SD card errors +// See the SD Specification for command info. +typedef enum { + SD_CARD_ERROR_NONE = 0, + + // Basic commands and switch command. + SD_CARD_ERROR_CMD0 = 0X20, + SD_CARD_ERROR_CMD2, + SD_CARD_ERROR_CMD3, + SD_CARD_ERROR_CMD6, + SD_CARD_ERROR_CMD7, + SD_CARD_ERROR_CMD8, + SD_CARD_ERROR_CMD9, + SD_CARD_ERROR_CMD10, + SD_CARD_ERROR_CMD12, + SD_CARD_ERROR_CMD13, + + // Read, write, erase, and extension commands. + SD_CARD_ERROR_CMD17 = 0X30, + SD_CARD_ERROR_CMD18, + SD_CARD_ERROR_CMD24, + SD_CARD_ERROR_CMD25, + SD_CARD_ERROR_CMD32, + SD_CARD_ERROR_CMD33, + SD_CARD_ERROR_CMD38, + SD_CARD_ERROR_CMD58, + SD_CARD_ERROR_CMD59, + + // Application specific commands. + SD_CARD_ERROR_ACMD6 = 0X40, + SD_CARD_ERROR_ACMD13, + SD_CARD_ERROR_ACMD23, + SD_CARD_ERROR_ACMD41, + + // Read/write errors + SD_CARD_ERROR_READ = 0X50, + SD_CARD_ERROR_READ_CRC, + SD_CARD_ERROR_READ_FIFO, + SD_CARD_ERROR_READ_REG, + SD_CARD_ERROR_READ_START, + SD_CARD_ERROR_READ_TIMEOUT, + SD_CARD_ERROR_STOP_TRAN, + SD_CARD_ERROR_WRITE, + SD_CARD_ERROR_WRITE_FIFO, + SD_CARD_ERROR_WRITE_START, + SD_CARD_ERROR_WRITE_TIMEOUT, + + // Misc errors. + SD_CARD_ERROR_DMA = 0X60, + SD_CARD_ERROR_ERASE, + SD_CARD_ERROR_ERASE_SINGLE_BLOCK, + SD_CARD_ERROR_ERASE_TIMEOUT, + SD_CARD_ERROR_INIT_NOT_CALLED, + SD_CARD_ERROR_FUNCTION_NOT_SUPPORTED +} sd_error_code_t; +//------------------------------------------------------------------------------ +// card types +/** Standard capacity V1 SD card */ +const uint8_t SD_CARD_TYPE_SD1 = 1; +/** Standard capacity V2 SD card */ +const uint8_t SD_CARD_TYPE_SD2 = 2; +/** High Capacity SD card */ +const uint8_t SD_CARD_TYPE_SDHC = 3; +//------------------------------------------------------------------------------ +#define SD_SCK_HZ(maxSpeed) SPISettings(maxSpeed, MSBFIRST, SPI_MODE0) +#define SD_SCK_MHZ(maxMhz) SPISettings(1000000UL*maxMhz, MSBFIRST, SPI_MODE0) +// SPI divisor constants +/** Set SCK to max rate of F_CPU/2. */ +#define SPI_FULL_SPEED SD_SCK_MHZ(50) +/** Set SCK rate to F_CPU/3 for Due */ +#define SPI_DIV3_SPEED SD_SCK_HZ(F_CPU/3) +/** Set SCK rate to F_CPU/4. */ +#define SPI_HALF_SPEED SD_SCK_HZ(F_CPU/4) +/** Set SCK rate to F_CPU/6 for Due */ +#define SPI_DIV6_SPEED SD_SCK_HZ(F_CPU/6) +/** Set SCK rate to F_CPU/8. */ +#define SPI_QUARTER_SPEED SD_SCK_HZ(F_CPU/8) +/** Set SCK rate to F_CPU/16. */ +#define SPI_EIGHTH_SPEED SD_SCK_HZ(F_CPU/16) +/** Set SCK rate to F_CPU/32. */ +#define SPI_SIXTEENTH_SPEED SD_SCK_HZ(F_CPU/32) +//------------------------------------------------------------------------------ +// SD operation timeouts +/** init timeout ms */ +const uint16_t SD_INIT_TIMEOUT = 2000; +/** erase timeout ms */ +const uint16_t SD_ERASE_TIMEOUT = 10000; +/** read timeout ms */ +const uint16_t SD_READ_TIMEOUT = 300; +/** write time out ms */ +const uint16_t SD_WRITE_TIMEOUT = 600; +//------------------------------------------------------------------------------ +// SD card commands +/** GO_IDLE_STATE - init card in spi mode if CS low */ +const uint8_t CMD0 = 0X00; +/** ALL_SEND_CID - Asks any card to send the CID. */ +const uint8_t CMD2 = 0X02; +/** SEND_RELATIVE_ADDR - Ask the card to publish a new RCA. */ +const uint8_t CMD3 = 0X03; +/** SWITCH_FUNC - Switch Function Command */ +const uint8_t CMD6 = 0X06; +/** SELECT/DESELECT_CARD - toggles between the stand-by and transfer states. */ +const uint8_t CMD7 = 0X07; +/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ +const uint8_t CMD8 = 0X08; +/** SEND_CSD - read the Card Specific Data (CSD register) */ +const uint8_t CMD9 = 0X09; +/** SEND_CID - read the card identification information (CID register) */ +const uint8_t CMD10 = 0X0A; +/** STOP_TRANSMISSION - end multiple block read sequence */ +const uint8_t CMD12 = 0X0C; +/** SEND_STATUS - read the card status register */ +const uint8_t CMD13 = 0X0D; +/** READ_SINGLE_BLOCK - read a single data block from the card */ +const uint8_t CMD17 = 0X11; +/** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card */ +const uint8_t CMD18 = 0X12; +/** WRITE_BLOCK - write a single data block to the card */ +const uint8_t CMD24 = 0X18; +/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ +const uint8_t CMD25 = 0X19; +/** ERASE_WR_BLK_START - sets the address of the first block to be erased */ +const uint8_t CMD32 = 0X20; +/** ERASE_WR_BLK_END - sets the address of the last block of the continuous + range to be erased*/ +const uint8_t CMD33 = 0X21; +/** ERASE - erase all previously selected blocks */ +const uint8_t CMD38 = 0X26; +/** APP_CMD - escape for application specific command */ +const uint8_t CMD55 = 0X37; +/** READ_OCR - read the OCR register of a card */ +const uint8_t CMD58 = 0X3A; +/** CRC_ON_OFF - enable or disable CRC checking */ +const uint8_t CMD59 = 0X3B; +/** SET_BUS_WIDTH - Defines the data bus width for data transfer. */ +const uint8_t ACMD6 = 0X06; +/** SD_STATUS - Send the SD Status. */ +const uint8_t ACMD13 = 0X0D; +/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be + pre-erased before writing */ +const uint8_t ACMD23 = 0X17; +/** SD_SEND_OP_COMD - Sends host capacity support information and + activates the card's initialization process */ +const uint8_t ACMD41 = 0X29; +//============================================================================== +// CARD_STATUS +/** The command's argument was out of the allowed range for this card. */ +const uint32_t CARD_STATUS_OUT_OF_RANGE = 1UL << 31; +/** A misaligned address which did not match the block length. */ +const uint32_t CARD_STATUS_ADDRESS_ERROR = 1UL << 30; +/** The transferred block length is not allowed for this card. */ +const uint32_t CARD_STATUS_BLOCK_LEN_ERROR = 1UL << 29; +/** An error in the sequence of erase commands occurred. */ +const uint32_t CARD_STATUS_ERASE_SEQ_ERROR = 1UL <<28; +/** An invalid selection of write-blocks for erase occurred. */ +const uint32_t CARD_STATUS_ERASE_PARAM = 1UL << 27; +/** Set when the host attempts to write to a protected block. */ +const uint32_t CARD_STATUS_WP_VIOLATION = 1UL << 26; +/** When set, signals that the card is locked by the host. */ +const uint32_t CARD_STATUS_CARD_IS_LOCKED = 1UL << 25; +/** Set when a sequence or password error has been detected. */ +const uint32_t CARD_STATUS_LOCK_UNLOCK_FAILED = 1UL << 24; +/** The CRC check of the previous command failed. */ +const uint32_t CARD_STATUS_COM_CRC_ERROR = 1UL << 23; +/** Command not legal for the card state. */ +const uint32_t CARD_STATUS_ILLEGAL_COMMAND = 1UL << 22; +/** Card internal ECC was applied but failed to correct the data. */ +const uint32_t CARD_STATUS_CARD_ECC_FAILED = 1UL << 21; +/** Internal card controller error */ +const uint32_t CARD_STATUS_CC_ERROR = 1UL << 20; +/** A general or an unknown error occurred during the operation. */ +const uint32_t CARD_STATUS_ERROR = 1UL << 19; +// bits 19, 18, and 17 reserved. +/** Permanent WP set or attempt to change read only values of CSD. */ +const uint32_t CARD_STATUS_CSD_OVERWRITE = 1UL <<16; +/** partial address space was erased due to write protect. */ +const uint32_t CARD_STATUS_WP_ERASE_SKIP = 1UL << 15; +/** The command has been executed without using the internal ECC. */ +const uint32_t CARD_STATUS_CARD_ECC_DISABLED = 1UL << 14; +/** out of erase sequence command was received. */ +const uint32_t CARD_STATUS_ERASE_RESET = 1UL << 13; +/** The state of the card when receiving the command. + * 0 = idle + * 1 = ready + * 2 = ident + * 3 = stby + * 4 = tran + * 5 = data + * 6 = rcv + * 7 = prg + * 8 = dis + * 9-14 = reserved + * 15 = reserved for I/O mode + */ +const uint32_t CARD_STATUS_CURRENT_STATE = 0XF << 9; +/** Shift for current state. */ +const uint32_t CARD_STATUS_CURRENT_STATE_SHIFT = 9; +/** Corresponds to buffer empty signaling on the bus. */ +const uint32_t CARD_STATUS_READY_FOR_DATA = 1UL << 8; +// bit 7 reserved. +/** Extension Functions may set this bit to get host to deal with events. */ +const uint32_t CARD_STATUS_FX_EVENT = 1UL << 6; +/** The card will expect ACMD, or the command has been interpreted as ACMD */ +const uint32_t CARD_STATUS_APP_CMD = 1UL << 5; +// bit 4 reserved. +/** Error in the sequence of the authentication process. */ +const uint32_t CARD_STATUS_AKE_SEQ_ERROR = 1UL << 3; +// bits 2,1, and 0 reserved for manufacturer test mode. +//============================================================================== +/** status for card in the ready state */ +const uint8_t R1_READY_STATE = 0X00; +/** status for card in the idle state */ +const uint8_t R1_IDLE_STATE = 0X01; +/** status bit for illegal command */ +const uint8_t R1_ILLEGAL_COMMAND = 0X04; +/** start data token for read or write single block*/ +const uint8_t DATA_START_BLOCK = 0XFE; +/** stop token for write multiple blocks*/ +const uint8_t STOP_TRAN_TOKEN = 0XFD; +/** start data token for write multiple blocks*/ +const uint8_t WRITE_MULTIPLE_TOKEN = 0XFC; +/** mask for data response tokens after a write block operation */ +const uint8_t DATA_RES_MASK = 0X1F; +/** write data accepted token */ +const uint8_t DATA_RES_ACCEPTED = 0X05; +//============================================================================== +/** + * \class CID + * \brief Card IDentification (CID) register. + */ +typedef struct CID { + // byte 0 + /** Manufacturer ID */ + unsigned char mid; + // byte 1-2 + /** OEM/Application ID */ + char oid[2]; + // byte 3-7 + /** Product name */ + char pnm[5]; + // byte 8 + /** Product revision least significant digit */ + unsigned char prv_m : 4; + /** Product revision most significant digit */ + unsigned char prv_n : 4; + // byte 9-12 + /** Product serial number */ + uint32_t psn; + // byte 13 + /** Manufacturing date year low digit */ + unsigned char mdt_year_high : 4; + /** not used */ + unsigned char reserved : 4; + // byte 14 + /** Manufacturing date month */ + unsigned char mdt_month : 4; + /** Manufacturing date year low digit */ + unsigned char mdt_year_low : 4; + // byte 15 + /** not used always 1 */ + unsigned char always1 : 1; + /** CRC7 checksum */ + unsigned char crc : 7; +} __attribute__((packed)) cid_t; + +//============================================================================== +/** + * \class CSDV1 + * \brief CSD register for version 1.00 cards . + */ +typedef struct CSDV1 { + // byte 0 + unsigned char reserved1 : 6; + unsigned char csd_ver : 2; + // byte 1 + unsigned char taac; + // byte 2 + unsigned char nsac; + // byte 3 + unsigned char tran_speed; + // byte 4 + unsigned char ccc_high; + // byte 5 + unsigned char read_bl_len : 4; + unsigned char ccc_low : 4; + // byte 6 + unsigned char c_size_high : 2; + unsigned char reserved2 : 2; + unsigned char dsr_imp : 1; + unsigned char read_blk_misalign : 1; + unsigned char write_blk_misalign : 1; + unsigned char read_bl_partial : 1; + // byte 7 + unsigned char c_size_mid; + // byte 8 + unsigned char vdd_r_curr_max : 3; + unsigned char vdd_r_curr_min : 3; + unsigned char c_size_low : 2; + // byte 9 + unsigned char c_size_mult_high : 2; + unsigned char vdd_w_cur_max : 3; + unsigned char vdd_w_curr_min : 3; + // byte 10 + unsigned char sector_size_high : 6; + unsigned char erase_blk_en : 1; + unsigned char c_size_mult_low : 1; + // byte 11 + unsigned char wp_grp_size : 7; + unsigned char sector_size_low : 1; + // byte 12 + unsigned char write_bl_len_high : 2; + unsigned char r2w_factor : 3; + unsigned char reserved3 : 2; + unsigned char wp_grp_enable : 1; + // byte 13 + unsigned char reserved4 : 5; + unsigned char write_partial : 1; + unsigned char write_bl_len_low : 2; + // byte 14 + unsigned char reserved5: 2; + unsigned char file_format : 2; + unsigned char tmp_write_protect : 1; + unsigned char perm_write_protect : 1; + unsigned char copy : 1; + /** Indicates the file format on the card */ + unsigned char file_format_grp : 1; + // byte 15 + unsigned char always1 : 1; + unsigned char crc : 7; +} __attribute__((packed)) csd1_t; +//============================================================================== +/** + * \class CSDV2 + * \brief CSD register for version 2.00 cards. + */ +typedef struct CSDV2 { + // byte 0 + unsigned char reserved1 : 6; + unsigned char csd_ver : 2; + // byte 1 + /** fixed to 0X0E */ + unsigned char taac; + // byte 2 + /** fixed to 0 */ + unsigned char nsac; + // byte 3 + unsigned char tran_speed; + // byte 4 + unsigned char ccc_high; + // byte 5 + /** This field is fixed to 9h, which indicates READ_BL_LEN=512 Byte */ + unsigned char read_bl_len : 4; + unsigned char ccc_low : 4; + // byte 6 + /** not used */ + unsigned char reserved2 : 4; + unsigned char dsr_imp : 1; + /** fixed to 0 */ + unsigned char read_blk_misalign : 1; + /** fixed to 0 */ + unsigned char write_blk_misalign : 1; + /** fixed to 0 - no partial read */ + unsigned char read_bl_partial : 1; + // byte 7 + /** high part of card size */ + unsigned char c_size_high : 6; + /** not used */ + unsigned char reserved3 : 2; + // byte 8 + /** middle part of card size */ + unsigned char c_size_mid; + // byte 9 + /** low part of card size */ + unsigned char c_size_low; + // byte 10 + /** sector size is fixed at 64 KB */ + unsigned char sector_size_high : 6; + /** fixed to 1 - erase single is supported */ + unsigned char erase_blk_en : 1; + /** not used */ + unsigned char reserved4 : 1; + // byte 11 + unsigned char wp_grp_size : 7; + /** sector size is fixed at 64 KB */ + unsigned char sector_size_low : 1; + // byte 12 + /** write_bl_len fixed for 512 byte blocks */ + unsigned char write_bl_len_high : 2; + /** fixed value of 2 */ + unsigned char r2w_factor : 3; + /** not used */ + unsigned char reserved5 : 2; + /** fixed value of 0 - no write protect groups */ + unsigned char wp_grp_enable : 1; + // byte 13 + unsigned char reserved6 : 5; + /** always zero - no partial block read*/ + unsigned char write_partial : 1; + /** write_bl_len fixed for 512 byte blocks */ + unsigned char write_bl_len_low : 2; + // byte 14 + unsigned char reserved7: 2; + /** Do not use always 0 */ + unsigned char file_format : 2; + unsigned char tmp_write_protect : 1; + unsigned char perm_write_protect : 1; + unsigned char copy : 1; + /** Do not use always 0 */ + unsigned char file_format_grp : 1; + // byte 15 + /** not used always 1 */ + unsigned char always1 : 1; + /** checksum */ + unsigned char crc : 7; +} __attribute__((packed)) csd2_t; +//============================================================================== +/** + * \class csd_t + * \brief Union of old and new style CSD register. + */ +union csd_t { + csd1_t v1; + csd2_t v2; +}; +//----------------------------------------------------------------------------- +inline uint32_t sdCardCapacity(csd_t* csd) { + if (csd->v1.csd_ver == 0) { + uint8_t read_bl_len = csd->v1.read_bl_len; + uint16_t c_size = (csd->v1.c_size_high << 10) + | (csd->v1.c_size_mid << 2) | csd->v1.c_size_low; + uint8_t c_size_mult = (csd->v1.c_size_mult_high << 1) + | csd->v1.c_size_mult_low; + return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7); + } else if (csd->v2.csd_ver == 1) { + uint32_t c_size = 0X10000L * csd->v2.c_size_high + 0X100L + * (uint32_t)csd->v2.c_size_mid + csd->v2.c_size_low; + return (c_size + 1) << 10; + } else { + return 0; + } +} +#endif // SdInfo_h diff --git a/libraries/SdFat/src/SdCard/SdSpiCard.cpp b/libraries/SdFat/src/SdCard/SdSpiCard.cpp new file mode 100644 index 0000000..7fce040 --- /dev/null +++ b/libraries/SdFat/src/SdCard/SdSpiCard.cpp @@ -0,0 +1,665 @@ +/* Arduino SdCard Library + * Copyright (C) 2016 by William Greiman + * + * This file is part of the Arduino SdSpiCard 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 SdSpiCard Library. If not, see + * . + */ +#include "SdSpiCard.h" +// debug trace macro +#define SD_TRACE(m, b) +// #define SD_TRACE(m, b) Serial.print(m);Serial.println(b); +#define SD_CS_DBG(m) +// #define SD_CS_DBG(m) Serial.println(F(m)); +//============================================================================== +#if USE_SD_CRC +// CRC functions +//------------------------------------------------------------------------------ +static uint8_t CRC7(const uint8_t* data, uint8_t n) { + uint8_t crc = 0; + for (uint8_t i = 0; i < n; i++) { + uint8_t d = data[i]; + for (uint8_t j = 0; j < 8; j++) { + crc <<= 1; + if ((d & 0x80) ^ (crc & 0x80)) { + crc ^= 0x09; + } + d <<= 1; + } + } + return (crc << 1) | 1; +} +//------------------------------------------------------------------------------ +#if USE_SD_CRC == 1 +// Shift based CRC-CCITT +// uses the x^16,x^12,x^5,x^1 polynomial. +static uint16_t CRC_CCITT(const uint8_t *data, size_t n) { + uint16_t crc = 0; + for (size_t i = 0; i < n; i++) { + crc = (uint8_t)(crc >> 8) | (crc << 8); + crc ^= data[i]; + crc ^= (uint8_t)(crc & 0xff) >> 4; + crc ^= crc << 12; + crc ^= (crc & 0xff) << 5; + } + return crc; +} +#elif USE_SD_CRC > 1 // CRC_CCITT +//------------------------------------------------------------------------------ +// Table based CRC-CCITT +// uses the x^16,x^12,x^5,x^1 polynomial. +#ifdef __AVR__ +static const uint16_t crctab[] PROGMEM = { +#else // __AVR__ +static const uint16_t crctab[] = { +#endif // __AVR__ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; +static uint16_t CRC_CCITT(const uint8_t* data, size_t n) { + uint16_t crc = 0; + for (size_t i = 0; i < n; i++) { +#ifdef __AVR__ + crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0XFF]) ^ (crc << 8); +#else // __AVR__ + crc = crctab[(crc >> 8 ^ data[i]) & 0XFF] ^ (crc << 8); +#endif // __AVR__ + } + return crc; +} +#endif // CRC_CCITT +#endif // USE_SD_CRC +//============================================================================== +// SdSpiCard member functions +//------------------------------------------------------------------------------ +bool SdSpiCard::begin(SdSpiDriver* spi, uint8_t csPin, SPISettings settings) { + m_spiActive = false; + m_errorCode = SD_CARD_ERROR_NONE; + m_type = 0; + m_spiDriver = spi; + uint16_t t0 = curTimeMS(); + uint32_t arg; + + m_spiDriver->begin(csPin); + m_spiDriver->setSpiSettings(SD_SCK_HZ(250000)); + spiStart(); + + // must supply min of 74 clock cycles with CS high. + spiUnselect(); + for (uint8_t i = 0; i < 10; i++) { + spiSend(0XFF); + } + spiSelect(); + // command to go idle in SPI mode + while (cardCommand(CMD0, 0) != R1_IDLE_STATE) { + if (isTimedOut(t0, SD_INIT_TIMEOUT)) { + error(SD_CARD_ERROR_CMD0); + goto fail; + } + } +#if USE_SD_CRC + if (cardCommand(CMD59, 1) != R1_IDLE_STATE) { + error(SD_CARD_ERROR_CMD59); + goto fail; + } +#endif // USE_SD_CRC + // check SD version + while (1) { + if (cardCommand(CMD8, 0x1AA) == (R1_ILLEGAL_COMMAND | R1_IDLE_STATE)) { + type(SD_CARD_TYPE_SD1); + break; + } + for (uint8_t i = 0; i < 4; i++) { + m_status = spiReceive(); + } + if (m_status == 0XAA) { + type(SD_CARD_TYPE_SD2); + break; + } + if (isTimedOut(t0, SD_INIT_TIMEOUT)) { + error(SD_CARD_ERROR_CMD8); + goto fail; + } + } + // initialize card and send host supports SDHC if SD2 + arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0; + + while (cardAcmd(ACMD41, arg) != R1_READY_STATE) { + // check for timeout + if (isTimedOut(t0, SD_INIT_TIMEOUT)) { + error(SD_CARD_ERROR_ACMD41); + goto fail; + } + } + // if SD2 read OCR register to check for SDHC card + if (type() == SD_CARD_TYPE_SD2) { + if (cardCommand(CMD58, 0)) { + error(SD_CARD_ERROR_CMD58); + goto fail; + } + if ((spiReceive() & 0XC0) == 0XC0) { + type(SD_CARD_TYPE_SDHC); + } + // Discard rest of ocr - contains allowed voltage range. + for (uint8_t i = 0; i < 3; i++) { + spiReceive(); + } + } + spiStop(); + m_spiDriver->setSpiSettings(settings); + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +// send command and return error code. Return zero for OK +uint8_t SdSpiCard::cardCommand(uint8_t cmd, uint32_t arg) { + // select card + if (!m_spiActive) { + spiStart(); + } + // wait if busy + waitNotBusy(SD_WRITE_TIMEOUT); + +#if USE_SD_CRC + // form message + uint8_t buf[6]; + buf[0] = (uint8_t)0x40U | cmd; + buf[1] = (uint8_t)(arg >> 24U); + buf[2] = (uint8_t)(arg >> 16U); + buf[3] = (uint8_t)(arg >> 8U); + buf[4] = (uint8_t)arg; + + // add CRC + buf[5] = CRC7(buf, 5); + + // send message + spiSend(buf, 6); +#else // USE_SD_CRC + // send command + spiSend(cmd | 0x40); + + // send argument + uint8_t *pa = reinterpret_cast(&arg); + for (int8_t i = 3; i >= 0; i--) { + spiSend(pa[i]); + } + + // send CRC - correct for CMD0 with arg zero or CMD8 with arg 0X1AA + spiSend(cmd == CMD0 ? 0X95 : 0X87); +#endif // USE_SD_CRC + + // skip stuff byte for stop read + if (cmd == CMD12) { + spiReceive(); + } + + // wait for response + for (uint8_t i = 0; ((m_status = spiReceive()) & 0X80) && i != 0XFF; i++) { + } + return m_status; +} +//------------------------------------------------------------------------------ +uint32_t SdSpiCard::cardSize() { + csd_t csd; + return readCSD(&csd) ? sdCardCapacity(&csd) : 0; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::erase(uint32_t firstBlock, uint32_t lastBlock) { + csd_t csd; + if (!readCSD(&csd)) { + goto fail; + } + // check for single block erase + if (!csd.v1.erase_blk_en) { + // erase size mask + uint8_t m = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; + if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) { + // error card can't erase specified area + error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); + goto fail; + } + } + if (m_type != SD_CARD_TYPE_SDHC) { + firstBlock <<= 9; + lastBlock <<= 9; + } + if (cardCommand(CMD32, firstBlock) + || cardCommand(CMD33, lastBlock) + || cardCommand(CMD38, 0)) { + error(SD_CARD_ERROR_ERASE); + goto fail; + } + if (!waitNotBusy(SD_ERASE_TIMEOUT)) { + error(SD_CARD_ERROR_ERASE_TIMEOUT); + goto fail; + } + spiStop(); + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::eraseSingleBlockEnable() { + csd_t csd; + return readCSD(&csd) ? csd.v1.erase_blk_en : false; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::isBusy() { + bool rtn = true; + bool spiActive = m_spiActive; + if (!spiActive) { + spiStart(); + } + for (uint8_t i = 0; i < 8; i++) { + if (0XFF == spiReceive()) { + rtn = false; + break; + } + } + if (!spiActive) { + spiStop(); + } + return rtn; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::isTimedOut(uint16_t startMS, uint16_t timeoutMS) { +#if WDT_YIELD_TIME_MICROS + static uint32_t last; + if ((micros() - last) > WDT_YIELD_TIME_MICROS) { + SysCall::yield(); + last = micros(); + } +#endif // WDT_YIELD_TIME_MICROS + return (curTimeMS() - startMS) > timeoutMS; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::readBlock(uint32_t blockNumber, uint8_t* dst) { + SD_TRACE("RB", blockNumber); + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) { + blockNumber <<= 9; + } + if (cardCommand(CMD17, blockNumber)) { + error(SD_CARD_ERROR_CMD17); + goto fail; + } + if (!readData(dst, 512)) { + goto fail; + } + spiStop(); + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::readBlocks(uint32_t block, uint8_t* dst, size_t count) { + if (!readStart(block)) { + return false; + } + for (uint16_t b = 0; b < count; b++, dst += 512) { + if (!readData(dst, 512)) { + return false; + } + } + return readStop(); +} +//------------------------------------------------------------------------------ +bool SdSpiCard::readData(uint8_t *dst) { + return readData(dst, 512); +} +//------------------------------------------------------------------------------ +bool SdSpiCard::readData(uint8_t* dst, size_t count) { +#if USE_SD_CRC + uint16_t crc; +#endif // USE_SD_CRC + // wait for start block token + uint16_t t0 = curTimeMS(); + while ((m_status = spiReceive()) == 0XFF) { + if (isTimedOut(t0, SD_READ_TIMEOUT)) { + error(SD_CARD_ERROR_READ_TIMEOUT); + goto fail; + } + } + if (m_status != DATA_START_BLOCK) { + error(SD_CARD_ERROR_READ); + goto fail; + } + // transfer data + if ((m_status = spiReceive(dst, count))) { + error(SD_CARD_ERROR_DMA); + goto fail; + } + +#if USE_SD_CRC + // get crc + crc = (spiReceive() << 8) | spiReceive(); + if (crc != CRC_CCITT(dst, count)) { + error(SD_CARD_ERROR_READ_CRC); + goto fail; + } +#else + // discard crc + spiReceive(); + spiReceive(); +#endif // USE_SD_CRC + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::readOCR(uint32_t* ocr) { + uint8_t *p = reinterpret_cast(ocr); + if (cardCommand(CMD58, 0)) { + error(SD_CARD_ERROR_CMD58); + goto fail; + } + for (uint8_t i = 0; i < 4; i++) { + p[3 - i] = spiReceive(); + } + + spiStop(); + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +/** read CID or CSR register */ +bool SdSpiCard::readRegister(uint8_t cmd, void* buf) { + uint8_t* dst = reinterpret_cast(buf); + if (cardCommand(cmd, 0)) { + error(SD_CARD_ERROR_READ_REG); + goto fail; + } + if (!readData(dst, 16)) { + goto fail; + } + spiStop(); + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::readStart(uint32_t blockNumber) { + SD_TRACE("RS", blockNumber); + if (type() != SD_CARD_TYPE_SDHC) { + blockNumber <<= 9; + } + if (cardCommand(CMD18, blockNumber)) { + error(SD_CARD_ERROR_CMD18); + goto fail; + } +// spiStop(); + return true; + +fail: + spiStop(); + return false; +} +//----------------------------------------------------------------------------- +bool SdSpiCard::readStatus(uint8_t* status) { + // retrun is R2 so read extra status byte. + if (cardAcmd(ACMD13, 0) || spiReceive()) { + error(SD_CARD_ERROR_ACMD13); + goto fail; + } + if (!readData(status, 64)) { + goto fail; + } + spiStop(); + return true; + +fail: + spiStop(); + return false; +} +//----------------------------------------------------------------------------- +void SdSpiCard::spiStart() { + if (!m_spiActive) { + spiActivate(); + spiSelect(); + m_spiActive = true; + } +} +//----------------------------------------------------------------------------- +void SdSpiCard::spiStop() { + if (m_spiActive) { + spiUnselect(); + spiSend(0XFF); + spiDeactivate(); + m_spiActive = false; + } +} +//------------------------------------------------------------------------------ +bool SdSpiCard::readStop() { + if (cardCommand(CMD12, 0)) { + error(SD_CARD_ERROR_CMD12); + goto fail; + } + spiStop(); + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +// wait for card to go not busy +bool SdSpiCard::waitNotBusy(uint16_t timeoutMS) { + uint16_t t0 = curTimeMS(); +#if WDT_YIELD_TIME_MICROS + // Call isTimedOut first to insure yield is called. + while (!isTimedOut(t0, timeoutMS)) { + if (spiReceive() == 0XFF) { + return true; + } + } + return false; +#else // WDT_YIELD_TIME_MICROS + // Check not busy first since yield is not called in isTimedOut. + while (spiReceive() != 0XFF) { + if (isTimedOut(t0, timeoutMS)) { + return false; + } + } + return true; +#endif // WDT_YIELD_TIME_MICROS +} +//------------------------------------------------------------------------------ +bool SdSpiCard::writeBlock(uint32_t blockNumber, const uint8_t* src) { + SD_TRACE("WB", blockNumber); + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) { + blockNumber <<= 9; + } + if (cardCommand(CMD24, blockNumber)) { + error(SD_CARD_ERROR_CMD24); + goto fail; + } + if (!writeData(DATA_START_BLOCK, src)) { + goto fail; + } + +#define CHECK_PROGRAMMING 0 +#if CHECK_PROGRAMMING + // wait for flash programming to complete + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + error(SD_CARD_ERROR_WRITE_TIMEOUT); + goto fail; + } + // response is r2 so get and check two bytes for nonzero + if (cardCommand(CMD13, 0) || spiReceive()) { + error(SD_CARD_ERROR_CMD13); + goto fail; + } +#endif // CHECK_PROGRAMMING + + spiStop(); + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::writeBlocks(uint32_t block, const uint8_t* src, size_t count) { + if (!writeStart(block)) { + goto fail; + } + for (size_t b = 0; b < count; b++, src += 512) { + if (!writeData(src)) { + goto fail; + } + } + return writeStop(); + + fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::writeData(const uint8_t* src) { + // wait for previous write to finish + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + error(SD_CARD_ERROR_WRITE_TIMEOUT); + goto fail; + } + if (!writeData(WRITE_MULTIPLE_TOKEN, src)) { + goto fail; + } + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +// send one block of data for write block or write multiple blocks +bool SdSpiCard::writeData(uint8_t token, const uint8_t* src) { +#if USE_SD_CRC + uint16_t crc = CRC_CCITT(src, 512); +#else // USE_SD_CRC + uint16_t crc = 0XFFFF; +#endif // USE_SD_CRC + spiSend(token); + spiSend(src, 512); + spiSend(crc >> 8); + spiSend(crc & 0XFF); + + m_status = spiReceive(); + if ((m_status & DATA_RES_MASK) != DATA_RES_ACCEPTED) { + error(SD_CARD_ERROR_WRITE); + goto fail; + } + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::writeStart(uint32_t blockNumber) { + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) { + blockNumber <<= 9; + } + if (cardCommand(CMD25, blockNumber)) { + error(SD_CARD_ERROR_CMD25); + goto fail; + } + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::writeStart(uint32_t blockNumber, uint32_t eraseCount) { + SD_TRACE("WS", blockNumber); + // send pre-erase count + if (cardAcmd(ACMD23, eraseCount)) { + error(SD_CARD_ERROR_ACMD23); + goto fail; + } + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) { + blockNumber <<= 9; + } + if (cardCommand(CMD25, blockNumber)) { + error(SD_CARD_ERROR_CMD25); + goto fail; + } + return true; + +fail: + spiStop(); + return false; +} +//------------------------------------------------------------------------------ +bool SdSpiCard::writeStop() { + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + goto fail; + } + spiSend(STOP_TRAN_TOKEN); + spiStop(); + return true; + +fail: + error(SD_CARD_ERROR_STOP_TRAN); + spiStop(); + return false; +} diff --git a/libraries/SdFat/src/SdCard/SdSpiCard.h b/libraries/SdFat/src/SdCard/SdSpiCard.h new file mode 100644 index 0000000..4559903 --- /dev/null +++ b/libraries/SdFat/src/SdCard/SdSpiCard.h @@ -0,0 +1,368 @@ +/* Arduino SdCard Library + * Copyright (C) 2016 by William Greiman + * + * This file is part of the Arduino SdSpiCard 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 SdSpiCard Library. If not, see + * . + */ +#ifndef SdSpiCard_h +#define SdSpiCard_h +/** + * \file + * \brief SdSpiCard class for V2 SD/SDHC cards + */ +#include +#include "SysCall.h" +#include "SdInfo.h" +#include "../FatLib/BaseBlockDriver.h" +#include "../SpiDriver/SdSpiDriver.h" +//============================================================================== +/** + * \class SdSpiCard + * \brief Raw access to SD and SDHC flash memory cards via SPI protocol. + */ +#if ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS +class SdSpiCard : public BaseBlockDriver { +#else // ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS +class SdSpiCard { +#endif // ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS + public: + /** Construct an instance of SdSpiCard. */ + SdSpiCard() : m_errorCode(SD_CARD_ERROR_INIT_NOT_CALLED), m_type(0) {} + /** Initialize the SD card. + * \param[in] spi SPI driver for card. + * \param[in] csPin card chip select pin. + * \param[in] spiSettings SPI speed, mode, and bit order. + * \return true for success else false. + */ + bool begin(SdSpiDriver* spi, uint8_t csPin, SPISettings spiSettings); + /** + * Determine the size of an SD flash memory card. + * + * \return The number of 512 byte data blocks in the card + * or zero if an error occurs. + */ + uint32_t cardSize(); + /** Erase a range of blocks. + * + * \param[in] firstBlock The address of the first block in the range. + * \param[in] lastBlock The address of the last block in the range. + * + * \note This function requests the SD card to do a flash erase for a + * range of blocks. The data on the card after an erase operation is + * either 0 or 1, depends on the card vendor. The card must support + * single block erase. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool erase(uint32_t firstBlock, uint32_t lastBlock); + /** Determine if card supports single block erase. + * + * \return true is returned if single block erase is supported. + * false is returned if single block erase is not supported. + */ + bool eraseSingleBlockEnable(); + /** + * Set SD error code. + * \param[in] code value for error code. + */ + void error(uint8_t code) { + m_errorCode = code; + } + /** + * \return code for the last error. See SdInfo.h for a list of error codes. + */ + int errorCode() const { + return m_errorCode; + } + /** \return error data for last error. */ + int errorData() const { + return m_status; + } + /** + * Check for busy. MISO low indicates the card is busy. + * + * \return true if busy else false. + */ + bool isBusy(); + /** + * Read a 512 byte block from an SD card. + * + * \param[in] lba Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readBlock(uint32_t lba, uint8_t* dst); + /** + * Read multiple 512 byte blocks from an SD card. + * + * \param[in] lba Logical block to be read. + * \param[in] nb Number of blocks to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readBlocks(uint32_t lba, uint8_t* dst, size_t nb); + /** + * Read a card's CID register. The CID contains card identification + * information such as Manufacturer ID, Product name, Product serial + * number and Manufacturing date. + * + * \param[out] cid pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCID(cid_t* cid) { + return readRegister(CMD10, cid); + } + /** + * Read a card's CSD register. The CSD contains Card-Specific Data that + * provides information regarding access to the card's contents. + * + * \param[out] csd pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCSD(csd_t* csd) { + return readRegister(CMD9, csd); + } + /** Read one data block in a multiple block read sequence + * + * \param[out] dst Pointer to the location for the data to be read. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readData(uint8_t *dst); + /** Read OCR register. + * + * \param[out] ocr Value of OCR register. + * \return true for success else false. + */ + bool readOCR(uint32_t* ocr); + /** Start a read multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * + * \note This function is used with readData() and readStop() for optimized + * multiple block reads. SPI chipSelect must be low for the entire sequence. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readStart(uint32_t blockNumber); + /** Return the 64 byte card status + * \param[out] status location for 64 status bytes. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readStatus(uint8_t* status); + /** End a read multiple blocks sequence. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readStop(); + /** \return success if sync successful. Not for user apps. */ + bool syncBlocks() {return true;} + /** Return the card type: SD V1, SD V2 or SDHC + * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. + */ + int type() const { + return m_type; + } + /** + * Writes a 512 byte block to an SD card. + * + * \param[in] lba Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeBlock(uint32_t lba, const uint8_t* src); + /** + * Write multiple 512 byte blocks to an SD card. + * + * \param[in] lba Logical block to be written. + * \param[in] nb Number of blocks to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeBlocks(uint32_t lba, const uint8_t* src, size_t nb); + /** Write one data block in a multiple block write sequence. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeData(const uint8_t* src); + /** Start a write multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * + * \note This function is used with writeData() and writeStop() + * for optimized multiple block writes. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeStart(uint32_t blockNumber); + + /** Start a write multiple blocks sequence with pre-erase. + * + * \param[in] blockNumber Address of first block in sequence. + * \param[in] eraseCount The number of blocks to be pre-erased. + * + * \note This function is used with writeData() and writeStop() + * for optimized multiple block writes. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeStart(uint32_t blockNumber, uint32_t eraseCount); + /** End a write multiple blocks sequence. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeStop(); + /** Set CS low and activate the card. */ + void spiStart(); + /** Set CS high and deactivate the card. */ + void spiStop(); + + private: + // private functions + uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { + cardCommand(CMD55, 0); + return cardCommand(cmd, arg); + } + uint8_t cardCommand(uint8_t cmd, uint32_t arg); + bool isTimedOut(uint16_t startMS, uint16_t timeoutMS); + bool readData(uint8_t* dst, size_t count); + bool readRegister(uint8_t cmd, void* buf); + + void type(uint8_t value) { + m_type = value; + } + + bool waitNotBusy(uint16_t timeoutMS); + bool writeData(uint8_t token, const uint8_t* src); + + //--------------------------------------------------------------------------- + // functions defined in SdSpiDriver.h + void spiActivate() { + m_spiDriver->activate(); + } + void spiDeactivate() { + m_spiDriver->deactivate(); + } + uint8_t spiReceive() { + return m_spiDriver->receive(); + } + uint8_t spiReceive(uint8_t* buf, size_t n) { + return m_spiDriver->receive(buf, n); + } + void spiSend(uint8_t data) { + m_spiDriver->send(data); + } + void spiSend(const uint8_t* buf, size_t n) { + m_spiDriver->send(buf, n); + } + void spiSelect() { + m_spiDriver->select(); + } + void spiUnselect() { + m_spiDriver->unselect(); + } + uint8_t m_errorCode; + SdSpiDriver *m_spiDriver; + bool m_spiActive; + uint8_t m_status; + uint8_t m_type; +}; +//============================================================================== +/** + * \class SdSpiCardEX + * \brief Extended SD I/O block driver. + */ +class SdSpiCardEX : public SdSpiCard { + public: + /** Initialize the SD card + * + * \param[in] spi SPI driver. + * \param[in] csPin Card chip select pin number. + * \param[in] spiSettings SPI speed, mode, and bit order. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool begin(SdSpiDriver* spi, uint8_t csPin, SPISettings spiSettings) { + m_curState = IDLE_STATE; + return SdSpiCard::begin(spi, csPin, spiSettings); + } + /** + * Read a 512 byte block from an SD card. + * + * \param[in] block Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readBlock(uint32_t block, uint8_t* dst); + /** End multi-block transfer and go to idle state. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool syncBlocks(); + /** + * Writes a 512 byte block to an SD card. + * + * \param[in] block Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeBlock(uint32_t block, const uint8_t* src); + /** + * Read multiple 512 byte blocks from an SD card. + * + * \param[in] block Logical block to be read. + * \param[in] nb Number of blocks to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readBlocks(uint32_t block, uint8_t* dst, size_t nb); + /** + * Write multiple 512 byte blocks to an SD card. + * + * \param[in] block Logical block to be written. + * \param[in] nb Number of blocks to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeBlocks(uint32_t block, const uint8_t* src, size_t nb); + + private: + static const uint32_t IDLE_STATE = 0; + static const uint32_t READ_STATE = 1; + static const uint32_t WRITE_STATE = 2; + uint32_t m_curBlock; + uint8_t m_curState; +}; +#endif // SdSpiCard_h diff --git a/libraries/SdFat/src/SdCard/SdSpiCardEX.cpp b/libraries/SdFat/src/SdCard/SdSpiCardEX.cpp new file mode 100644 index 0000000..a3a5600 --- /dev/null +++ b/libraries/SdFat/src/SdCard/SdSpiCardEX.cpp @@ -0,0 +1,89 @@ +/* Arduino SdFat Library + * Copyright (C) 2016 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 + * . + */ +#include "SdSpiCard.h" +bool SdSpiCardEX::readBlock(uint32_t block, uint8_t* dst) { + if (m_curState != READ_STATE || block != m_curBlock) { + if (!syncBlocks()) { + return false; + } + if (!SdSpiCard::readStart(block)) { + return false; + } + m_curBlock = block; + m_curState = READ_STATE; + } + if (!SdSpiCard::readData(dst)) { + return false; + } + m_curBlock++; + return true; +} +//----------------------------------------------------------------------------- +bool SdSpiCardEX::readBlocks(uint32_t block, uint8_t* dst, size_t nb) { + for (size_t i = 0; i < nb; i++) { + if (!readBlock(block + i, dst + i*512UL)) { + return false; + } + } + return true; +} +//----------------------------------------------------------------------------- +bool SdSpiCardEX::syncBlocks() { + if (m_curState == READ_STATE) { + m_curState = IDLE_STATE; + if (!SdSpiCard::readStop()) { + return false; + } + } else if (m_curState == WRITE_STATE) { + m_curState = IDLE_STATE; + if (!SdSpiCard::writeStop()) { + return false; + } + } + return true; +} +//----------------------------------------------------------------------------- +bool SdSpiCardEX::writeBlock(uint32_t block, const uint8_t* src) { + if (m_curState != WRITE_STATE || m_curBlock != block) { + if (!syncBlocks()) { + return false; + } + if (!SdSpiCard::writeStart(block)) { + return false; + } + m_curBlock = block; + m_curState = WRITE_STATE; + } + if (!SdSpiCard::writeData(src)) { + return false; + } + m_curBlock++; + return true; +} +//----------------------------------------------------------------------------- +bool SdSpiCardEX::writeBlocks(uint32_t block, + const uint8_t* src, size_t nb) { + for (size_t i = 0; i < nb; i++) { + if (!writeBlock(block + i, src + i*512UL)) { + return false; + } + } + return true; +} diff --git a/libraries/SdFat/src/SdCard/SdioCard.h b/libraries/SdFat/src/SdCard/SdioCard.h new file mode 100644 index 0000000..2135326 --- /dev/null +++ b/libraries/SdFat/src/SdCard/SdioCard.h @@ -0,0 +1,296 @@ +/* Arduino SdCard Library + * Copyright (C) 2016 by William Greiman + * + * This file is part of the Arduino SdSpiCard 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 SdSpiCard Library. If not, see + * . + */ +#ifndef SdioCard_h +#define SdioCard_h +#include "SysCall.h" +#include "BlockDriver.h" +/** + * \class SdioCard + * \brief Raw SDIO access to SD and SDHC flash memory cards. + */ +class SdioCard : public BaseBlockDriver { + public: + /** Initialize the SD card. + * \return true for success else false. + */ + bool begin(); + /** + * Determine the size of an SD flash memory card. + * + * \return The number of 512 byte data blocks in the card + * or zero if an error occurs. + */ + uint32_t cardSize(); + /** Erase a range of blocks. + * + * \param[in] firstBlock The address of the first block in the range. + * \param[in] lastBlock The address of the last block in the range. + * + * \note This function requests the SD card to do a flash erase for a + * range of blocks. The data on the card after an erase operation is + * either 0 or 1, depends on the card vendor. The card must support + * single block erase. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool erase(uint32_t firstBlock, uint32_t lastBlock); + /** + * \return code for the last error. See SdInfo.h for a list of error codes. + */ + uint8_t errorCode(); + /** \return error data for last error. */ + uint32_t errorData(); + /** \return error line for last error. Tmp function for debug. */ + uint32_t errorLine(); + /** + * Check for busy with CMD13. + * + * \return true if busy else false. + */ + bool isBusy(); + /** \return the SD clock frequency in kHz. */ + uint32_t kHzSdClk(); + /** + * Read a 512 byte block from an SD card. + * + * \param[in] lba Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readBlock(uint32_t lba, uint8_t* dst); + /** + * Read multiple 512 byte blocks from an SD card. + * + * \param[in] lba Logical block to be read. + * \param[in] nb Number of blocks to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readBlocks(uint32_t lba, uint8_t* dst, size_t nb); + /** + * Read a card's CID register. The CID contains card identification + * information such as Manufacturer ID, Product name, Product serial + * number and Manufacturing date. + * + * \param[out] cid pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCID(void* cid); + /** + * Read a card's CSD register. The CSD contains Card-Specific Data that + * provides information regarding access to the card's contents. + * + * \param[out] csd pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCSD(void* csd); + /** Read one data block in a multiple block read sequence + * + * \param[out] dst Pointer to the location for the data to be read. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readData(uint8_t *dst); + /** Read OCR register. + * + * \param[out] ocr Value of OCR register. + * \return true for success else false. + */ + bool readOCR(uint32_t* ocr); + /** Start a read multiple blocks sequence. + * + * \param[in] lba Address of first block in sequence. + * + * \note This function is used with readData() and readStop() for optimized + * multiple block reads. SPI chipSelect must be low for the entire sequence. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readStart(uint32_t lba); + /** Start a read multiple blocks sequence. + * + * \param[in] lba Address of first block in sequence. + * \param[in] count Maximum block count. + * \note This function is used with readData() and readStop() for optimized + * multiple block reads. SPI chipSelect must be low for the entire sequence. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readStart(uint32_t lba, uint32_t count); + /** End a read multiple blocks sequence. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readStop(); + /** \return success if sync successful. Not for user apps. */ + bool syncBlocks(); + /** Return the card type: SD V1, SD V2 or SDHC + * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. + */ + uint8_t type(); + /** + * Writes a 512 byte block to an SD card. + * + * \param[in] lba Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeBlock(uint32_t lba, const uint8_t* src); + /** + * Write multiple 512 byte blocks to an SD card. + * + * \param[in] lba Logical block to be written. + * \param[in] nb Number of blocks to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeBlocks(uint32_t lba, const uint8_t* src, size_t nb); + /** Write one data block in a multiple block write sequence. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeData(const uint8_t* src); + /** Start a write multiple blocks sequence. + * + * \param[in] lba Address of first block in sequence. + * + * \note This function is used with writeData() and writeStop() + * for optimized multiple block writes. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeStart(uint32_t lba); + /** Start a write multiple blocks sequence. + * + * \param[in] lba Address of first block in sequence. + * \param[in] count Maximum block count. + * \note This function is used with writeData() and writeStop() + * for optimized multiple block writes. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeStart(uint32_t lba, uint32_t count); + + /** End a write multiple blocks sequence. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeStop(); +}; +//============================================================================== +/** + * \class SdioCardEX + * \brief Extended SD I/O block driver. + */ +class SdioCardEX : public SdioCard { + public: + /** Initialize the SD card + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool begin() { + m_curState = IDLE_STATE; + return SdioCard::begin(); + } + /** Erase a range of blocks. + * + * \param[in] firstBlock The address of the first block in the range. + * \param[in] lastBlock The address of the last block in the range. + * + * \note This function requests the SD card to do a flash erase for a + * range of blocks. The data on the card after an erase operation is + * either 0 or 1, depends on the card vendor. The card must support + * single block erase. + * + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool erase(uint32_t firstBlock, uint32_t lastBlock) { + return syncBlocks() && SdioCard::erase(firstBlock, lastBlock); + } + /** + * Read a 512 byte block from an SD card. + * + * \param[in] block Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readBlock(uint32_t block, uint8_t* dst); + /** End multi-block transfer and go to idle state. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool syncBlocks(); + /** + * Writes a 512 byte block to an SD card. + * + * \param[in] block Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeBlock(uint32_t block, const uint8_t* src); + /** + * Read multiple 512 byte blocks from an SD card. + * + * \param[in] block Logical block to be read. + * \param[in] nb Number of blocks to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool readBlocks(uint32_t block, uint8_t* dst, size_t nb); + /** + * Write multiple 512 byte blocks to an SD card. + * + * \param[in] block Logical block to be written. + * \param[in] nb Number of blocks to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value true is returned for success and + * the value false is returned for failure. + */ + bool writeBlocks(uint32_t block, const uint8_t* src, size_t nb); + + private: + static const uint32_t IDLE_STATE = 0; + static const uint32_t READ_STATE = 1; + static const uint32_t WRITE_STATE = 2; + uint32_t m_curLba; + uint32_t m_limitLba; + uint8_t m_curState; +}; +#endif // SdioCard_h diff --git a/libraries/SdFat/src/SdCard/SdioCardEX.cpp b/libraries/SdFat/src/SdCard/SdioCardEX.cpp new file mode 100644 index 0000000..07267bd --- /dev/null +++ b/libraries/SdFat/src/SdCard/SdioCardEX.cpp @@ -0,0 +1,103 @@ +/* Arduino SdFat Library + * Copyright (C) 2016 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 + * . + */ +#include "SdioCard.h" + +// limit of K66 due to errata KINETIS_K_0N65N. +const uint32_t MAX_SDHC_COUNT = 0XFFFF; + +// Max RU is 1024 blocks. +const uint32_t RU_MASK = 0X03FF; + +bool SdioCardEX::readBlock(uint32_t lba, uint8_t* dst) { + if (m_curState != READ_STATE || lba != m_curLba) { + if (!syncBlocks()) { + return false; + } + m_limitLba = (lba + MAX_SDHC_COUNT) & ~RU_MASK; + if (!SdioCard::readStart(lba, m_limitLba - lba)) { + return false; + } + m_curLba = lba; + m_curState = READ_STATE; + } + if (!SdioCard::readData(dst)) { + return false; + } + m_curLba++; + if (m_curLba >= m_limitLba) { + m_curState = IDLE_STATE; + } + return true; +} +//----------------------------------------------------------------------------- +bool SdioCardEX::readBlocks(uint32_t lba, uint8_t* dst, size_t nb) { + for (size_t i = 0; i < nb; i++) { + if (!readBlock(lba + i, dst + i*512UL)) { + return false; + } + } + return true; +} +//----------------------------------------------------------------------------- +bool SdioCardEX::syncBlocks() { + if (m_curState == READ_STATE) { + m_curState = IDLE_STATE; + if (!SdioCard::readStop()) { + return false; + } + } else if (m_curState == WRITE_STATE) { + m_curState = IDLE_STATE; + if (!SdioCard::writeStop()) { + return false; + } + } + return true; +} +//----------------------------------------------------------------------------- +bool SdioCardEX::writeBlock(uint32_t lba, const uint8_t* src) { + if (m_curState != WRITE_STATE || m_curLba != lba) { + if (!syncBlocks()) { + return false; + } + m_limitLba = (lba + MAX_SDHC_COUNT) & ~RU_MASK; + if (!SdioCard::writeStart(lba , m_limitLba - lba)) { + return false; + } + m_curLba = lba; + m_curState = WRITE_STATE; + } + if (!SdioCard::writeData(src)) { + return false; + } + m_curLba++; + if (m_curLba >= m_limitLba) { + m_curState = IDLE_STATE; + } + return true; +} +//----------------------------------------------------------------------------- +bool SdioCardEX::writeBlocks(uint32_t lba, const uint8_t* src, size_t nb) { + for (size_t i = 0; i < nb; i++) { + if (!writeBlock(lba + i, src + i*512UL)) { + return false; + } + } + return true; +} diff --git a/libraries/SdFat/src/SdCard/SdioTeensy.cpp b/libraries/SdFat/src/SdCard/SdioTeensy.cpp new file mode 100644 index 0000000..91bd6e3 --- /dev/null +++ b/libraries/SdFat/src/SdCard/SdioTeensy.cpp @@ -0,0 +1,795 @@ +/* Arduino SdCard Library + * Copyright (C) 2016 by William Greiman + * + * This file is part of the Arduino SdSpiCard 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 SdSpiCard Library. If not, see + * . + */ +#if defined(__MK64FX512__) || defined(__MK66FX1M0__) +#include "SdioCard.h" +//============================================================================== +#define SDHC_PROCTL_DTW_4BIT 0x01 +const uint32_t FIFO_WML = 16; +const uint32_t CMD8_RETRIES = 10; +const uint32_t BUSY_TIMEOUT_MICROS = 500000; +//============================================================================== +const uint32_t SDHC_IRQSTATEN_MASK = + SDHC_IRQSTATEN_DMAESEN | SDHC_IRQSTATEN_AC12ESEN | + SDHC_IRQSTATEN_DEBESEN | SDHC_IRQSTATEN_DCESEN | + SDHC_IRQSTATEN_DTOESEN | SDHC_IRQSTATEN_CIESEN | + SDHC_IRQSTATEN_CEBESEN | SDHC_IRQSTATEN_CCESEN | + SDHC_IRQSTATEN_CTOESEN | SDHC_IRQSTATEN_DINTSEN | + SDHC_IRQSTATEN_TCSEN | SDHC_IRQSTATEN_CCSEN; + +const uint32_t SDHC_IRQSTAT_CMD_ERROR = + SDHC_IRQSTAT_CIE | SDHC_IRQSTAT_CEBE | + SDHC_IRQSTAT_CCE | SDHC_IRQSTAT_CTOE; + +const uint32_t SDHC_IRQSTAT_DATA_ERROR = + SDHC_IRQSTAT_AC12E | SDHC_IRQSTAT_DEBE | + SDHC_IRQSTAT_DCE | SDHC_IRQSTAT_DTOE; + +const uint32_t SDHC_IRQSTAT_ERROR = + SDHC_IRQSTAT_DMAE | SDHC_IRQSTAT_CMD_ERROR | + SDHC_IRQSTAT_DATA_ERROR; + +const uint32_t SDHC_IRQSIGEN_MASK = + SDHC_IRQSIGEN_DMAEIEN | SDHC_IRQSIGEN_AC12EIEN | + SDHC_IRQSIGEN_DEBEIEN | SDHC_IRQSIGEN_DCEIEN | + SDHC_IRQSIGEN_DTOEIEN | SDHC_IRQSIGEN_CIEIEN | + SDHC_IRQSIGEN_CEBEIEN | SDHC_IRQSIGEN_CCEIEN | + SDHC_IRQSIGEN_CTOEIEN | SDHC_IRQSIGEN_TCIEN; +//============================================================================= +const uint32_t CMD_RESP_NONE = SDHC_XFERTYP_RSPTYP(0); + +const uint32_t CMD_RESP_R1 = SDHC_XFERTYP_CICEN | SDHC_XFERTYP_CCCEN | + SDHC_XFERTYP_RSPTYP(2); + +const uint32_t CMD_RESP_R1b = SDHC_XFERTYP_CICEN | SDHC_XFERTYP_CCCEN | + SDHC_XFERTYP_RSPTYP(3); + +const uint32_t CMD_RESP_R2 = SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(1); + +const uint32_t CMD_RESP_R3 = SDHC_XFERTYP_RSPTYP(2); + +const uint32_t CMD_RESP_R6 = CMD_RESP_R1; + +const uint32_t CMD_RESP_R7 = CMD_RESP_R1; + +const uint32_t DATA_READ = SDHC_XFERTYP_DTDSEL | SDHC_XFERTYP_DPSEL; + +const uint32_t DATA_READ_DMA = DATA_READ | SDHC_XFERTYP_DMAEN; + +const uint32_t DATA_READ_MULTI_DMA = DATA_READ_DMA | SDHC_XFERTYP_MSBSEL | + SDHC_XFERTYP_AC12EN | SDHC_XFERTYP_BCEN; + +const uint32_t DATA_READ_MULTI_PGM = DATA_READ | SDHC_XFERTYP_MSBSEL | + SDHC_XFERTYP_BCEN | SDHC_XFERTYP_AC12EN; + +const uint32_t DATA_WRITE_DMA = SDHC_XFERTYP_DPSEL | SDHC_XFERTYP_DMAEN; + +const uint32_t DATA_WRITE_MULTI_DMA = DATA_WRITE_DMA | SDHC_XFERTYP_MSBSEL | + SDHC_XFERTYP_AC12EN | SDHC_XFERTYP_BCEN; + +const uint32_t DATA_WRITE_MULTI_PGM = SDHC_XFERTYP_DPSEL | + SDHC_XFERTYP_MSBSEL | + SDHC_XFERTYP_BCEN | SDHC_XFERTYP_AC12EN; + +const uint32_t ACMD6_XFERTYP = SDHC_XFERTYP_CMDINX(ACMD6) | CMD_RESP_R1; + +const uint32_t ACMD41_XFERTYP = SDHC_XFERTYP_CMDINX(ACMD41) | CMD_RESP_R3; + +const uint32_t CMD0_XFERTYP = SDHC_XFERTYP_CMDINX(CMD0) | CMD_RESP_NONE; + +const uint32_t CMD2_XFERTYP = SDHC_XFERTYP_CMDINX(CMD2) | CMD_RESP_R2; + +const uint32_t CMD3_XFERTYP = SDHC_XFERTYP_CMDINX(CMD3) | CMD_RESP_R6; + +const uint32_t CMD6_XFERTYP = SDHC_XFERTYP_CMDINX(CMD6) | CMD_RESP_R1 | + DATA_READ_DMA; + +const uint32_t CMD7_XFERTYP = SDHC_XFERTYP_CMDINX(CMD7) | CMD_RESP_R1b; + +const uint32_t CMD8_XFERTYP = SDHC_XFERTYP_CMDINX(CMD8) | CMD_RESP_R7; + +const uint32_t CMD9_XFERTYP = SDHC_XFERTYP_CMDINX(CMD9) | CMD_RESP_R2; + +const uint32_t CMD10_XFERTYP = SDHC_XFERTYP_CMDINX(CMD10) | CMD_RESP_R2; + +const uint32_t CMD12_XFERTYP = SDHC_XFERTYP_CMDINX(CMD12) | CMD_RESP_R1b | + SDHC_XFERTYP_CMDTYP(3); + +const uint32_t CMD13_XFERTYP = SDHC_XFERTYP_CMDINX(CMD13) | CMD_RESP_R1; + +const uint32_t CMD17_DMA_XFERTYP = SDHC_XFERTYP_CMDINX(CMD17) | CMD_RESP_R1 | + DATA_READ_DMA; + +const uint32_t CMD18_DMA_XFERTYP = SDHC_XFERTYP_CMDINX(CMD18) | CMD_RESP_R1 | + DATA_READ_MULTI_DMA; + +const uint32_t CMD18_PGM_XFERTYP = SDHC_XFERTYP_CMDINX(CMD18) | CMD_RESP_R1 | + DATA_READ_MULTI_PGM; + +const uint32_t CMD24_DMA_XFERTYP = SDHC_XFERTYP_CMDINX(CMD24) | CMD_RESP_R1 | + DATA_WRITE_DMA; + +const uint32_t CMD25_DMA_XFERTYP = SDHC_XFERTYP_CMDINX(CMD25) | CMD_RESP_R1 | + DATA_WRITE_MULTI_DMA; + +const uint32_t CMD25_PGM_XFERTYP = SDHC_XFERTYP_CMDINX(CMD25) | CMD_RESP_R1 | + DATA_WRITE_MULTI_PGM; + +const uint32_t CMD32_XFERTYP = SDHC_XFERTYP_CMDINX(CMD32) | CMD_RESP_R1; + +const uint32_t CMD33_XFERTYP = SDHC_XFERTYP_CMDINX(CMD33) | CMD_RESP_R1; + +const uint32_t CMD38_XFERTYP = SDHC_XFERTYP_CMDINX(CMD38) | CMD_RESP_R1b; + +const uint32_t CMD55_XFERTYP = SDHC_XFERTYP_CMDINX(CMD55) | CMD_RESP_R1; + +//============================================================================= +static bool cardCommand(uint32_t xfertyp, uint32_t arg); +static void enableGPIO(bool enable); +static void enableDmaIrs(); +static void initSDHC(); +static bool isBusyCMD13(); +static bool isBusyCommandComplete(); +static bool isBusyCommandInhibit(); +static bool readReg16(uint32_t xfertyp, void* data); +static void setSdclk(uint32_t kHzMax); +static bool yieldTimeout(bool (*fcn)()); +static bool waitDmaStatus(); +static bool waitTimeout(bool (*fcn)()); +//----------------------------------------------------------------------------- +static bool (*m_busyFcn)() = 0; +static bool m_initDone = false; +static bool m_version2; +static bool m_highCapacity; +static uint8_t m_errorCode = SD_CARD_ERROR_INIT_NOT_CALLED; +static uint32_t m_errorLine = 0; +static uint32_t m_rca; +static volatile bool m_dmaBusy = false; +static volatile uint32_t m_irqstat; +static uint32_t m_sdClkKhz = 0; +static uint32_t m_ocr; +static cid_t m_cid; +static csd_t m_csd; +//============================================================================= +#define USE_DEBUG_MODE 0 +#if USE_DEBUG_MODE +#define DBG_IRQSTAT() if (SDHC_IRQSTAT) {Serial.print(__LINE__);\ + Serial.print(" IRQSTAT "); Serial.println(SDHC_IRQSTAT, HEX);} + +static void printRegs(uint32_t line) { + Serial.print(line); + Serial.print(" PRSSTAT "); + Serial.print(SDHC_PRSSTAT, HEX); + Serial.print(" PROCTL "); + Serial.print(SDHC_PROCTL, HEX); + Serial.print(" IRQSTAT "); + Serial.print(SDHC_IRQSTAT, HEX); + Serial.print(" m_irqstat "); + Serial.println(m_irqstat, HEX); +} +#else // USE_DEBUG_MODE +#define DBG_IRQSTAT() +#endif // USE_DEBUG_MODE +//============================================================================= +// Error function and macro. +#define sdError(code) setSdErrorCode(code, __LINE__) +inline bool setSdErrorCode(uint8_t code, uint32_t line) { + m_errorCode = code; + m_errorLine = line; + return false; // setSdErrorCode +} +//============================================================================= +// ISR +void sdhc_isr() { + SDHC_IRQSIGEN = 0; + m_irqstat = SDHC_IRQSTAT; + SDHC_IRQSTAT = m_irqstat; + m_dmaBusy = false; +} +//============================================================================= +// Static functions. +static bool cardAcmd(uint32_t rca, uint32_t xfertyp, uint32_t arg) { + return cardCommand(CMD55_XFERTYP, rca) && cardCommand (xfertyp, arg); +} +//----------------------------------------------------------------------------- +static bool cardCommand(uint32_t xfertyp, uint32_t arg) { + DBG_IRQSTAT(); + if (waitTimeout(isBusyCommandInhibit)) { + return false; // Caller will set errorCode. + } + SDHC_CMDARG = arg; + SDHC_XFERTYP = xfertyp; + if (waitTimeout(isBusyCommandComplete)) { + return false; // Caller will set errorCode. + } + m_irqstat = SDHC_IRQSTAT; + SDHC_IRQSTAT = m_irqstat; + + return (m_irqstat & SDHC_IRQSTAT_CC) && + !(m_irqstat & SDHC_IRQSTAT_CMD_ERROR); +} +//----------------------------------------------------------------------------- +static bool cardCMD6(uint32_t arg, uint8_t* status) { + // CMD6 returns 64 bytes. + if (waitTimeout(isBusyCMD13)) { + return sdError(SD_CARD_ERROR_CMD13); + } + enableDmaIrs(); + SDHC_DSADDR = (uint32_t)status; + SDHC_CMDARG = arg; + SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | SDHC_BLKATTR_BLKSIZE(64); + SDHC_IRQSIGEN = SDHC_IRQSIGEN_MASK; + SDHC_XFERTYP = CMD6_XFERTYP; + + if (!waitDmaStatus()) { + return sdError(SD_CARD_ERROR_CMD6); + } + return true; +} +//----------------------------------------------------------------------------- +static void enableGPIO(bool enable) { + const uint32_t PORT_CLK = PORT_PCR_MUX(4) | PORT_PCR_DSE; + const uint32_t PORT_CMD_DATA = PORT_CLK | PORT_PCR_PS | PORT_PCR_PE; + + PORTE_PCR0 = enable ? PORT_CMD_DATA : 0; // SDHC_D1 + PORTE_PCR1 = enable ? PORT_CMD_DATA : 0; // SDHC_D0 + PORTE_PCR2 = enable ? PORT_CLK : 0; // SDHC_CLK + PORTE_PCR3 = enable ? PORT_CMD_DATA : 0; // SDHC_CMD + PORTE_PCR4 = enable ? PORT_CMD_DATA : 0; // SDHC_D3 + PORTE_PCR5 = enable ? PORT_CMD_DATA : 0; // SDHC_D2 +} +//----------------------------------------------------------------------------- +static void enableDmaIrs() { + m_dmaBusy = true; + m_irqstat = 0; +} +//----------------------------------------------------------------------------- +static void initSDHC() { +#ifdef HAS_KINETIS_MPU + // Allow SDHC Bus Master access. + MPU_RGDAAC0 |= 0x0C000000; +#endif + // Enable SDHC clock. + SIM_SCGC3 |= SIM_SCGC3_SDHC; + + // Disable GPIO clock. + enableGPIO(false); + + // Reset SDHC. Use default Water Mark Level of 16. + SDHC_SYSCTL = SDHC_SYSCTL_RSTA; + while (SDHC_SYSCTL & SDHC_SYSCTL_RSTA) { + } + // Set initial SCK rate. + setSdclk(400); + + enableGPIO(true); + + // Enable desired IRQSTAT bits. + SDHC_IRQSTATEN = SDHC_IRQSTATEN_MASK; + + NVIC_SET_PRIORITY(IRQ_SDHC, 6*16); + NVIC_ENABLE_IRQ(IRQ_SDHC); + + // Send 80 clocks to card. + SDHC_SYSCTL |= SDHC_SYSCTL_INITA; + while (SDHC_SYSCTL & SDHC_SYSCTL_INITA) { + } +} +//----------------------------------------------------------------------------- +static bool isBusyCMD13() { + if (!cardCommand(CMD13_XFERTYP, m_rca)) { + // Caller will timeout. + return true; + } + return !(SDHC_CMDRSP0 & CARD_STATUS_READY_FOR_DATA); +} +//----------------------------------------------------------------------------- +static bool isBusyCommandComplete() { + return !(SDHC_IRQSTAT &(SDHC_IRQSTAT_CC | SDHC_IRQSTAT_CMD_ERROR)); +} +//----------------------------------------------------------------------------- +static bool isBusyCommandInhibit() { + return SDHC_PRSSTAT & SDHC_PRSSTAT_CIHB; +} +//----------------------------------------------------------------------------- +static bool isBusyDMA() { + return m_dmaBusy; +} +//----------------------------------------------------------------------------- +static bool isBusyFifoRead() { + return !(SDHC_PRSSTAT & SDHC_PRSSTAT_BREN); +} +//----------------------------------------------------------------------------- +static bool isBusyFifoWrite() { + return !(SDHC_PRSSTAT & SDHC_PRSSTAT_BWEN); +} +//----------------------------------------------------------------------------- +static bool isBusyTransferComplete() { + return !(SDHC_IRQSTAT & (SDHC_IRQSTAT_TC | SDHC_IRQSTAT_ERROR)); +} +//----------------------------------------------------------------------------- +static bool rdWrBlocks(uint32_t xfertyp, + uint32_t lba, uint8_t* buf, size_t n) { + if ((3 & (uint32_t)buf) || n == 0) { + return sdError(SD_CARD_ERROR_DMA); + } + if (yieldTimeout(isBusyCMD13)) { + return sdError(SD_CARD_ERROR_CMD13); + } + enableDmaIrs(); + SDHC_DSADDR = (uint32_t)buf; + SDHC_CMDARG = m_highCapacity ? lba : 512*lba; + SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(n) | SDHC_BLKATTR_BLKSIZE(512); + SDHC_IRQSIGEN = SDHC_IRQSIGEN_MASK; + SDHC_XFERTYP = xfertyp; + + return waitDmaStatus(); +} +//----------------------------------------------------------------------------- +// Read 16 byte CID or CSD register. +static bool readReg16(uint32_t xfertyp, void* data) { + uint8_t* d = reinterpret_cast(data); + if (!cardCommand(xfertyp, m_rca)) { + return false; // Caller will set errorCode. + } + uint32_t sr[] = {SDHC_CMDRSP0, SDHC_CMDRSP1, SDHC_CMDRSP2, SDHC_CMDRSP3}; + for (int i = 0; i < 15; i++) { + d[14 - i] = sr[i/4] >> 8*(i%4); + } + d[15] = 0; + return true; +} +//----------------------------------------------------------------------------- +static void setSdclk(uint32_t kHzMax) { + const uint32_t DVS_LIMIT = 0X10; + const uint32_t SDCLKFS_LIMIT = 0X100; + uint32_t dvs = 1; + uint32_t sdclkfs = 1; + uint32_t maxSdclk = 1000*kHzMax; + + while ((F_CPU/(sdclkfs*DVS_LIMIT) > maxSdclk) && (sdclkfs < SDCLKFS_LIMIT)) { + sdclkfs <<= 1; + } + while ((F_CPU/(sdclkfs*dvs) > maxSdclk) && (dvs < DVS_LIMIT)) { + dvs++; + } + m_sdClkKhz = F_CPU/(1000*sdclkfs*dvs); + sdclkfs >>= 1; + dvs--; + + // Disable SDHC clock. + SDHC_SYSCTL &= ~SDHC_SYSCTL_SDCLKEN; + + // Change dividers. + uint32_t sysctl = SDHC_SYSCTL & ~(SDHC_SYSCTL_DTOCV_MASK + | SDHC_SYSCTL_DVS_MASK | SDHC_SYSCTL_SDCLKFS_MASK); + + SDHC_SYSCTL = sysctl | SDHC_SYSCTL_DTOCV(0x0E) | SDHC_SYSCTL_DVS(dvs) + | SDHC_SYSCTL_SDCLKFS(sdclkfs); + + // Wait until the SDHC clock is stable. + while (!(SDHC_PRSSTAT & SDHC_PRSSTAT_SDSTB)) { + } + // Enable the SDHC clock. + SDHC_SYSCTL |= SDHC_SYSCTL_SDCLKEN; +} +//----------------------------------------------------------------------------- +static bool transferStop() { + DBG_IRQSTAT(); + + if (!cardCommand(CMD12_XFERTYP, 0)) { + return sdError(SD_CARD_ERROR_CMD12); + } + if (yieldTimeout(isBusyCMD13)) { + return sdError(SD_CARD_ERROR_CMD13); + } + // Save registers before reset DAT lines. + uint32_t irqsststen = SDHC_IRQSTATEN; + uint32_t proctl = SDHC_PROCTL & ~SDHC_PROCTL_SABGREQ; + + // Do reset to clear CDIHB. Should be a better way! + SDHC_SYSCTL |= SDHC_SYSCTL_RSTD; + + // Restore registers. + SDHC_IRQSTATEN = irqsststen; + SDHC_PROCTL = proctl; + + return true; +} +//----------------------------------------------------------------------------- +// Return true if timeout occurs. +static bool yieldTimeout(bool (*fcn)()) { + m_busyFcn = fcn; + uint32_t m = micros(); + while (fcn()) { + if ((micros() - m) > BUSY_TIMEOUT_MICROS) { + m_busyFcn = 0; + return true; + } + yield(); + } + m_busyFcn = 0; + return false; // Caller will set errorCode. +} +//----------------------------------------------------------------------------- +static bool waitDmaStatus() { + if (yieldTimeout(isBusyDMA)) { + return false; // Caller will set errorCode. + } + return (m_irqstat & SDHC_IRQSTAT_TC) && !(m_irqstat & SDHC_IRQSTAT_ERROR); +} +//----------------------------------------------------------------------------- +// Return true if timeout occurs. +static bool waitTimeout(bool (*fcn)()) { + uint32_t m = micros(); + while (fcn()) { + if ((micros() - m) > BUSY_TIMEOUT_MICROS) { + return true; + } + } + return false; // Caller will set errorCode. +} +//============================================================================= +bool SdioCard::begin() { + uint32_t kHzSdClk; + uint32_t arg; + m_initDone = false; + m_errorCode = SD_CARD_ERROR_NONE; + m_highCapacity = false; + m_version2 = false; + + // initialize controller. + initSDHC(); + + if (!cardCommand(CMD0_XFERTYP, 0)) { + return sdError(SD_CARD_ERROR_CMD0); + } + // Try several times for case of reset delay. + for (uint32_t i = 0; i < CMD8_RETRIES; i++) { + if (cardCommand(CMD8_XFERTYP, 0X1AA)) { + if (SDHC_CMDRSP0 != 0X1AA) { + return sdError(SD_CARD_ERROR_CMD8); + } + m_version2 = true; + break; + } + } + arg = m_version2 ? 0X40300000 : 0x00300000; + uint32_t m = micros(); + do { + if (!cardAcmd(0, ACMD41_XFERTYP, arg) || + ((micros() - m) > BUSY_TIMEOUT_MICROS)) { + return sdError(SD_CARD_ERROR_ACMD41); + } + } while ((SDHC_CMDRSP0 & 0x80000000) == 0); + + m_ocr = SDHC_CMDRSP0; + if (SDHC_CMDRSP0 & 0x40000000) { + // Is high capacity. + m_highCapacity = true; + } + if (!cardCommand(CMD2_XFERTYP, 0)) { + return sdError(SD_CARD_ERROR_CMD2); + } + if (!cardCommand(CMD3_XFERTYP, 0)) { + return sdError(SD_CARD_ERROR_CMD3); + } + m_rca = SDHC_CMDRSP0 & 0xFFFF0000; + + if (!readReg16(CMD9_XFERTYP, &m_csd)) { + return sdError(SD_CARD_ERROR_CMD9); + } + if (!readReg16(CMD10_XFERTYP, &m_cid)) { + return sdError(SD_CARD_ERROR_CMD10); + } + if (!cardCommand(CMD7_XFERTYP, m_rca)) { + return sdError(SD_CARD_ERROR_CMD7); + } + // Set card to bus width four. + if (!cardAcmd(m_rca, ACMD6_XFERTYP, 2)) { + return sdError(SD_CARD_ERROR_ACMD6); + } + // Set SDHC to bus width four. + SDHC_PROCTL &= ~SDHC_PROCTL_DTW_MASK; + SDHC_PROCTL |= SDHC_PROCTL_DTW(SDHC_PROCTL_DTW_4BIT); + + SDHC_WML = SDHC_WML_RDWML(FIFO_WML) | SDHC_WML_WRWML(FIFO_WML); + + // Determine if High Speed mode is supported and set frequency. + uint8_t status[64]; + if (cardCMD6(0X00FFFFFF, status) && (2 & status[13]) && + cardCMD6(0X80FFFFF1, status) && (status[16] & 0XF) == 1) { + kHzSdClk = 50000; + } else { + kHzSdClk = 25000; + } + // disable GPIO + enableGPIO(false); + + // Set the SDHC SCK frequency. + setSdclk(kHzSdClk); + + // enable GPIO + enableGPIO(true); + m_initDone = true; + return true; +} +//----------------------------------------------------------------------------- +uint32_t SdioCard::cardSize() { + return sdCardCapacity(&m_csd); +} +//----------------------------------------------------------------------------- +bool SdioCard::erase(uint32_t firstBlock, uint32_t lastBlock) { + // check for single block erase + if (!m_csd.v1.erase_blk_en) { + // erase size mask + uint8_t m = (m_csd.v1.sector_size_high << 1) | m_csd.v1.sector_size_low; + if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) { + // error card can't erase specified area + return sdError(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); + } + } + if (!m_highCapacity) { + firstBlock <<= 9; + lastBlock <<= 9; + } + if (!cardCommand(CMD32_XFERTYP, firstBlock)) { + return sdError(SD_CARD_ERROR_CMD32); + } + if (!cardCommand(CMD33_XFERTYP, lastBlock)) { + return sdError(SD_CARD_ERROR_CMD33); + } + if (!cardCommand(CMD38_XFERTYP, 0)) { + return sdError(SD_CARD_ERROR_CMD38); + } + if (waitTimeout(isBusyCMD13)) { + return sdError(SD_CARD_ERROR_ERASE_TIMEOUT); + } + return true; +} +//----------------------------------------------------------------------------- +uint8_t SdioCard::errorCode() { + return m_errorCode; +} +//----------------------------------------------------------------------------- +uint32_t SdioCard::errorData() { + return m_irqstat; +} +//----------------------------------------------------------------------------- +uint32_t SdioCard::errorLine() { + return m_errorLine; +} +//----------------------------------------------------------------------------- +bool SdioCard::isBusy() { + return m_busyFcn ? m_busyFcn() : m_initDone && isBusyCMD13(); +} +//----------------------------------------------------------------------------- +uint32_t SdioCard::kHzSdClk() { + return m_sdClkKhz; +} +//----------------------------------------------------------------------------- +bool SdioCard::readBlock(uint32_t lba, uint8_t* buf) { + uint8_t aligned[512]; + + uint8_t* ptr = (uint32_t)buf & 3 ? aligned : buf; + + if (!rdWrBlocks(CMD17_DMA_XFERTYP, lba, ptr, 1)) { + return sdError(SD_CARD_ERROR_CMD18); + } + if (ptr != buf) { + memcpy(buf, aligned, 512); + } + return true; +} +//----------------------------------------------------------------------------- +bool SdioCard::readBlocks(uint32_t lba, uint8_t* buf, size_t n) { + if ((uint32_t)buf & 3) { + for (size_t i = 0; i < n; i++, lba++, buf += 512) { + if (!readBlock(lba, buf)) { + return false; // readBlock will set errorCode. + } + } + return true; + } + if (!rdWrBlocks(CMD18_DMA_XFERTYP, lba, buf, n)) { + return sdError(SD_CARD_ERROR_CMD18); + } + return true; +} +//----------------------------------------------------------------------------- +bool SdioCard::readCID(void* cid) { + memcpy(cid, &m_cid, 16); + return true; +} +//----------------------------------------------------------------------------- +bool SdioCard::readCSD(void* csd) { + memcpy(csd, &m_csd, 16); + return true; +} +//----------------------------------------------------------------------------- +bool SdioCard::readData(uint8_t *dst) { + DBG_IRQSTAT(); + uint32_t *p32 = reinterpret_cast(dst); + + if (!(SDHC_PRSSTAT & SDHC_PRSSTAT_RTA)) { + SDHC_PROCTL &= ~SDHC_PROCTL_SABGREQ; + if ((SDHC_BLKATTR & 0XFFFF0000) == 0X10000) { + // Don't stop at block gap if last block. Allows auto CMD12. + SDHC_PROCTL |= SDHC_PROCTL_CREQ; + } else { + noInterrupts(); + SDHC_PROCTL |= SDHC_PROCTL_CREQ; + SDHC_PROCTL |= SDHC_PROCTL_SABGREQ; + interrupts(); + } + } + if (waitTimeout(isBusyFifoRead)) { + return sdError(SD_CARD_ERROR_READ_FIFO); + } + for (uint32_t iw = 0 ; iw < 512/(4*FIFO_WML); iw++) { + while (0 == (SDHC_PRSSTAT & SDHC_PRSSTAT_BREN)) { + } + for (uint32_t i = 0; i < FIFO_WML; i++) { + p32[i] = SDHC_DATPORT; + } + p32 += FIFO_WML; + } + if (waitTimeout(isBusyTransferComplete)) { + return sdError(SD_CARD_ERROR_READ_TIMEOUT); + } + m_irqstat = SDHC_IRQSTAT; + SDHC_IRQSTAT = m_irqstat; + return (m_irqstat & SDHC_IRQSTAT_TC) && !(m_irqstat & SDHC_IRQSTAT_ERROR); +} +//----------------------------------------------------------------------------- +bool SdioCard::readOCR(uint32_t* ocr) { + *ocr = m_ocr; + return true; +} +//----------------------------------------------------------------------------- +bool SdioCard::readStart(uint32_t lba) { + // K66/K65 Errata - SDHC: Does not support Infinite Block Transfer Mode. + return sdError(SD_CARD_ERROR_FUNCTION_NOT_SUPPORTED); +} +//----------------------------------------------------------------------------- +// SDHC will do Auto CMD12 after count blocks. +bool SdioCard::readStart(uint32_t lba, uint32_t count) { + DBG_IRQSTAT(); + if (count > 0XFFFF) { + return sdError(SD_CARD_ERROR_READ_START); + } + if (yieldTimeout(isBusyCMD13)) { + return sdError(SD_CARD_ERROR_CMD13); + } + if (count > 1) { + SDHC_PROCTL |= SDHC_PROCTL_SABGREQ; + } + SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(count) | SDHC_BLKATTR_BLKSIZE(512); + if (!cardCommand(CMD18_PGM_XFERTYP, m_highCapacity ? lba : 512*lba)) { + return sdError(SD_CARD_ERROR_CMD18); + } + return true; +} +//----------------------------------------------------------------------------- +bool SdioCard::readStop() { + return transferStop(); +} +//----------------------------------------------------------------------------- +bool SdioCard::syncBlocks() { + return true; +} +//----------------------------------------------------------------------------- +uint8_t SdioCard::type() { + return m_version2 ? m_highCapacity ? + SD_CARD_TYPE_SDHC : SD_CARD_TYPE_SD2 : SD_CARD_TYPE_SD1; +} +//----------------------------------------------------------------------------- +bool SdioCard::writeBlock(uint32_t lba, const uint8_t* buf) { + uint8_t *ptr; + uint8_t aligned[512]; + if (3 & (uint32_t)buf) { + ptr = aligned; + memcpy(aligned, buf, 512); + } else { + ptr = const_cast(buf); + } + if (!rdWrBlocks(CMD24_DMA_XFERTYP, lba, ptr, 1)) { + return sdError(SD_CARD_ERROR_CMD24); + } + return true; +} +//----------------------------------------------------------------------------- +bool SdioCard::writeBlocks(uint32_t lba, const uint8_t* buf, size_t n) { + uint8_t* ptr = const_cast(buf); + if (3 & (uint32_t)ptr) { + for (size_t i = 0; i < n; i++, lba++, ptr += 512) { + if (!writeBlock(lba, ptr)) { + return false; // writeBlock will set errorCode. + } + } + return true; + } + if (!rdWrBlocks(CMD25_DMA_XFERTYP, lba, ptr, n)) { + return sdError(SD_CARD_ERROR_CMD25); + } + return true; +} +//----------------------------------------------------------------------------- +bool SdioCard::writeData(const uint8_t* src) { + DBG_IRQSTAT(); + const uint32_t* p32 = reinterpret_cast(src); + + if (!(SDHC_PRSSTAT & SDHC_PRSSTAT_WTA)) { + SDHC_PROCTL &= ~SDHC_PROCTL_SABGREQ; + // Don't stop at block gap if last block. Allows auto CMD12. + if ((SDHC_BLKATTR & 0XFFFF0000) == 0X10000) { + SDHC_PROCTL |= SDHC_PROCTL_CREQ; + } else { + SDHC_PROCTL |= SDHC_PROCTL_CREQ; + SDHC_PROCTL |= SDHC_PROCTL_SABGREQ; + } + } + if (waitTimeout(isBusyFifoWrite)) { + return sdError(SD_CARD_ERROR_WRITE_FIFO); + } + for (uint32_t iw = 0 ; iw < 512/(4*FIFO_WML); iw++) { + while (0 == (SDHC_PRSSTAT & SDHC_PRSSTAT_BWEN)) { + } + for (uint32_t i = 0; i < FIFO_WML; i++) { + SDHC_DATPORT = p32[i]; + } + p32 += FIFO_WML; + } + if (waitTimeout(isBusyTransferComplete)) { + return sdError(SD_CARD_ERROR_WRITE_TIMEOUT); + } + m_irqstat = SDHC_IRQSTAT; + SDHC_IRQSTAT = m_irqstat; + return (m_irqstat & SDHC_IRQSTAT_TC) && !(m_irqstat & SDHC_IRQSTAT_ERROR); +} +//----------------------------------------------------------------------------- +bool SdioCard::writeStart(uint32_t lba) { + // K66/K65 Errata - SDHC: Does not support Infinite Block Transfer Mode. + return sdError(SD_CARD_ERROR_FUNCTION_NOT_SUPPORTED); +} +//----------------------------------------------------------------------------- +// SDHC will do Auto CMD12 after count blocks. +bool SdioCard::writeStart(uint32_t lba, uint32_t count) { + if (count > 0XFFFF) { + return sdError(SD_CARD_ERROR_WRITE_START); + } + DBG_IRQSTAT(); + if (yieldTimeout(isBusyCMD13)) { + return sdError(SD_CARD_ERROR_CMD13); + } + if (count > 1) { + SDHC_PROCTL |= SDHC_PROCTL_SABGREQ; + } + SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(count) | SDHC_BLKATTR_BLKSIZE(512); + + if (!cardCommand(CMD25_PGM_XFERTYP, m_highCapacity ? lba : 512*lba)) { + return sdError(SD_CARD_ERROR_CMD25); + } + return true; +} +//----------------------------------------------------------------------------- +bool SdioCard::writeStop() { + return transferStop(); +} +#endif // defined(__MK64FX512__) || defined(__MK66FX1M0__) diff --git a/libraries/SdFat/src/SdFat.h b/libraries/SdFat/src/SdFat.h new file mode 100644 index 0000000..bf06952 --- /dev/null +++ b/libraries/SdFat/src/SdFat.h @@ -0,0 +1,504 @@ +/* Arduino SdFat Library + * Copyright (C) 2016 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 SdFat_h +#define SdFat_h +/** + * \file + * \brief SdFat class + */ +#include "SysCall.h" +#include "BlockDriver.h" +#include "FatLib/FatLib.h" +#include "SdCard/SdioCard.h" +//------------------------------------------------------------------------------ +/** SdFat version */ +#define SD_FAT_VERSION "1.0.3" +//============================================================================== +/** + * \class SdBaseFile + * \brief Class for backward compatibility. + */ +class SdBaseFile : public FatFile { + public: + SdBaseFile() {} + /** Create a file object and open it in the current working directory. + * + * \param[in] path A path for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a + * bitwise-inclusive OR of open flags. see + * FatFile::open(FatFile*, const char*, uint8_t). + */ + SdBaseFile(const char* path, uint8_t oflag) : FatFile(path, oflag) {} +}; +//----------------------------------------------------------------------------- +#if ENABLE_ARDUINO_FEATURES +/** + * \class SdFile + * \brief Class for backward compatibility. + */ +class SdFile : public PrintFile { + public: + SdFile() {} + /** Create a file object and open it in the current working directory. + * + * \param[in] path A path for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a + * bitwise-inclusive OR of open flags. see + * FatFile::open(FatFile*, const char*, uint8_t). + */ + SdFile(const char* path, uint8_t oflag) : PrintFile(path, oflag) {} +}; +#endif // #if ENABLE_ARDUINO_FEATURES +//----------------------------------------------------------------------------- +/** + * \class SdFileSystem + * \brief Virtual base class for %SdFat library. + */ +template +class SdFileSystem : public FatFileSystem { + public: + /** Initialize file system. + * \return true for success else false. + */ + bool begin() { + return FatFileSystem::begin(&m_card); + } + /** \return Pointer to SD card object */ + SdDriverClass *card() { + m_card.syncBlocks(); + return &m_card; + } + /** %Print any SD error code to Serial and halt. */ + void errorHalt() { + errorHalt(&Serial); + } + /** %Print any SD error code and halt. + * + * \param[in] pr Print destination. + */ + void errorHalt(Print* pr) { + errorPrint(pr); + SysCall::halt(); + } + /** %Print msg, any SD error code and halt. + * + * \param[in] msg Message to print. + */ + void errorHalt(char const* msg) { + errorHalt(&Serial, msg); + } + /** %Print msg, any SD error code, and halt. + * + * \param[in] pr Print destination. + * \param[in] msg Message to print. + */ + void errorHalt(Print* pr, char const* msg) { + errorPrint(pr, msg); + SysCall::halt(); + } + /** %Print any SD error code to Serial */ + void errorPrint() { + errorPrint(&Serial); + } + /** %Print any SD error code. + * \param[in] pr Print device. + */ + void errorPrint(Print* pr) { + if (!cardErrorCode()) { + return; + } + pr->print(F("SD errorCode: 0X")); + pr->print(cardErrorCode(), HEX); + pr->print(F(",0X")); + pr->println(cardErrorData(), HEX); + } + /** %Print msg, any SD error code. + * + * \param[in] msg Message to print. + */ + void errorPrint(const char* msg) { + errorPrint(&Serial, msg); + } + /** %Print msg, any SD error code. + * + * \param[in] pr Print destination. + * \param[in] msg Message to print. + */ + void errorPrint(Print* pr, char const* msg) { + pr->print(F("error: ")); + pr->println(msg); + errorPrint(pr); + } + /** %Print any SD error code and halt. */ + void initErrorHalt() { + initErrorHalt(&Serial); + } + /** %Print error details and halt after begin fails. + * + * \param[in] pr Print destination. + */ + void initErrorHalt(Print* pr) { + initErrorPrint(pr); + SysCall::halt(); + } + /**Print message, error details, and halt after begin() fails. + * + * \param[in] msg Message to print. + */ + void initErrorHalt(char const *msg) { + initErrorHalt(&Serial, msg); + } + /**Print message, error details, and halt after begin() fails. + * \param[in] pr Print device. + * \param[in] msg Message to print. + */ + void initErrorHalt(Print* pr, char const *msg) { + pr->println(msg); + initErrorHalt(pr); + } + + /** Print error details after begin() fails. */ + void initErrorPrint() { + initErrorPrint(&Serial); + } + /** Print error details after begin() fails. + * + * \param[in] pr Print destination. + */ + void initErrorPrint(Print* pr) { + if (cardErrorCode()) { + pr->println(F("Can't access SD card. Do not reformat.")); + if (cardErrorCode() == SD_CARD_ERROR_CMD0) { + pr->println(F("No card, wrong chip select pin, or SPI problem?")); + } + errorPrint(pr); + } else if (vol()->fatType() == 0) { + pr->println(F("Invalid format, reformat SD.")); + } else if (!vwd()->isOpen()) { + pr->println(F("Can't open root directory.")); + } else { + pr->println(F("No error found.")); + } + } + /**Print message and error details and halt after begin() fails. + * + * \param[in] msg Message to print. + */ + void initErrorPrint(char const *msg) { + initErrorPrint(&Serial, msg); + } + /**Print message and error details and halt after begin() fails. + * + * \param[in] pr Print destination. + * \param[in] msg Message to print. + */ + void initErrorPrint(Print* pr, char const *msg) { + pr->println(msg); + initErrorPrint(pr); + } +#if defined(ARDUINO) || defined(DOXYGEN) + /** %Print msg, any SD error code, and halt. + * + * \param[in] msg Message to print. + */ + void errorHalt(const __FlashStringHelper* msg) { + errorHalt(&Serial, msg); + } + /** %Print msg, any SD error code, and halt. + * + * \param[in] pr Print destination. + * \param[in] msg Message to print. + */ + void errorHalt(Print* pr, const __FlashStringHelper* msg) { + errorPrint(pr, msg); + SysCall::halt(); + } + + /** %Print msg, any SD error code. + * + * \param[in] msg Message to print. + */ + void errorPrint(const __FlashStringHelper* msg) { + errorPrint(&Serial, msg); + } + /** %Print msg, any SD error code. + * + * \param[in] pr Print destination. + * \param[in] msg Message to print. + */ + void errorPrint(Print* pr, const __FlashStringHelper* msg) { + pr->print(F("error: ")); + pr->println(msg); + errorPrint(pr); + } + /**Print message, error details, and halt after begin() fails. + * + * \param[in] msg Message to print. + */ + void initErrorHalt(const __FlashStringHelper* msg) { + initErrorHalt(&Serial, msg); + } + /**Print message, error details, and halt after begin() fails. + * \param[in] pr Print device for message. + * \param[in] msg Message to print. + */ + void initErrorHalt(Print* pr, const __FlashStringHelper* msg) { + pr->println(msg); + initErrorHalt(pr); + } + /**Print message and error details and halt after begin() fails. + * + * \param[in] msg Message to print. + */ + void initErrorPrint(const __FlashStringHelper* msg) { + initErrorPrint(&Serial, msg); + } + /**Print message and error details and halt after begin() fails. + * + * \param[in] pr Print destination. + * \param[in] msg Message to print. + */ + void initErrorPrint(Print* pr, const __FlashStringHelper* msg) { + pr->println(msg); + initErrorPrint(pr); + } +#endif // defined(ARDUINO) || defined(DOXYGEN) + /** \return The card error code */ + uint8_t cardErrorCode() { + return m_card.errorCode(); + } + /** \return the card error data */ + uint32_t cardErrorData() { + return m_card.errorData(); + } + + protected: + SdDriverClass m_card; +}; +//============================================================================== +/** + * \class SdFat + * \brief Main file system class for %SdFat library. + */ +class SdFat : public SdFileSystem { + public: +#if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) + SdFat() { + m_spi.setPort(0); + } + /** Constructor with SPI port selection. + * \param[in] spiPort SPI port number. + */ + explicit SdFat(uint8_t spiPort) { + m_spi.setPort(spiPort); + } +#endif // IMPLEMENT_SPI_PORT_SELECTION + /** Initialize SD card and file system. + * + * \param[in] csPin SD card chip select pin. + * \param[in] spiSettings SPI speed, mode, and bit order. + * \return true for success else false. + */ + bool begin(uint8_t csPin = SS, SPISettings spiSettings = SPI_FULL_SPEED) { + return m_card.begin(&m_spi, csPin, spiSettings) && + SdFileSystem::begin(); + } + /** Initialize SD card for diagnostic use only. + * + * \param[in] csPin SD card chip select pin. + * \param[in] settings SPI speed, mode, and bit order. + * \return true for success else false. + */ + bool cardBegin(uint8_t csPin = SS, SPISettings settings = SPI_FULL_SPEED) { + return m_card.begin(&m_spi, csPin, settings); + } + /** Initialize file system for diagnostic use only. + * \return true for success else false. + */ + bool fsBegin() { + return FatFileSystem::begin(card()); + } + + private: + SdFatSpiDriver m_spi; +}; +//============================================================================== +#if ENABLE_SDIO_CLASS || defined(DOXYGEN) +/** + * \class SdFatSdio + * \brief SdFat class using SDIO. + */ +class SdFatSdio : public SdFileSystem { + public: + /** Initialize SD card and file system. + * \return true for success else false. + */ + bool begin() { + return m_card.begin() && SdFileSystem::begin(); + } + /** Initialize SD card for diagnostic use only. + * + * \return true for success else false. + */ + bool cardBegin() { + return m_card.begin(); + } + /** Initialize file system for diagnostic use only. + * \return true for success else false. + */ + bool fsBegin() { + return SdFileSystem::begin(); + } +}; +#if ENABLE_SDIOEX_CLASS || defined(DOXYGEN) +//----------------------------------------------------------------------------- +/** + * \class SdFatSdioEX + * \brief SdFat class using SDIO. + */ +class SdFatSdioEX : public SdFileSystem { + public: + /** Initialize SD card and file system. + * \return true for success else false. + */ + bool begin() { + return m_card.begin() && SdFileSystem::begin(); + } + /** \return Pointer to SD card object */ + SdioCardEX* card() { + return &m_card; + } + /** Initialize SD card for diagnostic use only. + * + * \return true for success else false. + */ + bool cardBegin() { + return m_card.begin(); + } + /** Initialize file system for diagnostic use only. + * \return true for success else false. + */ + bool fsBegin() { + return SdFileSystem::begin(); + } +}; +#endif // ENABLE_SDIOEX_CLASS || defined(DOXYGEN) +#endif // ENABLE_SDIO_CLASS || defined(DOXYGEN) +//============================================================================= +#if ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN) +/** + * \class SdFatSoftSpi + * \brief SdFat class using software SPI. + */ +template +class SdFatSoftSpi : public SdFileSystem { + public: + /** Initialize SD card and file system. + * + * \param[in] csPin SD card chip select pin. + * \param[in] spiSettings ignored for software SPI.. + * \return true for success else false. + */ + bool begin(uint8_t csPin = SS, SPISettings spiSettings = SPI_FULL_SPEED) { + return m_card.begin(&m_spi, csPin, spiSettings) && + SdFileSystem::begin(); + } + private: + SdSpiSoftDriver m_spi; +}; +#endif // #if ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN) +//============================================================================== +#if ENABLE_EXTENDED_TRANSFER_CLASS || defined(DOXYGEN) +/** + * \class SdFatEX + * \brief SdFat class with extended SD I/O. + */ +class SdFatEX : public SdFileSystem { + public: +#if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) + SdFatEX() { + m_spi.setPort(0); + } + /** Constructor with SPI port selection. + * \param[in] spiPort SPI port number. + */ + explicit SdFatEX(uint8_t spiPort) { + m_spi.setPort(spiPort); + } +#endif // IMPLEMENT_SPI_PORT_SELECTION + /** Initialize SD card and file system. + * + * \param[in] csPin SD card chip select pin. + * \param[in] spiSettings SPI speed, mode, and bit order. + * \return true for success else false. + */ + bool begin(uint8_t csPin = SS, SPISettings spiSettings = SPI_FULL_SPEED) { + return m_card.begin(&m_spi, csPin, spiSettings) && + SdFileSystem::begin(); + } + + private: + SdFatSpiDriver m_spi; +}; +//============================================================================== +#if ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN) +/** + * \class SdFatSoftSpiEX + * \brief SdFat class using software SPI and extended SD I/O. + */ +template +class SdFatSoftSpiEX : public SdFileSystem { + public: + /** Initialize SD card and file system. + * + * \param[in] csPin SD card chip select pin. + * \param[in] spiSettings ignored for software SPI. + * \return true for success else false. + */ + bool begin(uint8_t csPin = SS, SPISettings spiSettings = SPI_FULL_SPEED) { + return m_card.begin(&m_spi, csPin, spiSettings) && + SdFileSystem::begin(); + } + private: + SdSpiSoftDriver m_spi; +}; +#endif // #if ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN) +#endif // ENABLE_EXTENDED_TRANSFER_CLASS || defined(DOXYGEN) +//============================================================================= +/** + * \class Sd2Card + * \brief Raw access to SD and SDHC card using default SPI library. + */ +class Sd2Card : public SdSpiCard { + public: + /** Initialize the SD card. + * \param[in] csPin SD chip select pin. + * \param[in] settings SPI speed, mode, and bit order. + * \return true for success else false. + */ + bool begin(uint8_t csPin = SS, SPISettings settings = SD_SCK_MHZ(50)) { + return SdSpiCard::begin(&m_spi, csPin, settings); + } + private: + SdFatSpiDriver m_spi; +}; +#endif // SdFat_h diff --git a/libraries/SdFat/src/SdFatConfig.h b/libraries/SdFat/src/SdFatConfig.h new file mode 100644 index 0000000..01561a2 --- /dev/null +++ b/libraries/SdFat/src/SdFatConfig.h @@ -0,0 +1,192 @@ +/* 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 + * . + */ +/** + * \file + * \brief configuration definitions + */ +#ifndef SdFatConfig_h +#define SdFatConfig_h +#include +#ifdef __AVR__ +#include +#endif // __AVR__ +//------------------------------------------------------------------------------ +/** + * Set USE_LONG_FILE_NAMES nonzero to use long file names (LFN). + * Long File Name are limited to a maximum length of 255 characters. + * + * This implementation allows 7-bit characters in the range + * 0X20 to 0X7E except the following characters are not allowed: + * + * < (less than) + * > (greater than) + * : (colon) + * " (double quote) + * / (forward slash) + * \ (backslash) + * | (vertical bar or pipe) + * ? (question mark) + * * (asterisk) + * + */ +#define USE_LONG_FILE_NAMES 1 +//------------------------------------------------------------------------------ +/** + * If the symbol ENABLE_EXTENDED_TRANSFER_CLASS is nonzero, the class SdFatEX + * will be defined. If the symbol ENABLE_SOFTWARE_SPI_CLASS is also nonzero, + * the class SdFatSoftSpiEX will be defined. + * + * These classes used extended multi-block SD I/O for better performance. + * the SPI bus may not be shared with other devices in this mode. + */ +#define ENABLE_EXTENDED_TRANSFER_CLASS 0 +//----------------------------------------------------------------------------- +/** + * If the symbol USE_STANDARD_SPI_LIBRARY is nonzero, the classes SdFat and + * SdFatEX use the standard Arduino SPI.h library. If USE_STANDARD_SPI_LIBRARY + * is zero, an optimized custom SPI driver is used if it exists. + */ +#define USE_STANDARD_SPI_LIBRARY 0 +//----------------------------------------------------------------------------- +/** + * If the symbol ENABLE_SOFTWARE_SPI_CLASS is nonzero, the class SdFatSoftSpi + * will be defined. If ENABLE_EXTENDED_TRANSFER_CLASS is also nonzero, + * the class SdFatSoftSpiEX will be defined. + */ +#define ENABLE_SOFTWARE_SPI_CLASS 0 +//------------------------------------------------------------------------------ +/** + * Set MAINTAIN_FREE_CLUSTER_COUNT nonzero to keep the count of free clusters + * updated. This will increase the speed of the freeClusterCount() call + * after the first call. Extra flash will be required. + */ +#define MAINTAIN_FREE_CLUSTER_COUNT 0 +//------------------------------------------------------------------------------ +/** + * To enable SD card CRC checking set USE_SD_CRC nonzero. + * + * Set USE_SD_CRC to 1 to use a smaller CRC-CCITT function. This function + * is slower for AVR but may be fast for ARM and other processors. + * + * Set USE_SD_CRC to 2 to used a larger table driven CRC-CCITT function. This + * function is faster for AVR but may be slower for ARM and other processors. + */ +#define USE_SD_CRC 0 +//------------------------------------------------------------------------------ +/** + * Handle Watchdog Timer for WiFi modules. + * + * Yield will be called before accessing the SPI bus if it has been more + * than WDT_YIELD_TIME_MICROS microseconds since the last yield call by SdFat. + */ +#if defined(PLATFORM_ID) || defined(ESP8266) +// If Particle device or ESP8266 call yield. +#define WDT_YIELD_TIME_MICROS 100000 +#else +#define WDT_YIELD_TIME_MICROS 0 +#endif +//------------------------------------------------------------------------------ +/** + * Set FAT12_SUPPORT nonzero to enable use if FAT12 volumes. + * FAT12 has not been well tested and requires additional flash. + */ +#define FAT12_SUPPORT 0 +//------------------------------------------------------------------------------ +/** + * Set DESTRUCTOR_CLOSES_FILE nonzero to close a file in its destructor. + * + * Causes use of lots of heap in ARM. + */ +#define DESTRUCTOR_CLOSES_FILE 0 +//------------------------------------------------------------------------------ +/** + * Call flush for endl if ENDL_CALLS_FLUSH is nonzero + * + * The standard for iostreams is to call flush. This is very costly for + * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. + * + * SdFat has a single 512 byte buffer for SD I/O so it must write the current + * data block to the SD, read the directory block from the SD, update the + * directory entry, write the directory block to the SD and read the data + * block back into the buffer. + * + * The SD flash memory controller is not designed for this many rewrites + * so performance may be reduced by more than a factor of 100. + * + * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force + * all data to be written to the SD. + */ +#define ENDL_CALLS_FLUSH 0 +//------------------------------------------------------------------------------ +/** + * Set USE_SEPARATE_FAT_CACHE nonzero to use a second 512 byte cache + * for FAT table entries. This improves performance for large writes + * that are not a multiple of 512 bytes. + */ +#ifdef __arm__ +#define USE_SEPARATE_FAT_CACHE 1 +#else // __arm__ +#define USE_SEPARATE_FAT_CACHE 0 +#endif // __arm__ +//------------------------------------------------------------------------------ +/** + * Set USE_MULTI_BLOCK_IO nonzero to use multi-block SD read/write. + * + * Don't use mult-block read/write on small AVR boards. + */ +#if defined(RAMEND) && RAMEND < 3000 +#define USE_MULTI_BLOCK_IO 0 +#else // RAMEND +#define USE_MULTI_BLOCK_IO 1 +#endif // RAMEND +//----------------------------------------------------------------------------- +/** Enable SDIO driver if available. */ +#if defined(__MK64FX512__) || defined(__MK66FX1M0__) +#define ENABLE_SDIO_CLASS 1 +#define ENABLE_SDIOEX_CLASS 1 +#else // ENABLE_SDIO_CLASS +#define ENABLE_SDIO_CLASS 0 +#endif // ENABLE_SDIO_CLASS +//------------------------------------------------------------------------------ +/** + * Determine the default SPI configuration. + */ +#if defined(__STM32F1__) +// has multiple SPI ports +#define SD_HAS_CUSTOM_SPI 2 +#elif defined(__AVR__)\ + || defined(__SAM3X8E__) || defined(__SAM3X8H__)\ + || (defined(__arm__) && defined(CORE_TEENSY))\ + || defined(ESP8266) +#define SD_HAS_CUSTOM_SPI 1 +#else // SD_HAS_CUSTOM_SPI +// Use standard SPI library. +#define SD_HAS_CUSTOM_SPI 0 +#endif // SD_HAS_CUSTOM_SPI +//------------------------------------------------------------------------------ +/** + * Check if API to select HW SPI port is needed. + */ +#if (USE_STANDARD_SPI_LIBRARY || SD_HAS_CUSTOM_SPI < 2) +#define IMPLEMENT_SPI_PORT_SELECTION 0 +#else // USE_STANDARD_SPI_LIBRARY +#define IMPLEMENT_SPI_PORT_SELECTION 1 +#endif // USE_STANDARD_SPI_LIBRARY +#endif // SdFatConfig_h diff --git a/libraries/SdFat/src/SpiDriver/DigitalPin.h b/libraries/SdFat/src/SpiDriver/DigitalPin.h new file mode 100644 index 0000000..4ab09c9 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/DigitalPin.h @@ -0,0 +1,381 @@ +/* Arduino DigitalIO Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the Arduino DigitalIO 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 DigitalIO Library. If not, see + * . + */ +/** + * @file + * @brief Fast Digital Pin functions + * + * @defgroup digitalPin Fast Pin I/O + * @details Fast Digital I/O functions and template class. + * @{ + */ +#ifndef DigitalPin_h +#define DigitalPin_h +#if defined(__AVR__) || defined(DOXYGEN) +#include +/** GpioPinMap type */ +struct GpioPinMap_t { + volatile uint8_t* pin; /**< address of PIN for this pin */ + volatile uint8_t* ddr; /**< address of DDR for this pin */ + volatile uint8_t* port; /**< address of PORT for this pin */ + uint8_t mask; /**< bit mask for this pin */ +}; + +/** Initializer macro. */ +#define GPIO_PIN(reg, bit) {&PIN##reg, &DDR##reg, &PORT##reg, 1 << bit} + +// Include pin map for current board. +#include "boards/GpioPinMap.h" +//------------------------------------------------------------------------------ +/** generate bad pin number error */ +void badPinNumber(void) + __attribute__((error("Pin number is too large or not a constant"))); +//------------------------------------------------------------------------------ +/** Check for valid pin number + * @param[in] pin Number of pin to be checked. + */ +static inline __attribute__((always_inline)) +void badPinCheck(uint8_t pin) { + if (!__builtin_constant_p(pin) || pin >= NUM_DIGITAL_PINS) { + badPinNumber(); + } +} +//------------------------------------------------------------------------------ +/** DDR register address + * @param[in] pin Arduino pin number + * @return register address + */ +static inline __attribute__((always_inline)) +volatile uint8_t* ddrReg(uint8_t pin) { + badPinCheck(pin); + return GpioPinMap[pin].ddr; +} +//------------------------------------------------------------------------------ +/** Bit mask for pin + * @param[in] pin Arduino pin number + * @return mask + */ +static inline __attribute__((always_inline)) +uint8_t pinMask(uint8_t pin) { + badPinCheck(pin); + return GpioPinMap[pin].mask; +} +//------------------------------------------------------------------------------ +/** PIN register address + * @param[in] pin Arduino pin number + * @return register address + */ +static inline __attribute__((always_inline)) +volatile uint8_t* pinReg(uint8_t pin) { + badPinCheck(pin); + return GpioPinMap[pin].pin; +} +//------------------------------------------------------------------------------ +/** PORT register address + * @param[in] pin Arduino pin number + * @return register address + */ +static inline __attribute__((always_inline)) +volatile uint8_t* portReg(uint8_t pin) { + badPinCheck(pin); + return GpioPinMap[pin].port; +} +//------------------------------------------------------------------------------ +/** Fast write helper. + * @param[in] address I/O register address + * @param[in] mask bit mask for pin + * @param[in] level value for bit + */ +static inline __attribute__((always_inline)) +void fastBitWriteSafe(volatile uint8_t* address, uint8_t mask, bool level) { + uint8_t s; + if (address > reinterpret_cast(0X3F)) { + s = SREG; + cli(); + } + if (level) { + *address |= mask; + } else { + *address &= ~mask; + } + if (address > reinterpret_cast(0X3F)) { + SREG = s; + } +} +//------------------------------------------------------------------------------ +/** Read pin value. + * @param[in] pin Arduino pin number + * @return value read + */ +static inline __attribute__((always_inline)) +bool fastDigitalRead(uint8_t pin) { + return *pinReg(pin) & pinMask(pin); +} +//------------------------------------------------------------------------------ +/** Toggle a pin. + * @param[in] pin Arduino pin number + * + * If the pin is in output mode toggle the pin level. + * If the pin is in input mode toggle the state of the 20K pullup. + */ +static inline __attribute__((always_inline)) +void fastDigitalToggle(uint8_t pin) { + if (pinReg(pin) > reinterpret_cast(0X3F)) { + // must write bit to high address port + *pinReg(pin) = pinMask(pin); + } else { + // will compile to sbi and PIN register will not be read. + *pinReg(pin) |= pinMask(pin); + } +} +//------------------------------------------------------------------------------ +/** Set pin value. + * @param[in] pin Arduino pin number + * @param[in] level value to write + */ +static inline __attribute__((always_inline)) +void fastDigitalWrite(uint8_t pin, bool level) { + fastBitWriteSafe(portReg(pin), pinMask(pin), level); +} +//------------------------------------------------------------------------------ +/** Write the DDR register. + * @param[in] pin Arduino pin number + * @param[in] level value to write + */ +static inline __attribute__((always_inline)) +void fastDdrWrite(uint8_t pin, bool level) { + fastBitWriteSafe(ddrReg(pin), pinMask(pin), level); +} +//------------------------------------------------------------------------------ +/** Set pin mode. + * @param[in] pin Arduino pin number + * @param[in] mode INPUT, OUTPUT, or INPUT_PULLUP. + * + * The internal pullup resistors will be enabled if mode is INPUT_PULLUP + * and disabled if the mode is INPUT. + */ +static inline __attribute__((always_inline)) +void fastPinMode(uint8_t pin, uint8_t mode) { + fastDdrWrite(pin, mode == OUTPUT); + if (mode != OUTPUT) { + fastDigitalWrite(pin, mode == INPUT_PULLUP); + } +} +#else // defined(__AVR__) +#if defined(CORE_TEENSY) +//------------------------------------------------------------------------------ +/** read pin value + * @param[in] pin Arduino pin number + * @return value read + */ +static inline __attribute__((always_inline)) +bool fastDigitalRead(uint8_t pin) { + return *portInputRegister(pin); +} +//------------------------------------------------------------------------------ +/** Set pin value + * @param[in] pin Arduino pin number + * @param[in] level value to write + */ +static inline __attribute__((always_inline)) +void fastDigitalWrite(uint8_t pin, bool value) { + if (value) { + *portSetRegister(pin) = 1; + } else { + *portClearRegister(pin) = 1; + } +} +#elif defined(__SAM3X8E__) || defined(__SAM3X8H__) +//------------------------------------------------------------------------------ +/** read pin value + * @param[in] pin Arduino pin number + * @return value read + */ +static inline __attribute__((always_inline)) +bool fastDigitalRead(uint8_t pin) { + return g_APinDescription[pin].pPort->PIO_PDSR & g_APinDescription[pin].ulPin; +} +//------------------------------------------------------------------------------ +/** Set pin value + * @param[in] pin Arduino pin number + * @param[in] level value to write + */ +static inline __attribute__((always_inline)) +void fastDigitalWrite(uint8_t pin, bool value) { + if (value) { + g_APinDescription[pin].pPort->PIO_SODR = g_APinDescription[pin].ulPin; + } else { + g_APinDescription[pin].pPort->PIO_CODR = g_APinDescription[pin].ulPin; + } +} +#elif defined(ESP8266) +//------------------------------------------------------------------------------ +/** Set pin value + * @param[in] pin Arduino pin number + * @param[in] val value to write + */ +static inline __attribute__((always_inline)) +void fastDigitalWrite(uint8_t pin, uint8_t val) { + if (pin < 16) { + if (val) { + GPOS = (1 << pin); + } else { + GPOC = (1 << pin); + } + } else if (pin == 16) { + if (val) { + GP16O |= 1; + } else { + GP16O &= ~1; + } + } +} +//------------------------------------------------------------------------------ +/** Read pin value + * @param[in] pin Arduino pin number + * @return value read + */ +static inline __attribute__((always_inline)) +bool fastDigitalRead(uint8_t pin) { + if (pin < 16) { + return GPIP(pin); + } else if (pin == 16) { + return GP16I & 0x01; + } + return 0; +} +#else // CORE_TEENSY +//------------------------------------------------------------------------------ +inline void fastDigitalWrite(uint8_t pin, bool value) { + digitalWrite(pin, value); +} +//------------------------------------------------------------------------------ +inline bool fastDigitalRead(uint8_t pin) { + return digitalRead(pin); +} +#endif // CORE_TEENSY +//------------------------------------------------------------------------------ +inline void fastDigitalToggle(uint8_t pin) { + fastDigitalWrite(pin, !fastDigitalRead(pin)); +} +//------------------------------------------------------------------------------ +inline void fastPinMode(pin, mode) { + pinMode(pin, mode); +} +#endif // __AVR__ +//------------------------------------------------------------------------------ +/** set pin configuration + * @param[in] pin Arduino pin number + * @param[in] mode mode INPUT or OUTPUT. + * @param[in] level If mode is output, set level high/low. + * If mode is input, enable or disable the pin's 20K pullup. + */ +#define fastPinConfig(pin, mode, level)\ + {fastPinMode(pin, mode); fastDigitalWrite(pin, level);} +//============================================================================== +/** + * @class DigitalPin + * @brief Fast digital port I/O + */ +template +class DigitalPin { + public: + //---------------------------------------------------------------------------- + /** Constructor */ + DigitalPin() {} + //---------------------------------------------------------------------------- + /** Asignment operator. + * @param[in] value If true set the pin's level high else set the + * pin's level low. + * + * @return This DigitalPin instance. + */ + inline DigitalPin & operator = (bool value) __attribute__((always_inline)) { + write(value); + return *this; + } + //---------------------------------------------------------------------------- + /** Parenthesis operator. + * @return Pin's level + */ + inline operator bool () const __attribute__((always_inline)) { + return read(); + } + //---------------------------------------------------------------------------- + /** Set pin configuration. + * @param[in] mode: INPUT or OUTPUT. + * @param[in] level If mode is OUTPUT, set level high/low. + * If mode is INPUT, enable or disable the pin's 20K pullup. + */ + inline __attribute__((always_inline)) + void config(uint8_t mode, bool level) { + fastPinConfig(PinNumber, mode, level); + } + //---------------------------------------------------------------------------- + /** + * Set pin level high if output mode or enable 20K pullup if input mode. + */ + inline __attribute__((always_inline)) + void high() {write(true);} + //---------------------------------------------------------------------------- + /** + * Set pin level low if output mode or disable 20K pullup if input mode. + */ + inline __attribute__((always_inline)) + void low() {write(false);} + //---------------------------------------------------------------------------- + /** + * Set pin mode. + * @param[in] mode: INPUT, OUTPUT, or INPUT_PULLUP. + * + * The internal pullup resistors will be enabled if mode is INPUT_PULLUP + * and disabled if the mode is INPUT. + */ + inline __attribute__((always_inline)) + void mode(uint8_t mode) { + fastPinMode(PinNumber, mode); + } + //---------------------------------------------------------------------------- + /** @return Pin's level. */ + inline __attribute__((always_inline)) + bool read() const { + return fastDigitalRead(PinNumber); + } + //---------------------------------------------------------------------------- + /** Toggle a pin. + * + * If the pin is in output mode toggle the pin's level. + * If the pin is in input mode toggle the state of the 20K pullup. + */ + inline __attribute__((always_inline)) + void toggle() { + fastDigitalToggle(PinNumber); + } + //---------------------------------------------------------------------------- + /** Write the pin's level. + * @param[in] value If true set the pin's level high else set the + * pin's level low. + */ + inline __attribute__((always_inline)) + void write(bool value) { + fastDigitalWrite(PinNumber, value); + } +}; +#endif // DigitalPin_h +/** @} */ diff --git a/libraries/SdFat/src/SpiDriver/SdSpiBaseDriver.h b/libraries/SdFat/src/SpiDriver/SdSpiBaseDriver.h new file mode 100644 index 0000000..cf35671 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/SdSpiBaseDriver.h @@ -0,0 +1,74 @@ +/* Arduino SdCard Library + * Copyright (C) 2016 by William Greiman + * + * This file is part of the Arduino SdSpiCard 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 SdSpiCard Library. If not, see + * . + */ +#ifndef SdSpiBaseDriver_h +#define SdSpiBaseDriver_h +/** + * \class SdSpiBaseDriver + * \brief SPI base driver. + */ +class SdSpiBaseDriver { + public: + /** Set SPI options for access to SD/SDHC cards. + * + */ + virtual void activate() = 0; + /** Initialize the SPI bus. + * + * \param[in] chipSelectPin SD card chip select pin. + */ + virtual void begin(uint8_t chipSelectPin) = 0; + /** + * End SPI transaction. + */ + virtual void deactivate() = 0; + /** Receive a byte. + * + * \return The byte. + */ + virtual uint8_t receive() = 0; + /** Receive multiple bytes. + * + * \param[out] buf Buffer to receive the data. + * \param[in] n Number of bytes to receive. + * + * \return Zero for no error or nonzero error code. + */ + virtual uint8_t receive(uint8_t* buf, size_t n) = 0; + /** Send a byte. + * + * \param[in] data Byte to send + */ + virtual void send(uint8_t data) = 0; + /** Send multiple bytes. + * + * \param[in] buf Buffer for data to be sent. + * \param[in] n Number of bytes to send. + */ + virtual void send(const uint8_t* buf, size_t n) = 0; + /** Set CS low. */ + virtual void select() = 0; + /** Save SPI settings. + * \param[in] spiSettings SPI speed, mode, and bit order. + */ + virtual void setSpiSettings(SPISettings spiSettings) = 0; + /** Set CS high. */ + virtual void unselect() = 0; +}; +#endif // SdSpiBaseDriver_h diff --git a/libraries/SdFat/src/SpiDriver/SdSpiDriver.h b/libraries/SdFat/src/SpiDriver/SdSpiDriver.h new file mode 100644 index 0000000..2f2ccb7 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/SdSpiDriver.h @@ -0,0 +1,364 @@ +/* SdFat Library + * Copyright (C) 2016 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +/** + * \file + * \brief SpiDriver classes + */ +#ifndef SdSpiDriver_h +#define SdSpiDriver_h +#include +#include "SPI.h" +#include "SdSpiBaseDriver.h" +#include "SdFatConfig.h" +//----------------------------------------------------------------------------- +/** SDCARD_SPI is defined if board has built-in SD card socket */ +#ifndef SDCARD_SPI +#define SDCARD_SPI SPI +#endif // SDCARD_SPI +//----------------------------------------------------------------------------- +/** + * \class SdSpiLibDriver + * \brief SdSpiLibDriver - use standard SPI library. + */ +#if ENABLE_SOFTWARE_SPI_CLASS +class SdSpiLibDriver : public SdSpiBaseDriver { +#else // ENABLE_SOFTWARE_SPI_CLASS +class SdSpiLibDriver { +#endif // ENABLE_SOFTWARE_SPI_CLASS + public: + /** Activate SPI hardware. */ + void activate() { + SDCARD_SPI.beginTransaction(m_spiSettings); + } + /** Deactivate SPI hardware. */ + void deactivate() { + SDCARD_SPI.endTransaction(); + } + /** Initialize the SPI bus. + * + * \param[in] csPin SD card chip select pin. + */ + void begin(uint8_t csPin) { + m_csPin = csPin; + digitalWrite(csPin, HIGH); + pinMode(csPin, OUTPUT); + SDCARD_SPI.begin(); + } + /** Receive a byte. + * + * \return The byte. + */ + uint8_t receive() { + return SDCARD_SPI.transfer( 0XFF); + } + /** Receive multiple bytes. + * + * \param[out] buf Buffer to receive the data. + * \param[in] n Number of bytes to receive. + * + * \return Zero for no error or nonzero error code. + */ + uint8_t receive(uint8_t* buf, size_t n) { + for (size_t i = 0; i < n; i++) { + buf[i] = SDCARD_SPI.transfer(0XFF); + } + return 0; + } + /** Send a byte. + * + * \param[in] data Byte to send + */ + void send(uint8_t data) { + SDCARD_SPI.transfer(data); + } + /** Send multiple bytes. + * + * \param[in] buf Buffer for data to be sent. + * \param[in] n Number of bytes to send. + */ + void send(const uint8_t* buf, size_t n) { + for (size_t i = 0; i < n; i++) { + SDCARD_SPI.transfer(buf[i]); + } + } + /** Set CS low. */ + void select() { + digitalWrite(m_csPin, LOW); + } + /** Save SPISettings. + * + * \param[in] spiSettings SPI speed, mode, and byte order. + */ + void setSpiSettings(SPISettings spiSettings) { + m_spiSettings = spiSettings; + } + /** Set CS high. */ + void unselect() { + digitalWrite(m_csPin, HIGH); + } + + private: + SPISettings m_spiSettings; + uint8_t m_csPin; +}; +//----------------------------------------------------------------------------- +/** + * \class SdSpiAltDriver + * \brief Optimized SPI class for access to SD and SDHC flash memory cards. + */ +#if ENABLE_SOFTWARE_SPI_CLASS +class SdSpiAltDriver : public SdSpiBaseDriver { +#else // ENABLE_SOFTWARE_SPI_CLASS +class SdSpiAltDriver { +#endif // ENABLE_SOFTWARE_SPI_CLASS + public: + /** Activate SPI hardware. */ + void activate(); + /** Deactivate SPI hardware. */ + void deactivate(); + /** Initialize the SPI bus. + * + * \param[in] csPin SD card chip select pin. + */ + void begin(uint8_t csPin); + /** Receive a byte. + * + * \return The byte. + */ + uint8_t receive(); + /** Receive multiple bytes. + * + * \param[out] buf Buffer to receive the data. + * \param[in] n Number of bytes to receive. + * + * \return Zero for no error or nonzero error code. + */ + uint8_t receive(uint8_t* buf, size_t n); + /** Send a byte. + * + * \param[in] data Byte to send + */ + void send(uint8_t data); + /** Send multiple bytes. + * + * \param[in] buf Buffer for data to be sent. + * \param[in] n Number of bytes to send. + */ + void send(const uint8_t* buf, size_t n); + /** Set CS low. */ + void select() { + digitalWrite(m_csPin, LOW); + } + /** Save SPISettings. + * + * \param[in] spiSettings SPI speed, mode, and byte order. + */ + void setSpiSettings(SPISettings spiSettings) { + m_spiSettings = spiSettings; + } + /** Set CS high. */ + void unselect() { + digitalWrite(m_csPin, HIGH); + } +#if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) + /** Set SPI port number. + * \param[in] portNumber Hardware SPI port number. + */ + void setPort(uint8_t portNumber); + + private: + uint8_t m_spiPort; +#else // IMPLEMENT_SPI_PORT_SELECTION + private: +#endif // IMPLEMENT_SPI_PORT_SELECTION + SPISettings m_spiSettings; + uint8_t m_csPin; +}; +//------------------------------------------------------------------------------ +#if ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN) +#ifdef ARDUINO +#include "SoftSPI.h" +#elif defined(PLATFORM_ID) // Only defined if a Particle device +#include "SoftSPIParticle.h" +#endif // ARDUINO +/** + * \class SdSpiSoftDriver + * \brief Software SPI class for access to SD and SDHC flash memory cards. + */ +template +class SdSpiSoftDriver : public SdSpiBaseDriver { + public: + /** Dummy activate SPI hardware for software SPI */ + void activate() {} + /** Dummy deactivate SPI hardware for software SPI */ + void deactivate() {} + /** Initialize the SPI bus. + * + * \param[in] csPin SD card chip select pin. + */ + void begin(uint8_t csPin) { + m_csPin = csPin; + pinMode(m_csPin, OUTPUT); + digitalWrite(m_csPin, HIGH); + m_spi.begin(); + } + /** Receive a byte. + * + * \return The byte. + */ + uint8_t receive() { + return m_spi.receive(); + } + /** Receive multiple bytes. + * + * \param[out] buf Buffer to receive the data. + * \param[in] n Number of bytes to receive. + * + * \return Zero for no error or nonzero error code. + */ + uint8_t receive(uint8_t* buf, size_t n) { + for (size_t i = 0; i < n; i++) { + buf[i] = receive(); + } + return 0; + } + /** Send a byte. + * + * \param[in] data Byte to send + */ + void send(uint8_t data) { + m_spi.send(data); + } + /** Send multiple bytes. + * + * \param[in] buf Buffer for data to be sent. + * \param[in] n Number of bytes to send. + */ + void send(const uint8_t* buf , size_t n) { + for (size_t i = 0; i < n; i++) { + send(buf[i]); + } + } + /** Set CS low. */ + void select() { + digitalWrite(m_csPin, LOW); + } + /** Save SPISettings. + * + * \param[in] spiSettings SPI speed, mode, and byte order. + */ + void setSpiSettings(SPISettings spiSettings) { + (void)spiSettings; + } + /** Set CS high. */ + void unselect() { + digitalWrite(m_csPin, HIGH); + } + + private: + uint8_t m_csPin; + SoftSPI m_spi; +}; +#endif // ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN) +//----------------------------------------------------------------------------- +// Choose SPI driver for SdFat and SdFatEX classes. +#if USE_STANDARD_SPI_LIBRARY || !SD_HAS_CUSTOM_SPI +/** SdFat uses Arduino library SPI. */ +typedef SdSpiLibDriver SdFatSpiDriver; +#else // USE_STANDARD_SPI_LIBRARY || !SD_HAS_CUSTOM_SPI +/** SdFat uses custom fast SPI. */ +typedef SdSpiAltDriver SdFatSpiDriver; +#endif // USE_STANDARD_SPI_LIBRARY || !SD_HAS_CUSTOM_SPI + +/** typedef for for SdSpiCard class. */ +#if ENABLE_SOFTWARE_SPI_CLASS +// Need virtual driver. +typedef SdSpiBaseDriver SdSpiDriver; +#else // ENABLE_SOFTWARE_SPI_CLASS +// Don't need virtual driver. +typedef SdFatSpiDriver SdSpiDriver; +#endif // ENABLE_SOFTWARE_SPI_CLASS +//============================================================================= +// Use of in-line for AVR to save flash. +#ifdef __AVR__ +//------------------------------------------------------------------------------ +inline void SdSpiAltDriver::begin(uint8_t csPin) { + m_csPin = csPin; + pinMode(m_csPin, OUTPUT); + digitalWrite(m_csPin, HIGH); + SPI.begin(); +} +//------------------------------------------------------------------------------ +inline void SdSpiAltDriver::activate() { + SPI.beginTransaction(m_spiSettings); +} +//------------------------------------------------------------------------------ +inline void SdSpiAltDriver::deactivate() { + SPI.endTransaction(); +} +//------------------------------------------------------------------------------ +inline uint8_t SdSpiAltDriver::receive() { + SPDR = 0XFF; + while (!(SPSR & (1 << SPIF))) {} + return SPDR; +} +//------------------------------------------------------------------------------ +inline uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { + if (n-- == 0) { + return 0; + } + SPDR = 0XFF; + for (size_t i = 0; i < n; i++) { + while (!(SPSR & (1 << SPIF))) {} + uint8_t b = SPDR; + SPDR = 0XFF; + buf[i] = b; + } + while (!(SPSR & (1 << SPIF))) {} + buf[n] = SPDR; + return 0; +} +//------------------------------------------------------------------------------ +inline void SdSpiAltDriver::send(uint8_t data) { + SPDR = data; + while (!(SPSR & (1 << SPIF))) {} +} +//------------------------------------------------------------------------------ +inline void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { + if (n == 0) { + return; + } + SPDR = buf[0]; + if (n > 1) { + uint8_t b = buf[1]; + size_t i = 2; + while (1) { + while (!(SPSR & (1 << SPIF))) {} + SPDR = b; + if (i == n) { + break; + } + b = buf[i++]; + } + } + while (!(SPSR & (1 << SPIF))) {} +} +#endif // __AVR__ +#endif // SdSpiDriver_h diff --git a/libraries/SdFat/src/SpiDriver/SdSpiESP8266.cpp b/libraries/SdFat/src/SpiDriver/SdSpiESP8266.cpp new file mode 100644 index 0000000..52e5b70 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/SdSpiESP8266.cpp @@ -0,0 +1,90 @@ +/* Arduino SdSpiAltDriver Library + * Copyright (C) 2016 by William Greiman + * + * STM32F1 code for Maple and Maple Mini support, 2015 by Victor Perez + * + * This file is part of the Arduino SdSpiAltDriver 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 SdSpiAltDriver Library. If not, see + * . + */ +#if defined(ESP8266) +#include "SdSpiDriver.h" +//------------------------------------------------------------------------------ +/** Initialize the SPI bus. + * + * \param[in] chipSelectPin SD card chip select pin. + */ +void SdSpiAltDriver::begin(uint8_t csPin) { + m_csPin = csPin; + pinMode(m_csPin, OUTPUT); + digitalWrite(m_csPin, HIGH); + SPI.begin(); +} +//------------------------------------------------------------------------------ +/** Set SPI options for access to SD/SDHC cards. + * + */ +void SdSpiAltDriver::activate() { + SPI.beginTransaction(m_spiSettings); +} +//------------------------------------------------------------------------------ +void SdSpiAltDriver::deactivate() { + // Note: endTransaction is an empty function on ESP8266. + SPI.endTransaction(); +} +//------------------------------------------------------------------------------ +/** Receive a byte. + * + * \return The byte. + */ +uint8_t SdSpiAltDriver::receive() { + return SPI.transfer(0XFF); +} +//------------------------------------------------------------------------------ +/** Receive multiple bytes. + * + * \param[out] buf Buffer to receive the data. + * \param[in] n Number of bytes to receive. + * + * \return Zero for no error or nonzero error code. + */ +uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { + // Works without 32-bit alignment of buf. + SPI.transferBytes(0, buf, n); + return 0; +} +//------------------------------------------------------------------------------ +/** Send a byte. + * + * \param[in] b Byte to send + */ +void SdSpiAltDriver::send(uint8_t b) { + SPI.transfer(b); +} +//------------------------------------------------------------------------------ +/** Send multiple bytes. + * + * \param[in] buf Buffer for data to be sent. + * \param[in] n Number of bytes to send. + */ +void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { + // Adjust to 32-bit alignment. + while ((reinterpret_cast(buf) & 0X3) && n) { + SPI.transfer(*buf++); + n--; + } + SPI.transferBytes(const_cast(buf), 0, n); +} +#endif // defined(ESP8266) diff --git a/libraries/SdFat/src/SpiDriver/SdSpiSAM3X.cpp b/libraries/SdFat/src/SpiDriver/SdSpiSAM3X.cpp new file mode 100644 index 0000000..942d72a --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/SdSpiSAM3X.cpp @@ -0,0 +1,213 @@ +/* Arduino SdSpiAltDriver Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the Arduino SdSpiAltDriver 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 SdSpiAltDriver Library. If not, see + * . + */ +#include "SdSpiDriver.h" +#if defined(__SAM3X8E__) || defined(__SAM3X8H__) +/** Use SAM3X DMAC if nonzero */ +#define USE_SAM3X_DMAC 1 +/** Use extra Bus Matrix arbitration fix if nonzero */ +#define USE_SAM3X_BUS_MATRIX_FIX 0 +/** Time in ms for DMA receive timeout */ +#define SAM3X_DMA_TIMEOUT 100 +/** chip select register number */ +#define SPI_CHIP_SEL 3 +/** DMAC receive channel */ +#define SPI_DMAC_RX_CH 1 +/** DMAC transmit channel */ +#define SPI_DMAC_TX_CH 0 +/** DMAC Channel HW Interface Number for SPI TX. */ +#define SPI_TX_IDX 1 +/** DMAC Channel HW Interface Number for SPI RX. */ +#define SPI_RX_IDX 2 +//------------------------------------------------------------------------------ +/** Disable DMA Controller. */ +static void dmac_disable() { + DMAC->DMAC_EN &= (~DMAC_EN_ENABLE); +} +/** Enable DMA Controller. */ +static void dmac_enable() { + DMAC->DMAC_EN = DMAC_EN_ENABLE; +} +/** Disable DMA Channel. */ +static void dmac_channel_disable(uint32_t ul_num) { + DMAC->DMAC_CHDR = DMAC_CHDR_DIS0 << ul_num; +} +/** Enable DMA Channel. */ +static void dmac_channel_enable(uint32_t ul_num) { + DMAC->DMAC_CHER = DMAC_CHER_ENA0 << ul_num; +} +/** Poll for transfer complete. */ +static bool dmac_channel_transfer_done(uint32_t ul_num) { + return (DMAC->DMAC_CHSR & (DMAC_CHSR_ENA0 << ul_num)) ? false : true; +} +//------------------------------------------------------------------------------ +void SdSpiAltDriver::begin(uint8_t csPin) { + m_csPin = csPin; + pinMode(m_csPin, OUTPUT); + digitalWrite(m_csPin, HIGH); +SPI.begin(); +#if USE_SAM3X_DMAC + pmc_enable_periph_clk(ID_DMAC); + dmac_disable(); + DMAC->DMAC_GCFG = DMAC_GCFG_ARB_CFG_FIXED; + dmac_enable(); +#if USE_SAM3X_BUS_MATRIX_FIX + MATRIX->MATRIX_WPMR = 0x4d415400; + MATRIX->MATRIX_MCFG[1] = 1; + MATRIX->MATRIX_MCFG[2] = 1; + MATRIX->MATRIX_SCFG[0] = 0x01000010; + MATRIX->MATRIX_SCFG[1] = 0x01000010; + MATRIX->MATRIX_SCFG[7] = 0x01000010; +#endif // USE_SAM3X_BUS_MATRIX_FIX +#endif // USE_SAM3X_DMAC +} +//------------------------------------------------------------------------------ +// start RX DMA +static void spiDmaRX(uint8_t* dst, uint16_t count) { + dmac_channel_disable(SPI_DMAC_RX_CH); + DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_SADDR = (uint32_t)&SPI0->SPI_RDR; + DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_DADDR = (uint32_t)dst; + DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_DSCR = 0; + DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CTRLA = count | + DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; + DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR | + DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_PER2MEM_DMA_FC | + DMAC_CTRLB_SRC_INCR_FIXED | DMAC_CTRLB_DST_INCR_INCREMENTING; + DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CFG = DMAC_CFG_SRC_PER(SPI_RX_IDX) | + DMAC_CFG_SRC_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG; + dmac_channel_enable(SPI_DMAC_RX_CH); +} +//------------------------------------------------------------------------------ +// start TX DMA +static void spiDmaTX(const uint8_t* src, uint16_t count) { + static uint8_t ff = 0XFF; + uint32_t src_incr = DMAC_CTRLB_SRC_INCR_INCREMENTING; + if (!src) { + src = &ff; + src_incr = DMAC_CTRLB_SRC_INCR_FIXED; + } + dmac_channel_disable(SPI_DMAC_TX_CH); + DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_SADDR = (uint32_t)src; + DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_DADDR = (uint32_t)&SPI0->SPI_TDR; + DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_DSCR = 0; + DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CTRLA = count | + DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; + + DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR | + DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2PER_DMA_FC | + src_incr | DMAC_CTRLB_DST_INCR_FIXED; + + DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CFG = DMAC_CFG_DST_PER(SPI_TX_IDX) | + DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG; + + dmac_channel_enable(SPI_DMAC_TX_CH); +} +//------------------------------------------------------------------------------ +// initialize SPI controller +void SdSpiAltDriver::activate() { + SPI.beginTransaction(m_spiSettings); + + Spi* pSpi = SPI0; + // Save the divisor + uint32_t scbr = pSpi->SPI_CSR[SPI_CHIP_SEL] & 0XFF00; + // Disable SPI + pSpi->SPI_CR = SPI_CR_SPIDIS; + // reset SPI + pSpi->SPI_CR = SPI_CR_SWRST; + // no mode fault detection, set master mode + pSpi->SPI_MR = SPI_PCS(SPI_CHIP_SEL) | SPI_MR_MODFDIS | SPI_MR_MSTR; + // mode 0, 8-bit, + pSpi->SPI_CSR[SPI_CHIP_SEL] = scbr | SPI_CSR_CSAAT | SPI_CSR_NCPHA; + // enable SPI + pSpi->SPI_CR |= SPI_CR_SPIEN; +} +//------------------------------------------------------------------------------ +void SdSpiAltDriver::deactivate() { + SPI.endTransaction(); +} +//------------------------------------------------------------------------------ +static inline uint8_t spiTransfer(uint8_t b) { + Spi* pSpi = SPI0; + + pSpi->SPI_TDR = b; + while ((pSpi->SPI_SR & SPI_SR_RDRF) == 0) {} + b = pSpi->SPI_RDR; + return b; +} +//------------------------------------------------------------------------------ +/** SPI receive a byte */ +uint8_t SdSpiAltDriver::receive() { + return spiTransfer(0XFF); +} +//------------------------------------------------------------------------------ +/** SPI receive multiple bytes */ +uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { + Spi* pSpi = SPI0; + int rtn = 0; +#if USE_SAM3X_DMAC + // clear overrun error + uint32_t s = pSpi->SPI_SR; + + spiDmaRX(buf, n); + spiDmaTX(0, n); + + uint32_t m = millis(); + while (!dmac_channel_transfer_done(SPI_DMAC_RX_CH)) { + if ((millis() - m) > SAM3X_DMA_TIMEOUT) { + dmac_channel_disable(SPI_DMAC_RX_CH); + dmac_channel_disable(SPI_DMAC_TX_CH); + rtn = 2; + break; + } + } + if (pSpi->SPI_SR & SPI_SR_OVRES) { + rtn |= 1; + } +#else // USE_SAM3X_DMAC + for (size_t i = 0; i < n; i++) { + pSpi->SPI_TDR = 0XFF; + while ((pSpi->SPI_SR & SPI_SR_RDRF) == 0) {} + buf[i] = pSpi->SPI_RDR; + } +#endif // USE_SAM3X_DMAC + return rtn; +} +//------------------------------------------------------------------------------ +/** SPI send a byte */ +void SdSpiAltDriver::send(uint8_t b) { + spiTransfer(b); +} +//------------------------------------------------------------------------------ +void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { + Spi* pSpi = SPI0; +#if USE_SAM3X_DMAC + spiDmaTX(buf, n); + while (!dmac_channel_transfer_done(SPI_DMAC_TX_CH)) {} +#else // #if USE_SAM3X_DMAC + while ((pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0) {} + for (size_t i = 0; i < n; i++) { + pSpi->SPI_TDR = buf[i]; + while ((pSpi->SPI_SR & SPI_SR_TDRE) == 0) {} + } +#endif // #if USE_SAM3X_DMAC + while ((pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0) {} + // leave RDR empty + uint8_t b = pSpi->SPI_RDR; +} +#endif // defined(__SAM3X8E__) || defined(__SAM3X8H__) diff --git a/libraries/SdFat/src/SpiDriver/SdSpiSTM32F1.cpp b/libraries/SdFat/src/SpiDriver/SdSpiSTM32F1.cpp new file mode 100644 index 0000000..f9727a9 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/SdSpiSTM32F1.cpp @@ -0,0 +1,121 @@ +/* Arduino SdSpiAltDriver Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the Arduino SdSpiAltDriver 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 SdSpiAltDriver Library. If not, see + * . + */ +#if defined(__STM32F1__) +#include "SdSpiDriver.h" +#define USE_STM32F1_DMAC 1 +//------------------------------------------------------------------------------ +static SPIClass m_SPI1(1); +#if BOARD_NR_SPI > 1 +static SPIClass m_SPI2(2); +#endif // BOARD_NR_SPI > 1 +#if BOARD_NR_SPI > 2 +static SPIClass m_SPI3(3); +#endif // BOARD_NR_SPI > 2 +// +static SPIClass* pSpi[] = +#if BOARD_NR_SPI == 1 + {&m_SPI1}; +#elif BOARD_NR_SPI == 2 + {&m_SPI1, &m_SPI2}; +#elif BOARD_NR_SPI == 3 + {&m_SPI1, &m_SPI2, &m_SPI3}; +#else // BOARD_NR_SPI +#error "BOARD_NR_SPI too large" +#endif // BOARD_NR_SPI +//------------------------------------------------------------------------------ +/** Set SPI options for access to SD/SDHC cards. + * + * \param[in] divisor SCK clock divider relative to the APB1 or APB2 clock. + */ +void SdSpiAltDriver::activate() { + pSpi[m_spiPort]->beginTransaction(m_spiSettings); +} +//------------------------------------------------------------------------------ +/** Initialize the SPI bus. + * + * \param[in] chipSelectPin SD card chip select pin. + */ +void SdSpiAltDriver::begin(uint8_t csPin) { + m_csPin = csPin; + pinMode(m_csPin, OUTPUT); + digitalWrite(m_csPin, HIGH); + pSpi[m_spiPort]->begin(); +} +//------------------------------------------------------------------------------ +/** + * End SPI transaction. + */ +void SdSpiAltDriver::deactivate() { + pSpi[m_spiPort]->endTransaction(); +} +//------------------------------------------------------------------------------ +/** Receive a byte. + * + * \return The byte. + */ +uint8_t SdSpiAltDriver::receive() { + return pSpi[m_spiPort]->transfer(0XFF); +} +//------------------------------------------------------------------------------ +/** Receive multiple bytes. + * + * \param[out] buf Buffer to receive the data. + * \param[in] n Number of bytes to receive. + * + * \return Zero for no error or nonzero error code. + */ +uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { + int rtn = 0; +#if USE_STM32F1_DMAC + rtn = pSpi[m_spiPort]->dmaTransfer(0, const_cast(buf), n); +#else // USE_STM32F1_DMAC + // pSpi[m_spiPort]->read(buf, n); fails ?? use byte transfer + for (size_t i = 0; i < n; i++) { + buf[i] = pSpi[m_spiPort]->transfer(0XFF); + } +#endif // USE_STM32F1_DMAC + return rtn; +} +//------------------------------------------------------------------------------ +/** Send a byte. + * + * \param[in] b Byte to send + */ +void SdSpiAltDriver::send(uint8_t b) { + pSpi[m_spiPort]->transfer(b); +} +//------------------------------------------------------------------------------ +/** Send multiple bytes. + * + * \param[in] buf Buffer for data to be sent. + * \param[in] n Number of bytes to send. + */ +void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { +#if USE_STM32F1_DMAC + pSpi[m_spiPort]->dmaSend(const_cast(buf), n); +#else // #if USE_STM32F1_DMAC + pSpi[m_spiPort]->write(buf, n); +#endif // USE_STM32F1_DMAC +} +//----------------------------------------------------------------------------- +void SdSpiAltDriver::setPort(uint8_t portNumber) { + m_spiPort = portNumber < 1 || portNumber > BOARD_NR_SPI ? 0 : portNumber -1; +} +#endif // defined(__STM32F1__) diff --git a/libraries/SdFat/src/SpiDriver/SdSpiTeensy3.cpp b/libraries/SdFat/src/SpiDriver/SdSpiTeensy3.cpp new file mode 100644 index 0000000..a07feda --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/SdSpiTeensy3.cpp @@ -0,0 +1,228 @@ +/* Arduino SdSpiAltDriver Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the Arduino SdSpiAltDriver 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 SdSpiAltDriver Library. If not, see + * . + */ +#include "SdSpiDriver.h" +#if defined(__arm__) && defined(CORE_TEENSY) +// SPI definitions +#include "kinetis.h" + +//------------------------------------------------------------------------------ +void SdSpiAltDriver::activate() { + SPI.beginTransaction(m_spiSettings); +} +//------------------------------------------------------------------------------ +void SdSpiAltDriver::begin(uint8_t chipSelectPin) { + m_csPin = chipSelectPin; + pinMode(m_csPin, OUTPUT); + digitalWrite(m_csPin, HIGH); + SPI.begin(); +} +//------------------------------------------------------------------------------ +void SdSpiAltDriver::deactivate() { + SPI.endTransaction(); +} +//============================================================================== +#ifdef KINETISK + +// use 16-bit frame if SPI_USE_8BIT_FRAME is zero +#define SPI_USE_8BIT_FRAME 0 +// Limit initial fifo to three entries to avoid fifo overrun +#define SPI_INITIAL_FIFO_DEPTH 3 +// define some symbols that are not in mk20dx128.h +#ifndef SPI_SR_RXCTR +#define SPI_SR_RXCTR 0XF0 +#endif // SPI_SR_RXCTR +#ifndef SPI_PUSHR_CONT +#define SPI_PUSHR_CONT 0X80000000 +#endif // SPI_PUSHR_CONT +#ifndef SPI_PUSHR_CTAS +#define SPI_PUSHR_CTAS(n) (((n) & 7) << 28) +#endif // SPI_PUSHR_CTAS +//------------------------------------------------------------------------------ +/** SPI receive a byte */ +uint8_t SdSpiAltDriver::receive() { + SPI0_MCR |= SPI_MCR_CLR_RXF; + SPI0_SR = SPI_SR_TCF; + SPI0_PUSHR = 0xFF; + while (!(SPI0_SR & SPI_SR_TCF)) {} + return SPI0_POPR; +} +//------------------------------------------------------------------------------ +/** SPI receive multiple bytes */ +uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { + // clear any data in RX FIFO + SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); +#if SPI_USE_8BIT_FRAME + // initial number of bytes to push into TX FIFO + int nf = n < SPI_INITIAL_FIFO_DEPTH ? n : SPI_INITIAL_FIFO_DEPTH; + for (int i = 0; i < nf; i++) { + SPI0_PUSHR = 0XFF; + } + // limit for pushing dummy data into TX FIFO + uint8_t* limit = buf + n - nf; + while (buf < limit) { + while (!(SPI0_SR & SPI_SR_RXCTR)) {} + SPI0_PUSHR = 0XFF; + *buf++ = SPI0_POPR; + } + // limit for rest of RX data + limit += nf; + while (buf < limit) { + while (!(SPI0_SR & SPI_SR_RXCTR)) {} + *buf++ = SPI0_POPR; + } +#else // SPI_USE_8BIT_FRAME + // use 16 bit frame to avoid TD delay between frames + // get one byte if n is odd + if (n & 1) { + *buf++ = receive(); + n--; + } + // initial number of words to push into TX FIFO + int nf = n/2 < SPI_INITIAL_FIFO_DEPTH ? n/2 : SPI_INITIAL_FIFO_DEPTH; + for (int i = 0; i < nf; i++) { + SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF; + } + uint8_t* limit = buf + n - 2*nf; + while (buf < limit) { + while (!(SPI0_SR & SPI_SR_RXCTR)) {} + SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF; + uint16_t w = SPI0_POPR; + *buf++ = w >> 8; + *buf++ = w & 0XFF; + } + // limit for rest of RX data + limit += 2*nf; + while (buf < limit) { + while (!(SPI0_SR & SPI_SR_RXCTR)) {} + uint16_t w = SPI0_POPR; + *buf++ = w >> 8; + *buf++ = w & 0XFF; + } +#endif // SPI_USE_8BIT_FRAME + return 0; +} +//------------------------------------------------------------------------------ +/** SPI send a byte */ +void SdSpiAltDriver::send(uint8_t b) { + SPI0_MCR |= SPI_MCR_CLR_RXF; + SPI0_SR = SPI_SR_TCF; + SPI0_PUSHR = b; + while (!(SPI0_SR & SPI_SR_TCF)) {} +} +//------------------------------------------------------------------------------ +/** SPI send multiple bytes */ +void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { + // clear any data in RX FIFO + SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); +#if SPI_USE_8BIT_FRAME + // initial number of bytes to push into TX FIFO + int nf = n < SPI_INITIAL_FIFO_DEPTH ? n : SPI_INITIAL_FIFO_DEPTH; + // limit for pushing data into TX fifo + const uint8_t* limit = buf + n; + for (int i = 0; i < nf; i++) { + SPI0_PUSHR = *buf++; + } + // write data to TX FIFO + while (buf < limit) { + while (!(SPI0_SR & SPI_SR_RXCTR)) {} + SPI0_PUSHR = *buf++; + SPI0_POPR; + } + // wait for data to be sent + while (nf) { + while (!(SPI0_SR & SPI_SR_RXCTR)) {} + SPI0_POPR; + nf--; + } +#else // SPI_USE_8BIT_FRAME + // use 16 bit frame to avoid TD delay between frames + // send one byte if n is odd + if (n & 1) { + send(*buf++); + n--; + } + // initial number of words to push into TX FIFO + int nf = n/2 < SPI_INITIAL_FIFO_DEPTH ? n/2 : SPI_INITIAL_FIFO_DEPTH; + // limit for pushing data into TX fifo + const uint8_t* limit = buf + n; + for (int i = 0; i < nf; i++) { + uint16_t w = (*buf++) << 8; + w |= *buf++; + SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w; + } + // write data to TX FIFO + while (buf < limit) { + uint16_t w = *buf++ << 8; + w |= *buf++; + while (!(SPI0_SR & SPI_SR_RXCTR)) {} + SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w; + SPI0_POPR; + } + // wait for data to be sent + while (nf) { + while (!(SPI0_SR & SPI_SR_RXCTR)) {} + SPI0_POPR; + nf--; + } +#endif // SPI_USE_8BIT_FRAME +} +#else // KINETISK +//============================================================================== +// Use standard SPI library if not KINETISK +//------------------------------------------------------------------------------ +/** Receive a byte. + * + * \return The byte. + */ +uint8_t SdSpiAltDriver::receive() { + return SPI.transfer(0XFF); +} +/** Receive multiple bytes. + * + * \param[out] buf Buffer to receive the data. + * \param[in] n Number of bytes to receive. + * + * \return Zero for no error or nonzero error code. + */ +uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { + for (size_t i = 0; i < n; i++) { + buf[i] = SPI.transfer(0XFF); + } + return 0; +} +/** Send a byte. + * + * \param[in] b Byte to send + */ +void SdSpiAltDriver::send(uint8_t b) { + SPI.transfer(b); +} +/** Send multiple bytes. + * + * \param[in] buf Buffer for data to be sent. + * \param[in] n Number of bytes to send. + */ +void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { + for (size_t i = 0; i < n; i++) { + SPI.transfer(buf[i]); + } +} +#endif // KINETISK +#endif // defined(__arm__) && defined(CORE_TEENSY) diff --git a/libraries/SdFat/src/SpiDriver/SoftSPI.h b/libraries/SdFat/src/SpiDriver/SoftSPI.h new file mode 100644 index 0000000..822932f --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/SoftSPI.h @@ -0,0 +1,162 @@ +/* Arduino DigitalIO Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the Arduino DigitalIO 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 DigitalIO Library. If not, see + * . + */ +/** + * @file + * @brief Software SPI. + * + * @defgroup softSPI Software SPI + * @details Software SPI Template Class. + * @{ + */ + +#ifndef SoftSPI_h +#define SoftSPI_h +#include "DigitalPin.h" +//------------------------------------------------------------------------------ +/** Nop for timing. */ +#define nop asm volatile ("nop\n\t") +//------------------------------------------------------------------------------ +/** Pin Mode for MISO is input.*/ +#define MISO_MODE INPUT +/** Pullups disabled for MISO are disabled. */ +#define MISO_LEVEL false +/** Pin Mode for MOSI is output.*/ +#define MOSI_MODE OUTPUT +/** Pin Mode for SCK is output. */ +#define SCK_MODE OUTPUT +//------------------------------------------------------------------------------ +/** + * @class SoftSPI + * @brief Fast software SPI. + */ +template +class SoftSPI { + public: + //---------------------------------------------------------------------------- + /** Initialize SoftSPI pins. */ + void begin() { + fastPinConfig(MisoPin, MISO_MODE, MISO_LEVEL); + fastPinConfig(MosiPin, MOSI_MODE, !MODE_CPHA(Mode)); + fastPinConfig(SckPin, SCK_MODE, MODE_CPOL(Mode)); + } + //---------------------------------------------------------------------------- + /** Soft SPI receive byte. + * @return Data byte received. + */ + inline __attribute__((always_inline)) + uint8_t receive() { + uint8_t data = 0; + receiveBit(7, &data); + receiveBit(6, &data); + receiveBit(5, &data); + receiveBit(4, &data); + receiveBit(3, &data); + receiveBit(2, &data); + receiveBit(1, &data); + receiveBit(0, &data); + return data; + } + //---------------------------------------------------------------------------- + /** Soft SPI send byte. + * @param[in] data Data byte to send. + */ + inline __attribute__((always_inline)) + void send(uint8_t data) { + sendBit(7, data); + sendBit(6, data); + sendBit(5, data); + sendBit(4, data); + sendBit(3, data); + sendBit(2, data); + sendBit(1, data); + sendBit(0, data); + } + //---------------------------------------------------------------------------- + /** Soft SPI transfer byte. + * @param[in] txData Data byte to send. + * @return Data byte received. + */ + inline __attribute__((always_inline)) + uint8_t transfer(uint8_t txData) { + uint8_t rxData = 0; + transferBit(7, &rxData, txData); + transferBit(6, &rxData, txData); + transferBit(5, &rxData, txData); + transferBit(4, &rxData, txData); + transferBit(3, &rxData, txData); + transferBit(2, &rxData, txData); + transferBit(1, &rxData, txData); + transferBit(0, &rxData, txData); + return rxData; + } + + private: + //---------------------------------------------------------------------------- + inline __attribute__((always_inline)) + bool MODE_CPHA(uint8_t mode) {return (mode & 1) != 0;} + inline __attribute__((always_inline)) + bool MODE_CPOL(uint8_t mode) {return (mode & 2) != 0;} + inline __attribute__((always_inline)) + void receiveBit(uint8_t bit, uint8_t* data) { + if (MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); + } + nop; + nop; + fastDigitalWrite(SckPin, + MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); + if (fastDigitalRead(MisoPin)) *data |= 1 << bit; + if (!MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, MODE_CPOL(Mode)); + } + } + //---------------------------------------------------------------------------- + inline __attribute__((always_inline)) + void sendBit(uint8_t bit, uint8_t data) { + if (MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); + } + fastDigitalWrite(MosiPin, data & (1 << bit)); + fastDigitalWrite(SckPin, + MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); + nop; + nop; + if (!MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, MODE_CPOL(Mode)); + } + } + //---------------------------------------------------------------------------- + inline __attribute__((always_inline)) + void transferBit(uint8_t bit, uint8_t* rxData, uint8_t txData) { + if (MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); + } + fastDigitalWrite(MosiPin, txData & (1 << bit)); + fastDigitalWrite(SckPin, + MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); + if (fastDigitalRead(MisoPin)) *rxData |= 1 << bit; + if (!MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, MODE_CPOL(Mode)); + } + } + //---------------------------------------------------------------------------- +}; +#endif // SoftSPI_h +/** @} */ diff --git a/libraries/SdFat/src/SpiDriver/boards/AvrDevelopersGpioPinMap.h b/libraries/SdFat/src/SpiDriver/boards/AvrDevelopersGpioPinMap.h new file mode 100644 index 0000000..67a8ec2 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/boards/AvrDevelopersGpioPinMap.h @@ -0,0 +1,37 @@ +#ifndef AvrDevelopersGpioPinMap_h +#define AvrDevelopersGpioPinMap_h +static const GpioPinMap_t GpioPinMap[] = { + GPIO_PIN(B, 0), // D0 + GPIO_PIN(B, 1), // D1 + GPIO_PIN(B, 2), // D2 + GPIO_PIN(B, 3), // D3 + GPIO_PIN(B, 4), // D4 + GPIO_PIN(B, 5), // D5 + GPIO_PIN(B, 6), // D6 + GPIO_PIN(B, 7), // D7 + GPIO_PIN(D, 0), // D8 + GPIO_PIN(D, 1), // D9 + GPIO_PIN(D, 2), // D10 + GPIO_PIN(D, 3), // D11 + GPIO_PIN(D, 4), // D12 + GPIO_PIN(D, 5), // D13 + GPIO_PIN(D, 6), // D14 + GPIO_PIN(D, 7), // D15 + GPIO_PIN(C, 0), // D16 + GPIO_PIN(C, 1), // D17 + GPIO_PIN(C, 2), // D18 + GPIO_PIN(C, 3), // D19 + GPIO_PIN(C, 4), // D20 + GPIO_PIN(C, 5), // D21 + GPIO_PIN(C, 6), // D22 + GPIO_PIN(C, 7), // D23 + GPIO_PIN(A, 7), // D24 + GPIO_PIN(A, 6), // D25 + GPIO_PIN(A, 5), // D26 + GPIO_PIN(A, 4), // D27 + GPIO_PIN(A, 3), // D28 + GPIO_PIN(A, 2), // D29 + GPIO_PIN(A, 1), // D30 + GPIO_PIN(A, 0) // D31 +}; +#endif // AvrDevelopersGpioPinMap_h \ No newline at end of file diff --git a/libraries/SdFat/src/SpiDriver/boards/BobuinoGpioPinMap.h b/libraries/SdFat/src/SpiDriver/boards/BobuinoGpioPinMap.h new file mode 100644 index 0000000..2d19944 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/boards/BobuinoGpioPinMap.h @@ -0,0 +1,37 @@ +#ifndef BobuinoGpioPinMap_h +#define BobuinoGpioPinMap_h +static const GpioPinMap_t GpioPinMap[] = { + GPIO_PIN(B, 0), // D0 + GPIO_PIN(B, 1), // D1 + GPIO_PIN(B, 2), // D2 + GPIO_PIN(B, 3), // D3 + GPIO_PIN(B, 4), // D4 + GPIO_PIN(B, 5), // D5 + GPIO_PIN(B, 6), // D6 + GPIO_PIN(B, 7), // D7 + GPIO_PIN(D, 0), // D8 + GPIO_PIN(D, 1), // D9 + GPIO_PIN(D, 2), // D10 + GPIO_PIN(D, 3), // D11 + GPIO_PIN(D, 4), // D12 + GPIO_PIN(D, 5), // D13 + GPIO_PIN(D, 6), // D14 + GPIO_PIN(D, 7), // D15 + GPIO_PIN(C, 0), // D16 + GPIO_PIN(C, 1), // D17 + GPIO_PIN(C, 2), // D18 + GPIO_PIN(C, 3), // D19 + GPIO_PIN(C, 4), // D20 + GPIO_PIN(C, 5), // D21 + GPIO_PIN(C, 6), // D22 + GPIO_PIN(C, 7), // D23 + GPIO_PIN(A, 0), // D24 + GPIO_PIN(A, 1), // D25 + GPIO_PIN(A, 2), // D26 + GPIO_PIN(A, 3), // D27 + GPIO_PIN(A, 4), // D28 + GPIO_PIN(A, 5), // D29 + GPIO_PIN(A, 6), // D30 + GPIO_PIN(A, 7) // D31 +}; +#endif // BobuinoGpioPinMap_h \ No newline at end of file diff --git a/libraries/SdFat/src/SpiDriver/boards/GpioPinMap.h b/libraries/SdFat/src/SpiDriver/boards/GpioPinMap.h new file mode 100644 index 0000000..326b762 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/boards/GpioPinMap.h @@ -0,0 +1,45 @@ +#ifndef GpioPinMap_h +#define GpioPinMap_h +#if defined(__AVR_ATmega168__)\ +||defined(__AVR_ATmega168P__)\ +||defined(__AVR_ATmega328P__) +// 168 and 328 Arduinos +#include "UnoGpioPinMap.h" +#elif defined(__AVR_ATmega1280__)\ +|| defined(__AVR_ATmega2560__) +// Mega ADK +#include "MegaGpioPinMap.h" +#elif defined(__AVR_ATmega32U4__) +#ifdef CORE_TEENSY +#include "Teensy2GpioPinMap.h" +#else // CORE_TEENSY +// Leonardo or Yun +#include "LeonardoGpioPinMap.h" +#endif // CORE_TEENSY +#elif defined(__AVR_AT90USB646__)\ +|| defined(__AVR_AT90USB1286__) +// Teensy++ 1.0 & 2.0 +#include "Teensy2ppGpioPinMap.h" +#elif defined(__AVR_ATmega1284P__)\ +|| defined(__AVR_ATmega1284__)\ +|| defined(__AVR_ATmega644P__)\ +|| defined(__AVR_ATmega644__)\ +|| defined(__AVR_ATmega64__)\ +|| defined(__AVR_ATmega32__)\ +|| defined(__AVR_ATmega324__)\ +|| defined(__AVR_ATmega16__) +#ifdef ARDUINO_1284P_AVR_DEVELOPERS +#include "AvrDevelopersGpioPinMap.h" +#elif defined(BOBUINO_PINOUT) || defined(ARDUINO_1284P_BOBUINO) +#include "BobuinoGpioPinMap.h" +#elif defined(ARDUINO_1284P_SLEEPINGBEAUTY) +#include "SleepingBeautyGpioPinMap.h" +#elif defined(STANDARD_PINOUT) || defined(ARDUINO_1284P_STANDARD) +#include "Standard1284GpioPinMap.h" +#else // ARDUINO_1284P_AVR_DEVELOPERS +#error Undefined variant 1284, 644, 324 +#endif // ARDUINO_1284P_AVR_DEVELOPERS +#else // 1284P, 1284, 644 +#error Unknown board type. +#endif // end all boards +#endif // GpioPinMap_h diff --git a/libraries/SdFat/src/SpiDriver/boards/LeonardoGpioPinMap.h b/libraries/SdFat/src/SpiDriver/boards/LeonardoGpioPinMap.h new file mode 100644 index 0000000..73544e6 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/boards/LeonardoGpioPinMap.h @@ -0,0 +1,35 @@ +#ifndef LeonardoGpioPinMap_h +#define LeonardoGpioPinMap_h +static const GpioPinMap_t GpioPinMap[] = { + GPIO_PIN(D, 2), // D0 + GPIO_PIN(D, 3), // D1 + GPIO_PIN(D, 1), // D2 + GPIO_PIN(D, 0), // D3 + GPIO_PIN(D, 4), // D4 + GPIO_PIN(C, 6), // D5 + GPIO_PIN(D, 7), // D6 + GPIO_PIN(E, 6), // D7 + GPIO_PIN(B, 4), // D8 + GPIO_PIN(B, 5), // D9 + GPIO_PIN(B, 6), // D10 + GPIO_PIN(B, 7), // D11 + GPIO_PIN(D, 6), // D12 + GPIO_PIN(C, 7), // D13 + GPIO_PIN(B, 3), // D14 + GPIO_PIN(B, 1), // D15 + GPIO_PIN(B, 2), // D16 + GPIO_PIN(B, 0), // D17 + GPIO_PIN(F, 7), // D18 + GPIO_PIN(F, 6), // D19 + GPIO_PIN(F, 5), // D20 + GPIO_PIN(F, 4), // D21 + GPIO_PIN(F, 1), // D22 + GPIO_PIN(F, 0), // D23 + GPIO_PIN(D, 4), // D24 + GPIO_PIN(D, 7), // D25 + GPIO_PIN(B, 4), // D26 + GPIO_PIN(B, 5), // D27 + GPIO_PIN(B, 6), // D28 + GPIO_PIN(D, 6) // D29 +}; +#endif // LeonardoGpioPinMap_h diff --git a/libraries/SdFat/src/SpiDriver/boards/MegaGpioPinMap.h b/libraries/SdFat/src/SpiDriver/boards/MegaGpioPinMap.h new file mode 100644 index 0000000..c041343 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/boards/MegaGpioPinMap.h @@ -0,0 +1,75 @@ +#ifndef MegaGpioPinMap_h +#define MegaGpioPinMap_h +static const GpioPinMap_t GpioPinMap[] = { + GPIO_PIN(E, 0), // D0 + GPIO_PIN(E, 1), // D1 + GPIO_PIN(E, 4), // D2 + GPIO_PIN(E, 5), // D3 + GPIO_PIN(G, 5), // D4 + GPIO_PIN(E, 3), // D5 + GPIO_PIN(H, 3), // D6 + GPIO_PIN(H, 4), // D7 + GPIO_PIN(H, 5), // D8 + GPIO_PIN(H, 6), // D9 + GPIO_PIN(B, 4), // D10 + GPIO_PIN(B, 5), // D11 + GPIO_PIN(B, 6), // D12 + GPIO_PIN(B, 7), // D13 + GPIO_PIN(J, 1), // D14 + GPIO_PIN(J, 0), // D15 + GPIO_PIN(H, 1), // D16 + GPIO_PIN(H, 0), // D17 + GPIO_PIN(D, 3), // D18 + GPIO_PIN(D, 2), // D19 + GPIO_PIN(D, 1), // D20 + GPIO_PIN(D, 0), // D21 + GPIO_PIN(A, 0), // D22 + GPIO_PIN(A, 1), // D23 + GPIO_PIN(A, 2), // D24 + GPIO_PIN(A, 3), // D25 + GPIO_PIN(A, 4), // D26 + GPIO_PIN(A, 5), // D27 + GPIO_PIN(A, 6), // D28 + GPIO_PIN(A, 7), // D29 + GPIO_PIN(C, 7), // D30 + GPIO_PIN(C, 6), // D31 + GPIO_PIN(C, 5), // D32 + GPIO_PIN(C, 4), // D33 + GPIO_PIN(C, 3), // D34 + GPIO_PIN(C, 2), // D35 + GPIO_PIN(C, 1), // D36 + GPIO_PIN(C, 0), // D37 + GPIO_PIN(D, 7), // D38 + GPIO_PIN(G, 2), // D39 + GPIO_PIN(G, 1), // D40 + GPIO_PIN(G, 0), // D41 + GPIO_PIN(L, 7), // D42 + GPIO_PIN(L, 6), // D43 + GPIO_PIN(L, 5), // D44 + GPIO_PIN(L, 4), // D45 + GPIO_PIN(L, 3), // D46 + GPIO_PIN(L, 2), // D47 + GPIO_PIN(L, 1), // D48 + GPIO_PIN(L, 0), // D49 + GPIO_PIN(B, 3), // D50 + GPIO_PIN(B, 2), // D51 + GPIO_PIN(B, 1), // D52 + GPIO_PIN(B, 0), // D53 + GPIO_PIN(F, 0), // D54 + GPIO_PIN(F, 1), // D55 + GPIO_PIN(F, 2), // D56 + GPIO_PIN(F, 3), // D57 + GPIO_PIN(F, 4), // D58 + GPIO_PIN(F, 5), // D59 + GPIO_PIN(F, 6), // D60 + GPIO_PIN(F, 7), // D61 + GPIO_PIN(K, 0), // D62 + GPIO_PIN(K, 1), // D63 + GPIO_PIN(K, 2), // D64 + GPIO_PIN(K, 3), // D65 + GPIO_PIN(K, 4), // D66 + GPIO_PIN(K, 5), // D67 + GPIO_PIN(K, 6), // D68 + GPIO_PIN(K, 7) // D69 +}; +#endif // MegaGpioPinMap_h diff --git a/libraries/SdFat/src/SpiDriver/boards/SleepingBeautyGpioPinMap.h b/libraries/SdFat/src/SpiDriver/boards/SleepingBeautyGpioPinMap.h new file mode 100644 index 0000000..bf040d9 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/boards/SleepingBeautyGpioPinMap.h @@ -0,0 +1,37 @@ +#ifndef SleepingBeautyGpioPinMap_h +#define SleepingBeautyGpioPinMap_h +static const GpioPinMap_t GpioPinMap[] = { + GPIO_PIN(D, 0), // D0 + GPIO_PIN(D, 1), // D1 + GPIO_PIN(D, 2), // D2 + GPIO_PIN(D, 3), // D3 + GPIO_PIN(B, 0), // D4 + GPIO_PIN(B, 1), // D5 + GPIO_PIN(B, 2), // D6 + GPIO_PIN(B, 3), // D7 + GPIO_PIN(D, 6), // D8 + GPIO_PIN(D, 5), // D9 + GPIO_PIN(B, 4), // D10 + GPIO_PIN(B, 5), // D11 + GPIO_PIN(B, 6), // D12 + GPIO_PIN(B, 7), // D13 + GPIO_PIN(C, 7), // D14 + GPIO_PIN(C, 6), // D15 + GPIO_PIN(A, 5), // D16 + GPIO_PIN(A, 4), // D17 + GPIO_PIN(A, 3), // D18 + GPIO_PIN(A, 2), // D19 + GPIO_PIN(A, 1), // D20 + GPIO_PIN(A, 0), // D21 + GPIO_PIN(D, 4), // D22 + GPIO_PIN(D, 7), // D23 + GPIO_PIN(C, 2), // D24 + GPIO_PIN(C, 3), // D25 + GPIO_PIN(C, 4), // D26 + GPIO_PIN(C, 5), // D27 + GPIO_PIN(C, 1), // D28 + GPIO_PIN(C, 0), // D29 + GPIO_PIN(A, 6), // D30 + GPIO_PIN(A, 7) // D31 +}; +#endif // SleepingBeautyGpioPinMap_h \ No newline at end of file diff --git a/libraries/SdFat/src/SpiDriver/boards/Standard1284GpioPinMap.h b/libraries/SdFat/src/SpiDriver/boards/Standard1284GpioPinMap.h new file mode 100644 index 0000000..d38ff0c --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/boards/Standard1284GpioPinMap.h @@ -0,0 +1,37 @@ +#ifndef Standard1284GpioPinMap_h +#define Standard1284GpioPinMap_h +static const GpioPinMap_t GpioPinMap[] = { + GPIO_PIN(B, 0), // D0 + GPIO_PIN(B, 1), // D1 + GPIO_PIN(B, 2), // D2 + GPIO_PIN(B, 3), // D3 + GPIO_PIN(B, 4), // D4 + GPIO_PIN(B, 5), // D5 + GPIO_PIN(B, 6), // D6 + GPIO_PIN(B, 7), // D7 + GPIO_PIN(D, 0), // D8 + GPIO_PIN(D, 1), // D9 + GPIO_PIN(D, 2), // D10 + GPIO_PIN(D, 3), // D11 + GPIO_PIN(D, 4), // D12 + GPIO_PIN(D, 5), // D13 + GPIO_PIN(D, 6), // D14 + GPIO_PIN(D, 7), // D15 + GPIO_PIN(C, 0), // D16 + GPIO_PIN(C, 1), // D17 + GPIO_PIN(C, 2), // D18 + GPIO_PIN(C, 3), // D19 + GPIO_PIN(C, 4), // D20 + GPIO_PIN(C, 5), // D21 + GPIO_PIN(C, 6), // D22 + GPIO_PIN(C, 7), // D23 + GPIO_PIN(A, 0), // D24 + GPIO_PIN(A, 1), // D25 + GPIO_PIN(A, 2), // D26 + GPIO_PIN(A, 3), // D27 + GPIO_PIN(A, 4), // D28 + GPIO_PIN(A, 5), // D29 + GPIO_PIN(A, 6), // D30 + GPIO_PIN(A, 7) // D31 +}; +#endif // Standard1284GpioPinMap_h \ No newline at end of file diff --git a/libraries/SdFat/src/SpiDriver/boards/Teensy2GpioPinMap.h b/libraries/SdFat/src/SpiDriver/boards/Teensy2GpioPinMap.h new file mode 100644 index 0000000..00aa437 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/boards/Teensy2GpioPinMap.h @@ -0,0 +1,30 @@ +#ifndef Teensy2GpioPinMap_h +#define Teensy2GpioPinMap_h +static const GpioPinMap_t GpioPinMap[] = { + GPIO_PIN(B, 0), // D0 + GPIO_PIN(B, 1), // D1 + GPIO_PIN(B, 2), // D2 + GPIO_PIN(B, 3), // D3 + GPIO_PIN(B, 7), // D4 + GPIO_PIN(D, 0), // D5 + GPIO_PIN(D, 1), // D6 + GPIO_PIN(D, 2), // D7 + GPIO_PIN(D, 3), // D8 + GPIO_PIN(C, 6), // D9 + GPIO_PIN(C, 7), // D10 + GPIO_PIN(D, 6), // D11 + GPIO_PIN(D, 7), // D12 + GPIO_PIN(B, 4), // D13 + GPIO_PIN(B, 5), // D14 + GPIO_PIN(B, 6), // D15 + GPIO_PIN(F, 7), // D16 + GPIO_PIN(F, 6), // D17 + GPIO_PIN(F, 5), // D18 + GPIO_PIN(F, 4), // D19 + GPIO_PIN(F, 1), // D20 + GPIO_PIN(F, 0), // D21 + GPIO_PIN(D, 4), // D22 + GPIO_PIN(D, 5), // D23 + GPIO_PIN(E, 6), // D24 +}; +#endif // Teensy2GpioPinMap_h diff --git a/libraries/SdFat/src/SpiDriver/boards/Teensy2ppGpioPinMap.h b/libraries/SdFat/src/SpiDriver/boards/Teensy2ppGpioPinMap.h new file mode 100644 index 0000000..68c51d7 --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/boards/Teensy2ppGpioPinMap.h @@ -0,0 +1,51 @@ +#ifndef Teensypp2GpioPinMap_h +#define Teensypp2GpioPinMap_h +static const GpioPinMap_t GpioPinMap[] = { + GPIO_PIN(D, 0), // D0 + GPIO_PIN(D, 1), // D1 + GPIO_PIN(D, 2), // D2 + GPIO_PIN(D, 3), // D3 + GPIO_PIN(D, 4), // D4 + GPIO_PIN(D, 5), // D5 + GPIO_PIN(D, 6), // D6 + GPIO_PIN(D, 7), // D7 + GPIO_PIN(E, 0), // D8 + GPIO_PIN(E, 1), // D9 + GPIO_PIN(C, 0), // D10 + GPIO_PIN(C, 1), // D11 + GPIO_PIN(C, 2), // D12 + GPIO_PIN(C, 3), // D13 + GPIO_PIN(C, 4), // D14 + GPIO_PIN(C, 5), // D15 + GPIO_PIN(C, 6), // D16 + GPIO_PIN(C, 7), // D17 + GPIO_PIN(E, 6), // D18 + GPIO_PIN(E, 7), // D19 + GPIO_PIN(B, 0), // D20 + GPIO_PIN(B, 1), // D21 + GPIO_PIN(B, 2), // D22 + GPIO_PIN(B, 3), // D23 + GPIO_PIN(B, 4), // D24 + GPIO_PIN(B, 5), // D25 + GPIO_PIN(B, 6), // D26 + GPIO_PIN(B, 7), // D27 + GPIO_PIN(A, 0), // D28 + GPIO_PIN(A, 1), // D29 + GPIO_PIN(A, 2), // D30 + GPIO_PIN(A, 3), // D31 + GPIO_PIN(A, 4), // D32 + GPIO_PIN(A, 5), // D33 + GPIO_PIN(A, 6), // D34 + GPIO_PIN(A, 7), // D35 + GPIO_PIN(E, 4), // D36 + GPIO_PIN(E, 5), // D37 + GPIO_PIN(F, 0), // D38 + GPIO_PIN(F, 1), // D39 + GPIO_PIN(F, 2), // D40 + GPIO_PIN(F, 3), // D41 + GPIO_PIN(F, 4), // D42 + GPIO_PIN(F, 5), // D43 + GPIO_PIN(F, 6), // D44 + GPIO_PIN(F, 7), // D45 +}; +#endif // Teensypp2GpioPinMap_h diff --git a/libraries/SdFat/src/SpiDriver/boards/UnoGpioPinMap.h b/libraries/SdFat/src/SpiDriver/boards/UnoGpioPinMap.h new file mode 100644 index 0000000..21ec75d --- /dev/null +++ b/libraries/SdFat/src/SpiDriver/boards/UnoGpioPinMap.h @@ -0,0 +1,25 @@ +#ifndef UnoGpioPinMap_h +#define UnoGpioPinMap_h +static const GpioPinMap_t GpioPinMap[] = { + GPIO_PIN(D, 0), // D0 + GPIO_PIN(D, 1), // D1 + GPIO_PIN(D, 2), // D2 + GPIO_PIN(D, 3), // D3 + GPIO_PIN(D, 4), // D4 + GPIO_PIN(D, 5), // D5 + GPIO_PIN(D, 6), // D6 + GPIO_PIN(D, 7), // D7 + GPIO_PIN(B, 0), // D8 + GPIO_PIN(B, 1), // D9 + GPIO_PIN(B, 2), // D10 + GPIO_PIN(B, 3), // D11 + GPIO_PIN(B, 4), // D12 + GPIO_PIN(B, 5), // D13 + GPIO_PIN(C, 0), // D14 + GPIO_PIN(C, 1), // D15 + GPIO_PIN(C, 2), // D16 + GPIO_PIN(C, 3), // D17 + GPIO_PIN(C, 4), // D18 + GPIO_PIN(C, 5) // D19 +}; +#endif // UnoGpioPinMap_h \ No newline at end of file diff --git a/libraries/SdFat/src/SysCall.h b/libraries/SdFat/src/SysCall.h new file mode 100644 index 0000000..9c2c010 --- /dev/null +++ b/libraries/SdFat/src/SysCall.h @@ -0,0 +1,83 @@ +/* FatLib Library + * Copyright (C) 2013 by William Greiman + * + * This file is part of the FatLib 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 FatLib Library. If not, see + * . + */ +#ifndef SysCall_h +#define SysCall_h +/** + * \file + * \brief SysCall class + */ +#if defined(ARDUINO) +#include +#include +#elif defined(PLATFORM_ID) // Only defined if a Particle device +#include "application.h" +#else // defined(ARDUINO) +#error "Unknown system" +#endif // defined(ARDUINO) +//----------------------------------------------------------------------------- +#ifdef ESP8266 +// undefine F macro if ESP8266. +#undef F +#endif // ESP8266 +//----------------------------------------------------------------------------- +#ifndef F +/** Define macro for strings stored in flash. */ +#define F(str) (str) +#endif // F +//----------------------------------------------------------------------------- +/** \return the time in milliseconds. */ +inline uint16_t curTimeMS() { + return millis(); +} +//----------------------------------------------------------------------------- +/** + * \class SysCall + * \brief SysCall - Class to wrap system calls. + */ +class SysCall { + public: + /** Halt execution of this thread. */ + static void halt() { + while (1) { + yield(); + } + } + /** Yield to other threads. */ + static void yield(); +}; + +#if defined(ESP8266) +inline void SysCall::yield() { + // Avoid ESP8266 bug + delay(0); +} +#elif defined(ARDUINO) +inline void SysCall::yield() { + // Use the external Arduino yield() function. + ::yield(); +} +#elif defined(PLATFORM_ID) // Only defined if a Particle device +inline void SysCall::yield() { + Particle.process(); +} +#else // ESP8266 +inline void SysCall::yield() {} +#endif // ESP8266 +#endif // SysCall_h diff --git a/lora-gps/config.h b/lora-gps/config.h new file mode 100644 index 0000000..23dde08 --- /dev/null +++ b/lora-gps/config.h @@ -0,0 +1,19 @@ +#include // for the key data type u1_t + +// Schedule TX every this many seconds (might become longer due to duty +// cycle limitations). +const unsigned TX_INTERVAL = 40; + +// This EUI must be in little-endian format, so least-significant-byte +// first. When copying an EUI from ttnctl output, this means to reverse +// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, +// 0x70. +static const u1_t PROGMEM APPEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD5, 0xB3, 0x70 }; + +// This should also be in little endian format, see above. +static const u1_t PROGMEM DEVEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0xBE, 0x77, 0x56, 0x00 }; + +// This key should be in big endian format (or, since it is not really a +// number but a block of memory, endianness does not really apply). In +// practice, a key taken from ttnctl can be copied as-is. +static const u1_t PROGMEM APPKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0x08 }; diff --git a/lora-gps/lora-gps.ino b/lora-gps/lora-gps.ino new file mode 100644 index 0000000..25a53c1 --- /dev/null +++ b/lora-gps/lora-gps.ino @@ -0,0 +1,169 @@ +/** + lora-gps senseBox with SDS011 particulate matter + HDC1008 temp & humi sensors + for Arduino Mega with Dragino LoRa shield. + SDS is on Serial3, GPS on Serial2 +*/ + +#include "config.h" +#include "lora.h" +#include "sd.h" + +#include +#include + +#include + +//#include + +#include +TinyGPSPlus gps; + +//Load sensors +SDS011 my_sds(Serial3); +HDC100X HDC(0x43); + +//measurement variables +float temperature = 0, humidity = 0, p10 = 0, p25 = 0; +int error; + +void do_send(osjob_t* j) { + // Check if there is not a current TX/RX job running + if (LMIC.opmode & OP_TXRXPEND) { + Serial.println(F("OP_TXRXPEND, not sending")); + } else { + LoraMessage message; + + //-----GPS-----// + bool newData = false; + float lat, lng; + for (unsigned long start = millis(); millis() - start < 5000;) // timeout + { + // TODO + //while (gps.location.isUpdated() && gps.location.isValid()) + while (Serial2.available()) + { + char c = Serial2.read(); + if (gps.encode(c)) // Did a new valid sentence come in? + newData = true; + } + } + if (newData) { + lat = gps.location.lat(); + lng = gps.location.lng(); + Serial.print("latitude: "); + Serial.println(lat, 6); + Serial.print("longitude: "); + Serial.println(lng, 6); + message.addLatLng(lat, lng); + } else { + return; + } + + delay(300); + + //-----Temperature-----// + Serial.print("temperature: "); + temperature = HDC.getTemp(); + Serial.println(temperature); + message.addTemperature(temperature); + delay(300); + + //-----Humidity-----// + Serial.print("humidity: "); + humidity = HDC.getHumi(); + Serial.println(humidity); + message.addHumidity(humidity); + delay(300); + + //-----fine dust-----/ + error = my_sds.read(&p25, &p10); + if (!error) { + message.addTemperature(p25); + message.addTemperature(p10); + Serial.println("P2.5: " + String(p25)); + Serial.println("P10: " + String(p10)); + } + + Serial.println(F("Writing to SD card.")); + writeToSD(temperature, humidity, p25, p10, gps); + + // Prepare upstream data transmission at the next possible time. + LMIC_setTxData2(1, message.getBytes(), message.getLength(), 0); + Serial.println(F("LoRa Packet queued")); + + } + // Next TX is scheduled after TX_COMPLETE event. +} + +void initSensors() { + //Initialize sensors + Serial.print("Initializing sensors..."); + Wire.begin(); + HDC.begin(HDC100X_TEMP_HUMI, HDC100X_14BIT, HDC100X_14BIT, DISABLE); + Serial.println("done!"); + temperature = HDC.getTemp(); + + // initialize GPS Serial Port + Serial2.begin(9600); + while (!Serial2.available()) { + Serial.println("detecting GPS device..."); + delay(1000); + } + Serial.println("Wait for GPS..."); + while (!gps.location.isValid()) { + gps.encode(Serial2.read()); + delay(1); + } + Serial.println("Got GPS fix!"); + + // init SD card + Serial.print("Initializing SD card..."); + + if (!SD.begin(4)) { + Serial.println("failed!"); + return; + } + Serial.println("done!"); + + // initalize SDS Serial Port + Serial3.begin(9600); +} + +void setup() { + Serial.begin(9600); // debug serial + Serial.println(F("Starting")); + +#ifdef VCC_ENABLE + // For Pinoccio Scout boards + pinMode(VCC_ENABLE, OUTPUT); + digitalWrite(VCC_ENABLE, HIGH); + delay(1000); +#endif + + // sd card + pinMode(4, INPUT); + digitalWrite(4, HIGH); + + initSensors(); + + Serial.println("initializing LoRa.."); + + // LMIC LoRa init + os_init(); + // Reset the MAC state. Session and pending data transfers will be discarded. + LMIC_reset(); + + // maximum tx power + LMIC.txpow = 27; + // slower datarate -> more stability. faster datarate -> lower airtime -> more packets + // see https://docs.google.com/spreadsheets/d/1eL1nHxMidIcIdDE_l-DoY3kmE2e8b0YpOBW64WnYxj8 + LMIC.datarate = DR_SF10; + + Serial.println("Starting loop."); + // Start job (sending automatically starts OTAA too) + do_send(&sendjob); +} + +void loop() { + os_runloop_once(); +} diff --git a/lora-gps/lora.h b/lora-gps/lora.h new file mode 100644 index 0000000..6fd7318 --- /dev/null +++ b/lora-gps/lora.h @@ -0,0 +1,108 @@ +#include +#include +#define LMIC_DEBUG_LEVEL 0 + +void os_getArtEui (u1_t* buf) { + memcpy_P(buf, APPEUI, 8); +} + +void os_getDevEui (u1_t* buf) { + Serial.println("writing devid"); + memcpy_P(buf, DEVEUI, 8); +} + +void os_getDevKey (u1_t* buf) { + memcpy_P(buf, APPKEY, 16); +} + +static osjob_t sendjob; +void do_send(osjob_t* j); // predeclaration, implementation in main script + + +// Pin mapping for Dragino LoRa Shield V1.3 +const lmic_pinmap lmic_pins = { + .nss = 10, + .rxtx = LMIC_UNUSED_PIN, + .rst = LMIC_UNUSED_PIN, + .dio = {2, 6, 7} +}; + +void reboot () { + Serial.println("Restarting System."); + delay(5000); + asm volatile (" jmp 0"); +} + +void onEvent (ev_t ev) { + Serial.print(os_getTime()); + Serial.print(": "); + switch (ev) { + case EV_SCAN_TIMEOUT: + Serial.println(F("EV_SCAN_TIMEOUT")); + break; + case EV_BEACON_FOUND: + Serial.println(F("EV_BEACON_FOUND")); + break; + case EV_BEACON_MISSED: + Serial.println(F("EV_BEACON_MISSED")); + break; + case EV_BEACON_TRACKED: + Serial.println(F("EV_BEACON_TRACKED")); + break; + case EV_JOINING: + Serial.println(F("EV_JOINING")); + break; + case EV_JOINED: + Serial.println(F("EV_JOINED")); + + // Disable link check validation (automatically enabled + // during join, but not supported by TTN at this time). + LMIC_setLinkCheckMode(0); + break; + case EV_RFU1: + Serial.println(F("EV_RFU1")); + break; + case EV_JOIN_FAILED: + Serial.println(F("EV_JOIN_FAILED")); + reboot(); + break; + case EV_REJOIN_FAILED: + Serial.println(F("EV_REJOIN_FAILED")); + reboot(); + break; + break; + case EV_TXCOMPLETE: + Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); + if (LMIC.txrxFlags & TXRX_ACK) + Serial.println(F("Received ack")); + if (LMIC.dataLen) { + Serial.println(F("Received ")); + Serial.println(LMIC.dataLen); + Serial.println(F(" bytes of payload")); + } + // Schedule next transmission + os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send); + break; + case EV_LOST_TSYNC: + Serial.println(F("EV_LOST_TSYNC")); + reboot(); + break; + case EV_RESET: + Serial.println(F("EV_RESET")); + reboot(); + break; + case EV_RXCOMPLETE: + // data received in ping slot + Serial.println(F("EV_RXCOMPLETE")); + break; + case EV_LINK_DEAD: + Serial.println(F("EV_LINK_DEAD")); + break; + case EV_LINK_ALIVE: + Serial.println(F("EV_LINK_ALIVE")); + break; + default: + Serial.println(F("Unknown event")); + break; + } +} diff --git a/lora-gps/sd.h b/lora-gps/sd.h new file mode 100644 index 0000000..656560d --- /dev/null +++ b/lora-gps/sd.h @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include + +#include + +SdFat SD; +File logFile; + +bool writeToSD (float temperature, float humidity, float p25, float p10, TinyGPSPlus gps) { + logFile = SD.open("datalog.csv", FILE_WRITE); + if (!logFile) return false; + + logFile.print(temperature, 2); + logFile.print(","); + logFile.print(humidity, 2); + logFile.print(","); + logFile.print(p25, 2); + logFile.print(","); + logFile.print(p10, 2); + logFile.print(","); + logFile.print(gps.location.lat(), 6); + logFile.print(","); + logFile.print(gps.location.lng(), 6); + logFile.print(","); + + logFile.print(gps.date.year()); + logFile.print(F("-")); + if (gps.date.month() < 10) logFile.print(F("0")); + logFile.print(gps.date.month()); + logFile.print(F("-")); + if (gps.date.day() < 10) logFile.print(F("0")); + logFile.print(gps.date.day()); + logFile.print(F("T")); + logFile.print(gps.time.hour()); + logFile.print(F(":")); + if (gps.time.minute() < 10) logFile.print(F("0")); + logFile.print(gps.time.minute()); + logFile.print(F(":")); + if (gps.time.second() < 10) logFile.print(F("0")); + logFile.print(gps.time.second()); + logFile.print(F("Z")); + + logFile.close(); +} +