Drizzled Public API Documentation

uuid.h
00001 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  * Copyright (C) 2010 Brian Aker
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are met:
00009  *     * Redistributions of source code must retain the above copyright
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright
00012  *       notice, this list of conditions and the following disclaimer in the
00013  *       documentation and/or other materials provided with the distribution.
00014  *     * Neither the name of the <organization> nor the
00015  *       names of its contributors may be used to endorse or promote products
00016  *       derived from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00019  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00020  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00021  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
00022  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00024  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00025  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00026  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00027  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  *
00029  */
00030 
00031 // I looked at code which also had this Copyright header.
00032 
00033 /*
00034  * Copyright (C) 1996, 1997 Theodore Ts'o.
00035  *
00036  * %Begin-Header%
00037  * Redistribution and use in source and binary forms, with or without
00038  * modification, are permitted provided that the following conditions
00039  * are met:
00040  * 1. Redistributions of source code must retain the above copyright
00041  *    notice, and the entire permission notice in its entirety,
00042  *    including the disclaimer of warranties.
00043  * 2. Redistributions in binary form must reproduce the above copyright
00044  *    notice, this list of conditions and the following disclaimer in the
00045  *    documentation and/or other materials provided with the distribution.
00046  * 3. The name of the author may not be used to endorse or promote
00047  *    products derived from this software without specific prior
00048  *    written permission.
00049  *
00050  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
00051  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00052  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
00053  * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
00054  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00055  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00056  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
00057  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00058  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00059  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00060  * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
00061  * DAMAGE.
00062  * %End-Header%
00063  */
00064 
00065 #pragma once
00066 
00067 #include <cstdio>
00068 #include <iosfwd>
00069 
00070 namespace drizzled {
00071 namespace type {
00072 
00073 class Uuid 
00074 {
00075   uint32_t  time_low;
00076   uint16_t  time_mid;
00077   uint16_t  time_hi_and_version;
00078   uint16_t  clock_seq;
00079   uint8_t node[6];
00080 
00081 public:
00082 
00083   Uuid() :
00084     time_low(0),
00085     time_mid(0),
00086     time_hi_and_version(0),
00087     clock_seq(0)
00088   {
00089     node[0]= node[1]= node[2]= node[3]= node[4]= node[5]= 0;
00090   }
00091 
00092   void unpack(const unsigned char *in)
00093   {
00094     const uint8_t *ptr= reinterpret_cast<const uint8_t *>(in);
00095     uint32_t tmp;
00096 
00097     tmp= *ptr++;
00098     tmp= (tmp << 8) | *ptr++;
00099     tmp= (tmp << 8) | *ptr++;
00100     tmp= (tmp << 8) | *ptr++;
00101     time_low= tmp;
00102 
00103     tmp= *ptr++;
00104     tmp= (tmp << 8) | *ptr++;
00105     time_mid= tmp;
00106 
00107     tmp= *ptr++;
00108     tmp= (tmp << 8) | *ptr++;
00109     time_hi_and_version = tmp;
00110 
00111     tmp= *ptr++;
00112     tmp= (tmp << 8) | *ptr++;
00113     clock_seq= tmp;
00114 
00115     memcpy(node, ptr, 6);
00116   }
00117 
00118   void pack(unsigned char *out)
00119   {
00120     uint32_t  tmp;
00121 
00122     tmp = time_low;
00123     out[3] = (unsigned char) tmp;
00124     tmp >>= 8;
00125     out[2] = (unsigned char) tmp;
00126     tmp >>= 8;
00127     out[1] = (unsigned char) tmp;
00128     tmp >>= 8;
00129     out[0] = (unsigned char) tmp;
00130 
00131     tmp = time_mid;
00132     out[5] = (unsigned char) tmp;
00133     tmp >>= 8;
00134     out[4] = (unsigned char) tmp;
00135 
00136     tmp = time_hi_and_version;
00137     out[7] = (unsigned char) tmp;
00138     tmp >>= 8;
00139     out[6] = (unsigned char) tmp;
00140 
00141     tmp = clock_seq;
00142     out[9] = (unsigned char) tmp;
00143     tmp >>= 8;
00144     out[8] = (unsigned char) tmp;
00145 
00146     memcpy(out+10, node, 6);
00147   }
00148 
00149   bool parse(const char *in)
00150   {
00151     const char  *cp;
00152     char buf[3];
00153     size_t i;
00154 
00155     for (i= 0, cp= in; i < DISPLAY_LENGTH; i++, cp++)
00156     {
00157       if ((i == 8) || (i == 13) || (i == 18) || (i == 23))
00158       {
00159         if (*cp == '-')
00160         {
00161           continue;
00162         }
00163         else
00164         {
00165           return true;
00166         }
00167       }
00168 
00169       if (not isxdigit(*cp))
00170         return true;
00171     }
00172 
00173     time_low= strtoul(in, NULL, 16);
00174     time_mid= strtoul(in+9, NULL, 16);
00175     time_hi_and_version= strtoul(in+14, NULL, 16);
00176     clock_seq= strtoul(in+19, NULL, 16);
00177     cp= in+24;
00178     buf[2]= 0;
00179 
00180     for (i= 0; i < 6; i++)
00181     {
00182       buf[0]= *cp++;
00183       buf[1]= *cp++;
00184       node[i]= strtoul(buf, NULL, 16);
00185     }
00186 
00187     return false;
00188   }
00189 
00190   void unparse(char *out) const
00191   {
00192     snprintf(out, DISPLAY_BUFFER_LENGTH, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
00193             time_low,
00194             time_mid,
00195             time_hi_and_version,
00196             clock_seq >> 8,
00197             clock_seq & 0xFF,
00198             node[0],
00199             node[1],
00200             node[2],
00201             node[3],
00202             node[4],
00203             node[5]);
00204   }
00205 
00206   void time(timeval& ret_val) const
00207   {
00208     uint32_t high;
00209     uint64_t clock_reg;
00210 
00211     high= time_mid | ((time_hi_and_version & 0xFFF) << 16);
00212     clock_reg= time_low | ((uint64_t) high << 32);
00213 
00214     clock_reg -= (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
00215     ret_val.tv_sec = clock_reg / 10000000;
00216     ret_val.tv_usec = (clock_reg % 10000000) / 10;
00217   }
00218   bool isTimeType() const
00219   {
00220     return ((time_hi_and_version >> 12) & 0xF) == 1; 
00221   }
00222 
00223   static const size_t LENGTH= 16;
00224   static const size_t DISPLAY_LENGTH= 36;
00225   static const size_t DISPLAY_BUFFER_LENGTH= DISPLAY_LENGTH+1;
00226 };
00227 
00228 } /* namespace type */
00229 } /* namespace drizzled */
00230 
00231