added binary support and procedural names to

Fl_Preferences, updated FLUID, update documentation.

Attempted to strip all Win32 CR.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@2146 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher
2002-04-30 22:25:18 +00:00
parent 8972642109
commit adb6fc4eeb
5 changed files with 232 additions and 49 deletions
+13 -10
View File
@@ -1,5 +1,5 @@
// //
// "$Id: Fl_Preferences.H,v 1.1.2.4 2002/04/30 18:11:49 easysw Exp $" // "$Id: Fl_Preferences.H,v 1.1.2.5 2002/04/30 22:25:18 matthiaswm Exp $"
// //
// Preferences definitions for the Fast Light Tool Kit (FLTK). // Preferences definitions for the Fast Light Tool Kit (FLTK).
// //
@@ -33,10 +33,6 @@
#include <stdio.h> #include <stdio.h>
// missing features:
// - get and set binary data
// - Fl_Preferences could offer functions that return the value instead off an error code to write directly into widgets
/** /**
* Preferences are a data tree containing a root, branches and leafs * Preferences are a data tree containing a root, branches and leafs
@@ -69,7 +65,7 @@ public:
FL_EXPORT char set( const char *entry, float value ); FL_EXPORT char set( const char *entry, float value );
FL_EXPORT char set( const char *entry, double value ); FL_EXPORT char set( const char *entry, double value );
FL_EXPORT char set( const char *entry, const char *value ); FL_EXPORT char set( const char *entry, const char *value );
// FL_EXPORT char set( const char *entry, const void *value, int size ); FL_EXPORT char set( const char *entry, const void *value, int size );
FL_EXPORT char get( const char *entry, char &value, char defaultValue ); FL_EXPORT char get( const char *entry, char &value, char defaultValue );
FL_EXPORT char get( const char *entry, int &value, int defaultValue ); FL_EXPORT char get( const char *entry, int &value, int defaultValue );
@@ -77,8 +73,8 @@ public:
FL_EXPORT char get( const char *entry, double &value, double defaultValue ); FL_EXPORT char get( const char *entry, double &value, double defaultValue );
FL_EXPORT char get( const char *entry, char *&value, const char *defaultValue ); FL_EXPORT char get( const char *entry, char *&value, const char *defaultValue );
FL_EXPORT char get( const char *entry, char *value, const char *defaultValue, int maxSize ); FL_EXPORT char get( const char *entry, char *value, const char *defaultValue, int maxSize );
// FL_EXPORT char get( const char *entry, void *&value, const char *defaultValue ); FL_EXPORT char get( const char *entry, void *&value, const void *defaultValue, int defaultSize );
// FL_EXPORT char get( const char *entry, void *value, const char *defaultValue, int maxSize ); FL_EXPORT char get( const char *entry, void *value, const void *defaultValue, int defaultSize, int maxSize );
FL_EXPORT int size( const char *entry ); FL_EXPORT int size( const char *entry );
FL_EXPORT char getUserdataPath( char *path, int pathlen ); FL_EXPORT char getUserdataPath( char *path, int pathlen );
@@ -88,7 +84,14 @@ public:
// FL_EXPORT char export( const char *filename, enum Type fileFormat ); // FL_EXPORT char export( const char *filename, enum Type fileFormat );
// FL_EXPORT char import( const char *filename ); // FL_EXPORT char import( const char *filename );
// FL_EXPORT const char *namef( const char *, ... ); class Name {
char *data_;
public:
FL_EXPORT Name( unsigned int n );
FL_EXPORT Name( const char *format, ... );
FL_EXPORT operator const char *() { return data_; }
FL_EXPORT ~Name();
};
private: private:
@@ -154,5 +157,5 @@ private:
#endif // !Fl_Preferences_H #endif // !Fl_Preferences_H
// //
// End of "$Id: Fl_Preferences.H,v 1.1.2.4 2002/04/30 18:11:49 easysw Exp $". // End of "$Id: Fl_Preferences.H,v 1.1.2.5 2002/04/30 22:25:18 matthiaswm Exp $".
// //
+27 -12
View File
@@ -10,7 +10,7 @@
<h3>Class Hierarchy</h3> <h3>Class Hierarchy</h3>
<ul><pre> <ul><pre>
<b>Fl_Preferences</a></H4>&nbsp; <b>Fl_Preferences</b></a></H4>&nbsp;
</pre></ul> </pre></ul>
<h3>Include Files</h3> <h3>Include Files</h3>
@@ -65,6 +65,7 @@ method.
<li><a href="#Fl_Preferences.groups">groups</a></li> <li><a href="#Fl_Preferences.groups">groups</a></li>
<li><a href="#Fl_Preferences.set">set</a></li> <li><a href="#Fl_Preferences.set">set</a></li>
<li><a href="#Fl_Preferences.size">size</a></li> <li><a href="#Fl_Preferences.size">size</a></li>
<li><a href="#Fl_Preferences.Name">Name</a></li>
</ul> </ul>
@@ -133,19 +134,21 @@ deleting the base preferences flushes automatically.
that is usable for application data beyond what is covered by that is usable for application data beyond what is covered by
<tt>Fl_Preferences</tt>. <tt>Fl_Preferences</tt>.
<H4><a name="Fl_Preferences.get">int get(const char *entry, int &amp;value,&nbsp;&nbsp; int defaultValue)<BR> <H4><a name="Fl_Preferences.get">int get(const char *entry, int &amp;value, int defaultValue)<BR>
int get(const char *entry, int &amp;value,&nbsp;&nbsp;&nbsp; int defaultValue)<BR> int get(const char *entry, int &amp;value, int defaultValue)<BR>
int get(const char *entry, float &amp;value,&nbsp; float defaultValue)<BR> int get(const char *entry, float &amp;value, float defaultValue)<BR>
int get(const char *entry, double &amp;value, double defaultValue ) int get(const char *entry, double &amp;value, double defaultValue )<BR>
int get(const char *entry, char *&amp;value,&nbsp; const char *defaultValue)<BR> int get(const char *entry, char *&amp;text, const char *defaultValue)<BR>
int get(const char *entry, char *value,&nbsp;&nbsp; const char *defaultValue, int get(const char *entry, char *text, const char *defaultValue, int maxSize)<BR>
int get(const char *entry, void *&amp;data, const void *defaultValue, int defaultSize)<BR>
int get(const char *entry, void *data, const void *defaultValue, int defaultSize,
int maxSize)</a></H4> int maxSize)</a></H4>
<P>Reads an entry from the group. A default value must be <P>Reads an entry from the group. A default value must be
supplied. The return value indicates if the value was available supplied. The return value indicates if the value was available
(non-zero) or the default was used (0). If the '<tt>char (non-zero) or the default was used (0). If the '<tt>char
*&amp;value</tt>' form is used, the resulting text must be freed *&amp;text</tt>' or '<tt>void *&amp;data</tt>' form is used,
with '<tt>free(value)</tt>'. the resulting data must be freed with '<tt>free(value)</tt>'.
<H4><a name="Fl_Preferences.group">const char <H4><a name="Fl_Preferences.group">const char
*Fl_Preferences::group(int ix)</a></H4> *Fl_Preferences::group(int ix)</a></H4>
@@ -167,10 +170,10 @@ group.
int set(const char *entry, int value)<BR> int set(const char *entry, int value)<BR>
int set(const char *entry, float value)<BR> int set(const char *entry, float value)<BR>
int set(const char *entry, double value)<BR> int set(const char *entry, double value)<BR>
int set(const char *entry, const char *value)</a></H4> int set(const char *entry, const char *text)<BR>
int set(const char *entry, const void *data, int size)</a></H4>
<P>Sets an entry (name/value pair). Text data must not contain <P>Sets an entry (name/value pair). The return value indicates if there
any '\n' or '\r' characters. The return value indicates if there
was a problem storing the data in memory. However it does not was a problem storing the data in memory. However it does not
reflect if the value was actually stored in the preferences reflect if the value was actually stored in the preferences
file. file.
@@ -179,6 +182,18 @@ file.
<P>Returns the size of the value part of an entry. <P>Returns the size of the value part of an entry.
<H4><a name="Fl_Preferences.Name">
Fl_Preferences::Name( unsigned int numericName )<BR>
Fl_Preferences::Name( const char *format, ... )
</a></H4>
<P>'Name' provides a simple method to create numerical or more complex
procedural names for entries and groups on the fly,
i.e. <tt>prefs.set(Fl_Preferences::Name("File%d",i),file[i]);</tt>.
See <tt>test/preferences.cxx</tt> as a sample for writing arrays into preferences.<p>
'Name' is actually implemented as a class inside Fl_Preferences. It casts
into <tt>const char*</tt> and gets automatically destroyed after the enclosing call.
</body> </body>
</html> </html>
+4 -8
View File
@@ -1,5 +1,5 @@
// //
// "$Id: fluid.cxx,v 1.15.2.13.2.15 2002/04/30 18:11:49 easysw Exp $" // "$Id: fluid.cxx,v 1.15.2.13.2.16 2002/04/30 22:25:18 matthiaswm Exp $"
// //
// FLUID main entry for the Fast Light Tool Kit (FLTK). // FLUID main entry for the Fast Light Tool Kit (FLTK).
// //
@@ -468,11 +468,9 @@ void make_main_window() {
// Load file history from preferences... // Load file history from preferences...
void load_history() { void load_history() {
int i; // Looping var int i; // Looping var
char name[32]; // Variable name
for (i = 0; i < 10; i ++) { for (i = 0; i < 10; i ++) {
sprintf(name, "file%d", i); fluid_prefs.get( Fl_Preferences::Name("file%d", i), absolute_history[i], "", sizeof(absolute_history[i]));
fluid_prefs.get(name, absolute_history[i], "", sizeof(absolute_history[i]));
if (absolute_history[i][0]) { if (absolute_history[i][0]) {
// Make a relative version of the filename for the menu... // Make a relative version of the filename for the menu...
fl_filename_relative(relative_history[i], sizeof(relative_history[i]), fl_filename_relative(relative_history[i], sizeof(relative_history[i]),
@@ -488,7 +486,6 @@ void load_history() {
// Update file history from preferences... // Update file history from preferences...
void update_history(const char *filename) { void update_history(const char *filename) {
int i; // Looping var int i; // Looping var
char name[32]; // Variable name
char absolute[1024]; char absolute[1024];
fl_filename_absolute(absolute, sizeof(absolute), filename); fl_filename_absolute(absolute, sizeof(absolute), filename);
@@ -519,8 +516,7 @@ void update_history(const char *filename) {
// Update the menu items as needed... // Update the menu items as needed...
for (i = 0; i < 10; i ++) { for (i = 0; i < 10; i ++) {
sprintf(name, "file%d", i); fluid_prefs.set( Fl_Preferences::Name("file%d", i), absolute_history[i]);
fluid_prefs.set(name, absolute_history[i]);
if (absolute_history[i][0]) Main_Menu[i + 4].flags = 0; if (absolute_history[i][0]) Main_Menu[i + 4].flags = 0;
else Main_Menu[i + 4].flags = FL_MENU_INVISIBLE; else Main_Menu[i + 4].flags = FL_MENU_INVISIBLE;
} }
@@ -618,5 +614,5 @@ int main(int argc,char **argv) {
} }
// //
// End of "$Id: fluid.cxx,v 1.15.2.13.2.15 2002/04/30 18:11:49 easysw Exp $". // End of "$Id: fluid.cxx,v 1.15.2.13.2.16 2002/04/30 22:25:18 matthiaswm Exp $".
// //
+163 -16
View File
@@ -1,5 +1,5 @@
// //
// "$Id: Fl_Preferences.cxx,v 1.1.2.7 2002/04/30 18:11:49 easysw Exp $" // "$Id: Fl_Preferences.cxx,v 1.1.2.8 2002/04/30 22:25:18 matthiaswm Exp $"
// //
// Preferences methods for the Fast Light Tool Kit (FLTK). // Preferences methods for the Fast Light Tool Kit (FLTK).
// //
@@ -48,10 +48,10 @@ char Fl_Preferences::nameBuffer[];
/** /**
* create the initial preferences base * create the initial preferences base
* i root: machine or user preferences * - root: machine or user preferences
* i vendor: unique identification of author or vendor of application * - vendor: unique identification of author or vendor of application
* Must be a valid directory name. * Must be a valid directory name.
* i application: vendor unique application name, i.e. "PreferencesTest" * - application: vendor unique application name, i.e. "PreferencesTest"
* multiple preferences files can be created per application. * multiple preferences files can be created per application.
* Must be a valid file name. * Must be a valid file name.
* example: Fl_Preferences base( Fl_Preferences::USER, "fltk.org", "test01"); * example: Fl_Preferences base( Fl_Preferences::USER, "fltk.org", "test01");
@@ -65,8 +65,8 @@ Fl_Preferences::Fl_Preferences( enum Root root, const char *vendor, const char *
/** /**
* create a Preferences node in relation to a parent node for reading and writing * create a Preferences node in relation to a parent node for reading and writing
* i parent: base name for group * - parent: base name for group
* i group: group name (can contain '/' seperated group names) * - group: group name (can contain '/' seperated group names)
* example: Fl_Preferences colors( base, "setup/colors" ); * example: Fl_Preferences colors( base, "setup/colors" );
*/ */
Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, const char *key ) Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, const char *key )
@@ -78,8 +78,8 @@ Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, const char *key )
/** /**
* create a Preferences node in relation to a parent node for reading and writing * create a Preferences node in relation to a parent node for reading and writing
* i parent: base name for group * - parent: base name for group
* i group: group name (can contain '/' seperated group names) * - group: group name (can contain '/' seperated group names)
* example: Fl_Preferences colors( base, "setup/colors" ); * example: Fl_Preferences colors( base, "setup/colors" );
*/ */
Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, const char *key ) Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, const char *key )
@@ -311,9 +311,8 @@ static char *decodeText( const char *src )
/** /**
* read a text entry from the group * read a text entry from the group
* - the maximum size for text plus entry name is 2046 bytes plus the trailling 0 * the text will be moved into the given text buffer
* - the text must not contain special characters * text will be clipped to the buffer size
* the text will be movet into the given text buffer
*/ */
char Fl_Preferences::get( const char *key, char *text, const char *defaultValue, int maxSize ) char Fl_Preferences::get( const char *key, char *text, const char *defaultValue, int maxSize )
{ {
@@ -327,16 +326,25 @@ char Fl_Preferences::get( const char *key, char *text, const char *defaultValue,
return 1; return 1;
} }
if ( !v ) v = defaultValue; if ( !v ) v = defaultValue;
if ( v )
{
int vLen = strlen( v );
if ( vLen >= maxSize )
{
strncpy( text, v, maxSize ); strncpy( text, v, maxSize );
if ( (int)strlen(v) >= maxSize ) text[maxSize] = 0; text[maxSize] = 0;
}
else
strcpy( text, v );
}
else
text = 0;
return ( v != defaultValue ); return ( v != defaultValue );
} }
/** /**
* read a text entry from the group * read a text entry from the group
* - the maximum size for text plus entry name is 2046 bytes plus the trailling 0
* - the text must not contain special characters (no \n or \r, "quotes" are OK)
* 'text' will be changed to point to a new text buffer * 'text' will be changed to point to a new text buffer
* the text buffer must be deleted with 'free(text)' by the user. * the text buffer must be deleted with 'free(text)' by the user.
*/ */
@@ -349,7 +357,10 @@ char Fl_Preferences::get( const char *key, char *&text, const char *defaultValue
return 1; return 1;
} }
if ( !v ) v = defaultValue; if ( !v ) v = defaultValue;
if ( v )
text = strdup( v ); text = strdup( v );
else
text = 0;
return ( v != defaultValue ); return ( v != defaultValue );
} }
@@ -385,6 +396,97 @@ char Fl_Preferences::set( const char *key, const char *text )
} }
// convert a hex string to binary data
static void *decodeHex( const char *src, int &size )
{
size = strlen( src )/2;
unsigned char *data = (unsigned char*)malloc( size ), *d = data;
const char *s = src;
int i;
for ( i=size; i>0; i-- )
{
unsigned char v = 0;
char x = tolower(*s++);
if ( x >= 'a' ) v = x-'a'+10; else v = x-'0';
v = v<<4;
x = tolower(*s++);
if ( x >= 'a' ) v += x-'a'+10; else v += x-'0';
*d++ = v;
}
return (void*)data;
}
/**
* read a binary entry from the group
* the data will be moved into the given destination buffer
* data will be clipped to the buffer size
*/
char Fl_Preferences::get( const char *key, void *data, const void *defaultValue, int defaultSize, int maxSize )
{
const char *v = node->get( key );
if ( v )
{
int size;
void *w = decodeHex( v, size );
memmove( data, w, size>maxSize?maxSize:size );
free( w );
return 1;
}
if ( defaultValue )
memmove( data, defaultValue, defaultSize>maxSize?maxSize:defaultSize );
return 0;
}
/**
* read a binary entry from the group
* 'data' will be changed to point to a new data buffer
* the data buffer must be deleted with 'free(data)' by the user.
*/
char Fl_Preferences::get( const char *key, void *&data, const void *defaultValue, int defaultSize )
{
const char *v = node->get( key );
if ( v )
{
int size;
data = decodeHex( v, size );
return 1;
}
if ( defaultValue )
{
data = (void*)malloc( defaultSize );
memmove( data, defaultValue, defaultSize );
}
else
data = 0;
return 0;
}
/**
* set an entry (name/value pair)
*/
char Fl_Preferences::set( const char *key, const void *data, int size )
{
char *buffer = (char*)malloc( size*2+1 ), *d = buffer;;
unsigned char *s = (unsigned char*)data;
for ( ; size>0; size-- )
{
static char lu[] = "0123456789abcdef";
unsigned char v = *s++;
*d++ = lu[v>>4];
*d++ = lu[v&0xf];
}
*d = 0;
node->set( key, buffer );
free( buffer );
return 1;
}
/** /**
* return the size of the value part of an entry * return the size of the value part of an entry
*/ */
@@ -418,7 +520,7 @@ char Fl_Preferences::getUserdataPath( char *path, int pathlen )
/** /**
* write all preferences to disk * write all preferences to disk
* - this function works only with the base preference group * - this function works only with the base preference group
* - this function is rarely used as deleting the base preferences does that automatically * - this function is rarely used as deleting the base preferences flushes automatically
*/ */
void Fl_Preferences::flush() void Fl_Preferences::flush()
{ {
@@ -426,6 +528,51 @@ void Fl_Preferences::flush()
rootNode->write(); rootNode->write();
} }
//-----------------------------------------------------------------------------
// helper class to create dynamic group and entry names on the fly
//
/**
* create a group name or entry name on the fly
* - this version creates a simple unsigned integer as an entry name
* example:
* int n, i;
* Fl_Preferences prev( appPrefs, "PreviousFiles" );
* prev.get( "n", 0 );
* for ( i=0; i<n; i++ )
* prev.get( Fl_Preferences::Name(i), prevFile[i], "" );
*/
Fl_Preferences::Name::Name( unsigned int n )
{
data_ = (char*)malloc(20);
itoa( n, data_, 10 );
}
/**
* create a group name or entry name on the fly
* - this version creates entry names as in 'printf'
* example:
* int n, i;
* Fl_Preferences prefs( USER, "matthiasm.com", "test" );
* prev.get( "nFiles", 0 );
* for ( i=0; i<n; i++ )
* prev.get( Fl_Preferences::Name( "File%d", i ), prevFile[i], "" );
*/
Fl_Preferences::Name::Name( const char *format, ... )
{
data_ = (char*)malloc(1024);
va_list args;
va_start(args, format);
vsnprintf(data_, 1024, format, args);
va_end(args);
}
// delete the name
Fl_Preferences::Name::~Name()
{
free(data_);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// internal methods, do not modify or use as they will change without notice // internal methods, do not modify or use as they will change without notice
// //
@@ -937,5 +1084,5 @@ char Fl_Preferences::Node::remove()
// //
// End of "$Id: Fl_Preferences.cxx,v 1.1.2.7 2002/04/30 18:11:49 easysw Exp $". // End of "$Id: Fl_Preferences.cxx,v 1.1.2.8 2002/04/30 22:25:18 matthiaswm Exp $".
// //
+23 -1
View File
@@ -172,7 +172,7 @@ double doubleValue;
Fl_Preferences app( Fl_Preferences::USER, "fltk.org", "test/preferences" ); Fl_Preferences app( Fl_Preferences::USER, "fltk.org", "test/preferences" );
char path[ FL_PATH_MAX ]; char path[ FL_PATH_MAX ];
app.getUserdataPath( path, sizeof(path) ); app.getUserdataPath( path );
Fl_Preferences bed( app, "Bed" ); Fl_Preferences bed( app, "Bed" );
bed.get( "alarm", buffer, "8:00", 80 ); bed.get( "alarm", buffer, "8:00", 80 );
@@ -222,6 +222,21 @@ Fl_Preferences app( Fl_Preferences::USER, "fltk.org", "test/preferences" );
if ( flexBuffer ) free( flexBuffer ); if ( flexBuffer ) free( flexBuffer );
eat.get( "foo", buffer, "bar", 80 ); eat.get( "foo", buffer, "bar", 80 );
/** sample code only:
Fl_Preferences prev( app, "PreviousStarts" );
{
int i, n;
prev.get( "n", n, 0 );
for ( i=0; i<n; i++ )
prev.get( Fl_Preferences::Name( i ), flexBuffer, "" );
}
unsigned int hex;
eat.get( "binFoo", (void*)&hex, 0, 0, sizeof( unsigned int ) );
void *data;
eat.get( "binFoo2", data, 0, 0 );
**/
} }
void writePrefs() { void writePrefs() {
@@ -259,4 +274,11 @@ void writePrefs() {
eat.set( "foo", "bar\nfly\rBackslash: \\ and bell: \007 and delete: \177\n" ); eat.set( "foo", "bar\nfly\rBackslash: \\ and bell: \007 and delete: \177\n" );
eat.set( Fl_Preferences::Name( 3 ), "Test3" );
/** sample code only:
unsigned int hex = 0x2387efcd;
eat.set( "binFoo", (void*)&hex, sizeof( unsigned int ) );
eat.set( "binFoo2", (void*)&writePrefs, 1024 );
**/
} }