I have finished a major overhaul, with far more possibilities.
I have created a generic printing class called NonStreamingIO and combined with the Arduino core provided 'Printable' Class, the eeprom code ( EString ) functions the same as the GString, except prints to ROM.
The Printable class allows printing strings directly into the print class. There is still more to go, but here is what the builtin version of GString and EString will look like, the printf functionality is builtin to Print now.
These allow things like:
EString e( 0, 10 ); //Set string from 0 to 0 + 10, or 11 characters.
//Send current string from EEPROM over serial.
Serial.print( e );
//Write a float to EEPROM.
e.print( 123.456f, 3 );
That code above is how the Print library and sprintf will deal with EEPROM and SRAM reading writing ( printing out / printing to ).
This is only a preliminary attempt, but here is the SRAMWriterand EEPROMWriter, which are typedef'd to GString and EString.
#ifndef HEADER_PRINTER
#define HEADER_PRINTER
class NonStreamingIO : public Print{
public:
size_t count( void ) const { return End - Start; }
virtual size_t write(uint8_t) = 0;
template< typename T > NonStreamingIO &operator +=( const T &t )
{
print( t );
return *this;
}
template< typename T > NonStreamingIO &concat( const T &t )
{
print( t );
return *this;
}
template< typename T > NonStreamingIO &concat( const T &t, const int i )
{
print( t, i );
return *this;
}
template< typename T > inline void assign( const T *u_DataPtr, const uint16_t u_Length )
{
Start = ( uint8_t* ) u_DataPtr;
End = Start + u_Length;
}
protected:
NonStreamingIO( uint8_t *u_DataPtr ) : Start( u_DataPtr ) , End( Start )
{ return; }
NonStreamingIO( uint8_t *u_DataPtr, const unsigned int u_Length ) : Start( u_DataPtr ) , End( Start + u_Length )
{ return; }
uint8_t *Start;
uint8_t *End;
private:
};
#include <avr/eeprom.h>
class EEPROMWriter : public NonStreamingIO, public Printable{
public:
template< typename T > EEPROMWriter( const T *t_DataPtr ) : NonStreamingIO( ( uint8_t* ) t_DataPtr ), Printable()
{ return; }
template< typename T > EEPROMWriter( const T *t_DataPtr, const unsigned int u_Length ) : NonStreamingIO( ( uint8_t* ) t_DataPtr, u_Length ), Printable()
{ return; }
size_t write( uint8_t u_Data )
{
if( eeprom_read_byte( End ) != u_Data )
eeprom_write_byte( End, u_Data );
++End;
return 0x01;
}
protected:
friend Print;
size_t printTo(Print& p) const
{
uint8_t *u_Cursor = Start;
while( u_Cursor <= End ) p.write( ( uint8_t ) eeprom_read_byte( u_Cursor++ ) );
return count();
}
private:
};
class SRAMWriter : public NonStreamingIO{
public:
template< typename T > SRAMWriter( const T *t_DataPtr ) : NonStreamingIO( ( uint8_t* ) t_DataPtr )
{ return; }
template< typename T > SRAMWriter( const T *t_DataPtr, const unsigned int u_Length ) : NonStreamingIO( ( uint8_t* ) t_DataPtr, u_Length )
{ return; }
operator char*( void )
{
*End = '\0';
return ( char* ) Start;
}
void end( void ) { *End++ = '\0'; }
size_t write( uint8_t u_Data )
{
*End++ = u_Data;
return 0x01;
}
protected:
private:
};
typedef SRAMWriter GString;
typedef EEPROMWriter EString;
#endif
I'll have to post the full patch later on tonight after work.