Data-UUID

 view release on metacpan or  search on metacpan

UUID.xs  view on Meta::CPAN

   rcount = call_method("digest", G_SCALAR);
   SPAGAIN;

   if ( rcount != 1 )
       croak("Digest::MD5->digest hasn't returned a scalar");

   retval = POPs;
   tmp = SvPV(retval, len);
   if ( len != 16 )
       croak("Digest::MD5->digest returned not 16 bytes");

   memcpy(hash, tmp, len);

   PUTBACK;
   FREETMPS;
   LEAVE;
};

MODULE = Data::UUID		PACKAGE = Data::UUID		

PROTOTYPES: DISABLE

uuid_context_t*
new(class)
PREINIT:
   FILE          *fd;
   unsigned char  seed[16];
   perl_uuid_time_t    timestamp;
   mode_t         mask;
   UV             one = 1;
CODE:
   RETVAL = (uuid_context_t *)PerlMemShared_malloc(sizeof(uuid_context_t));

      get_random_info(seed);
      seed[0] |= 0x80;
      memcpy(&(RETVAL->nodeid), seed, sizeof(uuid_node_t));

   errno = 0;
#if DU_THREADSAFE
   MUTEX_LOCK(&instances_mutex);
   ptable_store(instances, RETVAL, INT2PTR(void *, one));
   MUTEX_UNLOCK(&instances_mutex);
#endif
OUTPUT:
   RETVAL

void
create(self)
   uuid_context_t *self;
ALIAS:
   Data::UUID::create_bin = F_BIN
   Data::UUID::create_str = F_STR
   Data::UUID::create_hex = F_HEX
   Data::UUID::create_b64 = F_B64
PREINIT:
   perl_uuid_time_t  timestamp;
   unsigned16   clockseq;
   perl_uuid_t       uuid;
   FILE        *fd;
   mode_t       mask;
PPCODE:
   clockseq = self->state.cs;
   get_current_time(&timestamp);
   if ( self->state.ts == I64(0) ||
      memcmp(&(self->nodeid), &(self->state.node), sizeof(uuid_node_t)))
      clockseq = true_random();
   else if (timestamp <= self->state.ts)
      clockseq++;

   format_uuid_v1(&uuid, clockseq, timestamp, self->nodeid);
   self->state.node = self->nodeid;
   self->state.ts   = timestamp;
   self->state.cs   = clockseq;
   ST(0) = make_ret(uuid, ix);
   XSRETURN(1);

void
create_from_name(self,nsid,name)
   uuid_context_t *self;
   perl_uuid_t    *nsid;
   SV             *name;
ALIAS:
   Data::UUID::create_from_name_bin = F_BIN
   Data::UUID::create_from_name_str = F_STR
   Data::UUID::create_from_name_hex = F_HEX
   Data::UUID::create_from_name_b64 = F_B64
PREINIT:
   SV *ctx;
   unsigned char hash[16];
   perl_uuid_t        net_nsid; 
   perl_uuid_t        uuid;
PPCODE:
   net_nsid = *nsid;
   net_nsid.time_low            = htonl(net_nsid.time_low);
   net_nsid.time_mid            = htons(net_nsid.time_mid);
   net_nsid.time_hi_and_version = htons(net_nsid.time_hi_and_version);

   ctx = MD5Init();
   MD5Update(ctx, sv_2mortal(newSVpv((char*)&net_nsid, sizeof(perl_uuid_t))));
   MD5Update(ctx, name);
   MD5Final(hash, ctx);

   format_uuid_v3(&uuid, hash);
   ST(0) = make_ret(uuid, ix);
   XSRETURN(1);

int 
compare(self,u1,u2)
   uuid_context_t *self;
   perl_uuid_t         *u1; 
   perl_uuid_t         *u2;
PREINIT:
   int i;
CODE:
   RETVAL = 0;
   CHECK(u1->time_low, u2->time_low);
   CHECK(u1->time_mid, u2->time_mid);
   CHECK(u1->time_hi_and_version, u2->time_hi_and_version);
   CHECK(u1->clock_seq_hi_and_reserved, u2->clock_seq_hi_and_reserved);
   CHECK(u1->clock_seq_low, u2->clock_seq_low);
   for (i = 0; i < 6; i++) {
      if (u1->node[i] < u2->node[i])
         RETVAL = -1;
      if (u1->node[i] > u2->node[i])
         RETVAL =  1;
   }
OUTPUT:
   RETVAL

void
to_string(self,uuid)
   uuid_context_t *self;
   perl_uuid_t         *uuid;
ALIAS:
   Data::UUID::to_hexstring = F_HEX
   Data::UUID::to_b64string = F_B64
PPCODE:
   ST(0) = make_ret(*uuid, ix ? ix : F_STR);
   XSRETURN(1);

void
from_string(self,str) 
   uuid_context_t *self;
   char           *str;
ALIAS:
   Data::UUID::from_hexstring = F_HEX
   Data::UUID::from_b64string = F_B64
PREINIT:
   perl_uuid_t         uuid;
   char          *from, *to;
   int            c;
   unsigned int   i;
   unsigned char  buf[4];
PPCODE:
   switch(ix) {
   case F_BIN:
   case F_STR:
   case F_HEX:
      from = str;
      memset(&uuid, 0x00, sizeof(perl_uuid_t));
      if ( from[0] == '0' && from[1] == 'x' )
         from += 2;
      for (i = 0; i < sizeof(perl_uuid_t); i++) {
         if (*from == '-')
	    from++; 
         if (sscanf(from, "%2x", &c) != 1) 
	    croak("from_string(%s) failed...\n", str);
         ((unsigned char*)&uuid)[i] = (unsigned char)c;
         from += 2;
      }
      uuid.time_low            = ntohl(uuid.time_low);
      uuid.time_mid            = ntohs(uuid.time_mid);
      uuid.time_hi_and_version = ntohs(uuid.time_hi_and_version);
      break;
   case F_B64:
      from = str; to = (char*)&uuid;
      while(from < (str + strlen(str))) {
	 i = 0; memset(buf, 254, 4);
	 do {
	    c = index64[(int)*from++];
	    if (c != 255) buf[i++] = (unsigned char)c;
	    if (from == (str + strlen(str))) 
	       break;
         } while (i < 4);

	 if (buf[0] == 254 || buf[1] == 254) 
	    break;
         *to++ = (buf[0] << 2) | ((buf[1] & 0x30) >> 4);

	 if (buf[2] == 254) break;
	 *to++ = ((buf[1] & 0x0F) << 4) | ((buf[2] & 0x3C) >> 2);

	 if (buf[3] == 254) break;
	 *to++ = ((buf[2] & 0x03) << 6) | buf[3];
      }
      break;
   default:
      croak("invalid type %d\n", ix);
      break;
   }
   ST(0) = make_ret(uuid, F_BIN);
   XSRETURN(1);

#if DU_THREADSAFE

void
CLONE(klass)
CODE:
   MUTEX_LOCK(&instances_mutex);
   ptable_walk(instances, inc, instances);
   MUTEX_UNLOCK(&instances_mutex);

#endif



( run in 1.661 second using v1.01-cache-2.11-cpan-5511b514fd6 )