summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2009-12-27 20:14:04 +0000
committerMatthias Melcher <fltk@matthiasm.com>2009-12-27 20:14:04 +0000
commit9048b4b8950c95df9255e53c101b863037e56ecf (patch)
treec9dbcf55bedfcd1ed3801444e4d74e7105ace01d /src
parent38c15442a418a238462b1207adb681cf992edab7 (diff)
Improved Preferences database. Branches can now be accessed by index. Added UUID generation (better versions needed for Unix and MSWin!). Added access to group name and path
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6983 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Preferences.cxx146
1 files changed, 139 insertions, 7 deletions
diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx
index a24cf85d5..866c90cae 100644
--- a/src/Fl_Preferences.cxx
+++ b/src/Fl_Preferences.cxx
@@ -36,6 +36,7 @@
#include <FL/fl_utf8.h>
#include "flstring.h"
#include <sys/stat.h>
+#include <time.h>
#if defined(WIN32) && !defined(__CYGWIN__)
# include <direct.h>
@@ -52,10 +53,88 @@
#endif
#ifdef WIN32
-#include <windows.h>
+# include <windows.h>
+#else
+# include <sys/time.h>
#endif // WIN32
char Fl_Preferences::nameBuffer[128];
+char Fl_Preferences::uuidBuffer[40];
+
+/**
+ * Returns a UUID as generated by the system.
+ *
+ * A UUID is a "universally unique identifier" which is commonly used in
+ * configuration files to create identities. A UUID in ASCII looks like this:
+ * <tt>937C4900-51AA-4C11-8DD3-7AB59944F03E</tt>. It has always 36 bytes plus
+ * a trailing zero.
+ *
+ * \return a pointer to a static buffer containing the new UUID in ASCII format.
+ * The buffer is overwritten during every call to this function!
+ */
+const char *Fl_Preferences::newUUID()
+{
+#ifdef __APPLE__
+ CFUUIDRef theUUID = CFUUIDCreate(NULL);
+ CFUUIDBytes b = CFUUIDGetUUIDBytes(theUUID);
+ sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ b.byte0, b.byte1, b.byte2, b.byte3, b.byte4, b.byte5, b.byte6, b.byte7,
+ b.byte8, b.byte9, b.byte10, b.byte11, b.byte12, b.byte13, b.byte14, b.byte15);
+ CFRelease(theUUID);
+#elif defined (WIN32)
+#warning MSWindows implementation missing!
+ // UUID b;
+ // UuidCreate(&b);
+ unsigned char b[16];
+ time_t t = time(0); // first 4 byte
+ b[0] = (unsigned char)t;
+ b[1] = (unsigned char)(t>>8);
+ b[2] = (unsigned char)(t>>16);
+ b[3] = (unsigned char)(t>>24);
+ int r = rand(); // four more bytes
+ b[4] = (unsigned char)r;
+ b[5] = (unsigned char)(r>>8);
+ b[6] = (unsigned char)(r>>16);
+ b[7] = (unsigned char)(r>>24);
+ unsigned int a = (unsigned int)&t; // four more bytes
+ b[8] = (unsigned char)a;
+ b[9] = (unsigned char)(a>>8);
+ b[10] = (unsigned char)(a>>16);
+ b[11] = (unsigned char)(a>>24);
+ char name[80]; // last four bytes
+ gethostname(name, 79);
+ memcpy(b+12, name, 4);
+ sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
+ b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]);
+#else
+#warning Unix implementation missing!
+ // #include <uuid/uuid.h>
+ // void uuid_generate(uuid_t out);
+ unsigned char b[16];
+ time_t t = time(0); // first 4 byte
+ b[0] = (unsigned char)t;
+ b[1] = (unsigned char)(t>>8);
+ b[2] = (unsigned char)(t>>16);
+ b[3] = (unsigned char)(t>>24);
+ int r = rand(); // four more bytes
+ b[4] = (unsigned char)r;
+ b[5] = (unsigned char)(r>>8);
+ b[6] = (unsigned char)(r>>16);
+ b[7] = (unsigned char)(r>>24);
+ unsigned int a = (unsigned int)&t; // four more bytes
+ b[8] = (unsigned char)a;
+ b[9] = (unsigned char)(a>>8);
+ b[10] = (unsigned char)(a>>16);
+ b[11] = (unsigned char)(a>>24);
+ char name[80]; // last four bytes
+ gethostname(name, 79);
+ memcpy(b+12, name, 4);
+ sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
+ b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]);
+#endif
+}
/**
@@ -133,6 +212,41 @@ Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, const char *group )
/**
+ \brief Open a child group using a given index.
+
+ Use the \p groupIndex argument to find the group that you would like to access.
+ If the given index is invalid (negative or too high), a new group is created
+ with a UUID as a name.
+
+ \param[in] parent reference object for the new group
+ \param[in] groupIndex zero based index into child groups
+ */
+Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, int groupIndex )
+{
+ rootNode = parent.rootNode;
+ if (groupIndex<0 || groupIndex>=parent.groups()) {
+ node = parent.node->addChild( newUUID() );
+ } else {
+ node = parent.node->childNode( groupIndex );
+ }
+}
+
+
+/**
+ \see Fl_Preferences( Fl_Preferences&, int groupIndex )
+ */
+Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, int groupIndex )
+{
+ rootNode = parent->rootNode;
+ if (groupIndex<0 || groupIndex>=parent->groups()) {
+ node = parent->node->addChild( newUUID() );
+ } else {
+ node = parent->node->childNode( groupIndex );
+ }
+}
+
+
+/**
The destructor removes allocated resources. When used on the
\em base preferences group, the destructor flushes all
changes to the preferences file and deletes all internal
@@ -1348,20 +1462,38 @@ int Fl_Preferences::Node::nChildren()
return cnt;
}
+// return the node name
+const char *Fl_Preferences::Node::name()
+{
+ if ( path_ )
+ {
+ char *r = strrchr( path_, '/' );
+ return r ? r+1 : path_ ;
+ } else {
+ return 0L ;
+ }
+}
+
// return the n'th child node
const char *Fl_Preferences::Node::child( int ix )
{
+ Node *nd = childNode( ix );
+ if ( nd )
+ return nd->name();
+ else
+ return 0L ;
+}
+
+// return the n'th child node
+Fl_Preferences::Node *Fl_Preferences::Node::childNode( int ix )
+{
Node *nd;
for ( nd = child_; nd; nd = nd->next_ )
{
if ( !ix-- ) break;
+ if ( !nd ) break;
}
- if ( nd && nd->path_ )
- {
- char *r = strrchr( nd->path_, '/' );
- return r ? r+1 : nd->path_ ;
- }
- return 0L ;
+ return nd;
}
// remove myself from the list and delete me (and all children)