diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2002-04-30 22:25:18 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2002-04-30 22:25:18 +0000 |
| commit | adb6fc4eeb0d73481a1368531f8593c485fd5c91 (patch) | |
| tree | 0a303c6ab9d6b01cc7f3cb1f2484acb0131028f3 | |
| parent | 8972642109ea98fd71bc83d7ffc0167958ae22bf (diff) | |
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
| -rw-r--r-- | FL/Fl_Preferences.H | 23 | ||||
| -rw-r--r-- | documentation/Fl_Preferences.html | 39 | ||||
| -rw-r--r-- | fluid/fluid.cxx | 12 | ||||
| -rw-r--r-- | src/Fl_Preferences.cxx | 183 | ||||
| -rw-r--r-- | test/preferences.cxx | 24 |
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> +<b>Fl_Preferences</b></a></H4> </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 &value, int defaultValue)<BR> -int get(const char *entry, int &value, int defaultValue)<BR> -int get(const char *entry, float &value, float defaultValue)<BR> -int get(const char *entry, double &value, double defaultValue ) -int get(const char *entry, char *&value, const char *defaultValue)<BR> -int get(const char *entry, char *value, const char *defaultValue, +<H4><a name="Fl_Preferences.get">int get(const char *entry, int &value, int defaultValue)<BR> +int get(const char *entry, int &value, int defaultValue)<BR> +int get(const char *entry, float &value, float defaultValue)<BR> +int get(const char *entry, double &value, double defaultValue )<BR> +int get(const char *entry, char *&text, const char *defaultValue)<BR> +int get(const char *entry, char *text, const char *defaultValue, int maxSize)<BR> +int get(const char *entry, void *&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 -*&value</tt>' form is used, the resulting text must be freed -with '<tt>free(value)</tt>'. +*&text</tt>' or '<tt>void *&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 ); + **/ } |
