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 <iostream>
00069 
00070 namespace drizzled
00071 {
00072 namespace type
00073 {
00074 
00075 class Uuid {
00076   uint32_t  time_low;
00077   uint16_t  time_mid;
00078   uint16_t  time_hi_and_version;
00079   uint16_t  clock_seq;
00080   uint8_t node[6];
00081 
00082 public:
00083 
00084   Uuid() :
00085     time_low(0),
00086     time_mid(0),
00087     time_hi_and_version(0),
00088     clock_seq(0)
00089   {
00090     node[0]= node[1]= node[2]= node[3]= node[4]= node[5]= 0;
00091   }
00092 
00093   void unpack(const unsigned char *in)
00094   {
00095     const uint8_t *ptr= reinterpret_cast<const uint8_t *>(in);
00096     uint32_t tmp;
00097 
00098     tmp= *ptr++;
00099     tmp= (tmp << 8) | *ptr++;
00100     tmp= (tmp << 8) | *ptr++;
00101     tmp= (tmp << 8) | *ptr++;
00102     time_low= tmp;
00103 
00104     tmp= *ptr++;
00105     tmp= (tmp << 8) | *ptr++;
00106     time_mid= tmp;
00107 
00108     tmp= *ptr++;
00109     tmp= (tmp << 8) | *ptr++;
00110     time_hi_and_version = tmp;
00111 
00112     tmp= *ptr++;
00113     tmp= (tmp << 8) | *ptr++;
00114     clock_seq= tmp;
00115 
00116     memcpy(node, ptr, 6);
00117   }
00118 
00119   void pack(unsigned char *out)
00120   {
00121     uint32_t  tmp;
00122 
00123     tmp = time_low;
00124     out[3] = (unsigned char) tmp;
00125     tmp >>= 8;
00126     out[2] = (unsigned char) tmp;
00127     tmp >>= 8;
00128     out[1] = (unsigned char) tmp;
00129     tmp >>= 8;
00130     out[0] = (unsigned char) tmp;
00131 
00132     tmp = time_mid;
00133     out[5] = (unsigned char) tmp;
00134     tmp >>= 8;
00135     out[4] = (unsigned char) tmp;
00136 
00137     tmp = time_hi_and_version;
00138     out[7] = (unsigned char) tmp;
00139     tmp >>= 8;
00140     out[6] = (unsigned char) tmp;
00141 
00142     tmp = clock_seq;
00143     out[9] = (unsigned char) tmp;
00144     tmp >>= 8;
00145     out[8] = (unsigned char) tmp;
00146 
00147     memcpy(out+10, node, 6);
00148   }
00149 
00150   bool parse(const char *in)
00151   {
00152     const char  *cp;
00153     char buf[3];
00154     size_t i;
00155 
00156     for (i= 0, cp= in; i < DISPLAY_LENGTH; i++, cp++)
00157     {
00158       if ((i == 8) || (i == 13) || (i == 18) || (i == 23))
00159       {
00160         if (*cp == '-')
00161         {
00162           continue;
00163         }
00164         else
00165         {
00166           return true;
00167         }
00168       }
00169 
00170       if (not isxdigit(*cp))
00171         return true;
00172     }
00173 
00174     time_low= strtoul(in, NULL, 16);
00175     time_mid= strtoul(in+9, NULL, 16);
00176     time_hi_and_version= strtoul(in+14, NULL, 16);
00177     clock_seq= strtoul(in+19, NULL, 16);
00178     cp= in+24;
00179     buf[2]= 0;
00180 
00181     for (i= 0; i < 6; i++)
00182     {
00183       buf[0]= *cp++;
00184       buf[1]= *cp++;
00185       node[i]= strtoul(buf, NULL, 16);
00186     }
00187 
00188     return false;
00189   }
00190 
00191   void unparse(char *out)
00192   {
00193     snprintf(out, DISPLAY_BUFFER_LENGTH, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
00194             time_low,
00195             time_mid,
00196             time_hi_and_version,
00197             clock_seq >> 8,
00198             clock_seq & 0xFF,
00199             node[0],
00200             node[1],
00201             node[2],
00202             node[3],
00203             node[4],
00204             node[5]);
00205   }
00206 
00207   void time(struct timeval ret_val)
00208   {
00209     uint32_t high;
00210     uint64_t clock_reg;
00211 
00212     high= time_mid | ((time_hi_and_version & 0xFFF) << 16);
00213     clock_reg= time_low | ((uint64_t) high << 32);
00214 
00215     clock_reg -= (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
00216     ret_val.tv_sec = clock_reg / 10000000;
00217     ret_val.tv_usec = (clock_reg % 10000000) / 10;
00218   }
00219 
00220   bool isTimeType()
00221   {
00222     return ((time_hi_and_version >> 12) & 0xF) == 1 ? true : false; 
00223   }
00224 
00225   static const size_t LENGTH= 16;
00226   static const size_t DISPLAY_LENGTH= 36;
00227   static const size_t DISPLAY_BUFFER_LENGTH= DISPLAY_LENGTH+1;
00228 };
00229 
00230 } /* namespace type */
00231 } /* namespace drizzled */
00232 
00233