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

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).
//
@ -33,10 +33,6 @@
#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
@ -69,7 +65,7 @@ public:
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, 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, 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, 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, void *&value, const char *defaultValue );
// 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 );
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 char getUserdataPath( char *path, int pathlen );
@ -88,7 +84,14 @@ public:
// FL_EXPORT char export( const char *filename, enum Type fileFormat );
// 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:
@ -154,5 +157,5 @@ private:
#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 $".
//

View File

@ -10,7 +10,7 @@
<h3>Class Hierarchy</h3>
<ul><pre>
<b>Fl_Preferences</a></H4>&nbsp;
<b>Fl_Preferences</b></a></H4>&nbsp;
</pre></ul>
<h3>Include Files</h3>
@ -65,6 +65,7 @@ method.
<li><a href="#Fl_Preferences.groups">groups</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.Name">Name</a></li>
</ul>
@ -133,19 +134,21 @@ deleting the base preferences flushes automatically.
that is usable for application data beyond what is covered by
<tt>Fl_Preferences</tt>.
<H4><a name="Fl_Preferences.get">int get(const char *entry, int &amp;value,&nbsp;&nbsp; int defaultValue)<BR>
int get(const char *entry, int &amp;value,&nbsp;&nbsp;&nbsp; int defaultValue)<BR>
int get(const char *entry, float &amp;value,&nbsp; float defaultValue)<BR>
int get(const char *entry, double &amp;value, double defaultValue )
int get(const char *entry, char *&amp;value,&nbsp; const char *defaultValue)<BR>
int get(const char *entry, char *value,&nbsp;&nbsp; const char *defaultValue,
<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, int defaultValue)<BR>
int get(const char *entry, float &amp;value, float defaultValue)<BR>
int get(const char *entry, double &amp;value, double defaultValue )<BR>
int get(const char *entry, char *&amp;text, const char *defaultValue)<BR>
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>
<P>Reads an entry from the group. A default value must be
supplied. The return value indicates if the value was available
(non-zero) or the default was used (0). If the '<tt>char
*&amp;value</tt>' form is used, the resulting text must be freed
with '<tt>free(value)</tt>'.
*&amp;text</tt>' or '<tt>void *&amp;data</tt>' form is used,
the resulting data must be freed with '<tt>free(value)</tt>'.
<H4><a name="Fl_Preferences.group">const char
*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, float 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
any '\n' or '\r' characters. The return value indicates if there
<P>Sets an entry (name/value pair). The return value indicates if there
was a problem storing the data in memory. However it does not
reflect if the value was actually stored in the preferences
file.
@ -179,6 +182,18 @@ file.
<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>
</html>

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).
//
@ -468,11 +468,9 @@ void make_main_window() {
// Load file history from preferences...
void load_history() {
int i; // Looping var
char name[32]; // Variable name
for (i = 0; i < 10; i ++) {
sprintf(name, "file%d", i);
fluid_prefs.get(name, absolute_history[i], "", sizeof(absolute_history[i]));
fluid_prefs.get( Fl_Preferences::Name("file%d", i), absolute_history[i], "", sizeof(absolute_history[i]));
if (absolute_history[i][0]) {
// Make a relative version of the filename for the menu...
fl_filename_relative(relative_history[i], sizeof(relative_history[i]),
@ -488,7 +486,6 @@ void load_history() {
// Update file history from preferences...
void update_history(const char *filename) {
int i; // Looping var
char name[32]; // Variable name
char absolute[1024];
fl_filename_absolute(absolute, sizeof(absolute), filename);
@ -519,8 +516,7 @@ void update_history(const char *filename) {
// Update the menu items as needed...
for (i = 0; i < 10; i ++) {
sprintf(name, "file%d", i);
fluid_prefs.set(name, absolute_history[i]);
fluid_prefs.set( Fl_Preferences::Name("file%d", i), absolute_history[i]);
if (absolute_history[i][0]) Main_Menu[i + 4].flags = 0;
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 $".
//

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).
//
@ -48,10 +48,10 @@ char Fl_Preferences::nameBuffer[];
/**
* create the initial preferences base
* i root: machine or user preferences
* i vendor: unique identification of author or vendor of application
* - root: machine or user preferences
* - vendor: unique identification of author or vendor of application
* 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.
* Must be a valid file name.
* 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
* i parent: base name for group
* i group: group name (can contain '/' seperated group names)
* - parent: base name for group
* - group: group name (can contain '/' seperated group names)
* example: Fl_Preferences colors( base, "setup/colors" );
*/
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
* i parent: base name for group
* i group: group name (can contain '/' seperated group names)
* - parent: base name for group
* - group: group name (can contain '/' seperated group names)
* example: Fl_Preferences colors( base, "setup/colors" );
*/
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
* - the maximum size for text plus entry name is 2046 bytes plus the trailling 0
* - the text must not contain special characters
* the text will be movet into the given text buffer
* the text will be moved into the given text buffer
* text will be clipped to the buffer size
*/
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;
}
if ( !v ) v = defaultValue;
if ( v )
{
int vLen = strlen( v );
if ( vLen >= 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 );
}
/**
* 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
* 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;
}
if ( !v ) v = defaultValue;
if ( v )
text = strdup( v );
else
text = 0;
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
*/
@ -418,7 +520,7 @@ char Fl_Preferences::getUserdataPath( char *path, int pathlen )
/**
* write all preferences to disk
* - 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()
{
@ -426,6 +528,51 @@ void Fl_Preferences::flush()
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
//
@ -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 $".
//

View File

@ -172,7 +172,7 @@ double doubleValue;
Fl_Preferences app( Fl_Preferences::USER, "fltk.org", "test/preferences" );
char path[ FL_PATH_MAX ];
app.getUserdataPath( path, sizeof(path) );
app.getUserdataPath( path );
Fl_Preferences bed( app, "Bed" );
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 );
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() {
@ -259,4 +274,11 @@ void writePrefs() {
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 );
**/
}