The uuid(3) function can be used to generate UUIDs on most UNIX/Linux systems.  
Also see RFC 4122 for details on "version 3" UUIDs (which is what the uuid 
function generates), which can also be generated with code like this (from 
CUPS):

  snprintf(uuid, sizeof(uuid), "%s:%s:%d:%d", ServerName, con->servername,
           con->serverport, job->id);

  _cupsMD5Init(&md5state);
  _cupsMD5Append(&md5state, (unsigned char *)uuid, strlen(uuid));
  _cupsMD5Finish(&md5state, md5sum);

 /*
  * Format the UUID URI using the MD5 sum and job ID.
  */

  snprintf(uuid, sizeof(uuid),
           "urn:uuid:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
           "%02x%02x%02x%02x%02x%02x",
           md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5],
           (md5sum[6] & 15) | 0x30, md5sum[7], (md5sum[8] & 0x3f) | 0x40,
           md5sum[9], md5sum[10], md5sum[11], md5sum[12], md5sum[13],
           md5sum[14], md5sum[15]);


On Dec 27, 2009, at 12:14 PM, fltk-dev@easysw.com wrote:

> Author: matt
> Date: 2009-12-27 12:14:04 -0800 (Sun, 27 Dec 2009)
> New Revision: 6983
> Log:
> 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
> 
> Modified:
>   branches/branch-1.3/FL/Fl_Preferences.H
>   branches/branch-1.3/src/Fl_Preferences.cxx
> 
> Modified: branches/branch-1.3/FL/Fl_Preferences.H
> ===================================================================
> --- branches/branch-1.3/FL/Fl_Preferences.H   2009-12-27 15:23:47 UTC (rev 
> 6982)
> +++ branches/branch-1.3/FL/Fl_Preferences.H   2009-12-27 20:14:04 UTC (rev 
> 6983)
> @@ -79,13 +79,25 @@
>     SYSTEM=0,   ///< Preferences are used system-wide
>     USER        ///< Preferences apply only to the current user
>   };
> +  
> +  static const char *newUUID();
> 
>   Fl_Preferences( Root root, const char *vendor, const char *application );
>   Fl_Preferences( const char *path, const char *vendor, const char 
> *application );
>   Fl_Preferences( Fl_Preferences &parent, const char *group );
> -  Fl_Preferences( Fl_Preferences*, const char *group );
> +  Fl_Preferences( Fl_Preferences *parent, const char *group );
> +  Fl_Preferences( Fl_Preferences &parent, int groupIndex );
> +  Fl_Preferences( Fl_Preferences *parent, int groupIndex );
>   ~Fl_Preferences();
> 
> +  /** Return the name of this entry.
> +   */
> +  const char *name() { return node->name(); }
> +  
> +  /** Return the the full path to this entry.
> +   */
> +  const char *path() { return node->path(); }
> +  
>   int groups();
>   const char *group( int num_group );
>   char groupExists( const char *key );
> @@ -163,6 +175,7 @@
>   Fl_Preferences &operator=(const Fl_Preferences&);
> 
>   static char nameBuffer[128];
> +  static char uuidBuffer[40];
> 
>   class FL_EXPORT Node // a node contains a list to all its entries 
>   {          // and all means to manage the tree structure
> @@ -174,6 +187,8 @@
>     ~Node();
>     // node methods
>     int write( FILE *f );
> +    const char *name();
> +    const char *path() { return path_; }
>     Node *find( const char *path );
>     Node *search( const char *path, int offset=0 );
>     Node *addChild( const char *path );
> @@ -184,6 +199,7 @@
>     // entry methods
>     int nChildren();
>     const char *child( int ix );
> +    Node *childNode( int ix );
>     void set( const char *name, const char *value );
>     void set( const char *line );
>     void add( const char *line );
> 
> Modified: branches/branch-1.3/src/Fl_Preferences.cxx
> ===================================================================
> --- branches/branch-1.3/src/Fl_Preferences.cxx        2009-12-27 15:23:47 UTC 
> (rev 6982)
> +++ branches/branch-1.3/src/Fl_Preferences.cxx        2009-12-27 20:14:04 UTC 
> (rev 6983)
> @@ -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,12 +53,90 @@
> #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
> +}
> 
> +
> /**
>    The constructor creates a group that manages name/value pairs and
>    child groups. Groups are ready for reading and writing at any time.
> @@ -133,6 +212,41 @@
> 
> 
> /**
> + \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 @@
>   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)
> 
> _______________________________________________
> fltk-commit mailing list
> fltk-com...@easysw.com
> http://lists.easysw.com/mailman/listinfo/fltk-commit

________________________________________
Michael Sweet, Easy Software Products



_______________________________________________
fltk-dev mailing list
fltk-dev@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to