summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/Fl_Preferences.H23
-rw-r--r--documentation/Fl_Preferences.html39
-rw-r--r--fluid/fluid.cxx12
-rw-r--r--src/Fl_Preferences.cxx183
-rw-r--r--test/preferences.cxx24
5 files changed, 232 insertions, 49 deletions
diff --git a/FL/Fl_Preferences.H b/FL/Fl_Preferences.H
index 8f2dfdfaf..d42e9a72d 100644
--- a/FL/Fl_Preferences.H
+++ b/FL/Fl_Preferences.H
@@ -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 $".
//
diff --git a/documentation/Fl_Preferences.html b/documentation/Fl_Preferences.html
index 966cf08e2..b5a30623c 100644
--- a/documentation/Fl_Preferences.html
+++ b/documentation/Fl_Preferences.html
@@ -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>
diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx
index 1184a5d24..c66d07d24 100644
--- a/fluid/fluid.cxx
+++ b/fluid/fluid.cxx
@@ -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 $".
//
diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx
index 8d1ded130..d12c3cb69 100644
--- a/src/Fl_Preferences.cxx
+++ b/src/Fl_Preferences.cxx
@@ -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;
- strncpy( text, v, maxSize );
- if ( (int)strlen(v) >= maxSize ) text[maxSize] = 0;
+ if ( v )
+ {
+ int vLen = strlen( v );
+ if ( vLen >= maxSize )
+ {
+ strncpy( text, v, maxSize );
+ 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;
- text = strdup( v );
+ 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()
{
@@ -427,6 +529,51 @@ void Fl_Preferences::flush()
}
//-----------------------------------------------------------------------------
+// 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 $".
//
diff --git a/test/preferences.cxx b/test/preferences.cxx
index 6943ffd5f..237422f78 100644
--- a/test/preferences.cxx
+++ b/test/preferences.cxx
@@ -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 );
+ **/
}