blob: c0e38e1da50358908a0aef29a2ef08e2c5cf55d3 [file]
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
#include "qpid/types/Uuid.h"
#include "qpid/sys/uuid.h"
#include "qpid/sys/IntegerTypes.h"
#include <sstream>
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
namespace qpid {
namespace types {
using namespace std;
const size_t Uuid::SIZE=16;
static const int UNPARSED_SIZE=36;
Uuid::Uuid(bool unique)
{
if (unique) {
generate();
} else {
clear();
}
}
Uuid::Uuid(const Uuid& other)
{
::memcpy(bytes, other.bytes, Uuid::SIZE);
}
Uuid::Uuid(const unsigned char* uuid)
{
::memcpy(bytes, uuid, Uuid::SIZE);
}
Uuid::Uuid(const char* uuid)
{
::memcpy(bytes, uuid, Uuid::SIZE);
}
Uuid& Uuid::operator=(const Uuid& other)
{
if (this == &other) return *this;
::memcpy(bytes, other.bytes, Uuid::SIZE);
return *this;
}
void Uuid::generate()
{
sys::uuid_generate(bytes);
}
void Uuid::clear()
{
::memset(bytes, 0, Uuid::SIZE);
}
bool Uuid::isNull() const
{
static Uuid nullUuid;
return *this == nullUuid;
}
Uuid::operator bool() const { return !isNull(); }
bool Uuid::operator!() const { return isNull(); }
size_t Uuid::size() const { return SIZE; }
const unsigned char* Uuid::data() const
{
return bytes;
}
bool operator==(const Uuid& a, const Uuid& b)
{
return ::memcmp(a.bytes, b.bytes, Uuid::SIZE) == 0;
}
bool operator!=(const Uuid& a, const Uuid& b)
{
return !(a == b);
}
bool operator<(const Uuid& a, const Uuid& b)
{
return ::memcmp(a.bytes, b.bytes, Uuid::SIZE) < 0;
}
bool operator>(const Uuid& a, const Uuid& b)
{
return ::memcmp(a.bytes, b.bytes, Uuid::SIZE) > 0;
}
bool operator<=(const Uuid& a, const Uuid& b)
{
return ::memcmp(a.bytes, b.bytes, Uuid::SIZE) <= 0;
}
bool operator>=(const Uuid& a, const Uuid& b)
{
return ::memcmp(a.bytes, b.bytes, Uuid::SIZE) >= 0;
}
ostream& operator<<(ostream& out, Uuid uuid)
{
const uint8_t* bytes = uuid.bytes;
ios_base::fmtflags f = out.flags();
out << hex << setfill('0')
<< setw(2) << int(bytes[0])
<< setw(2) << int(bytes[1])
<< setw(2) << int(bytes[2])
<< setw(2) << int(bytes[3])
<< "-"
<< setw(2) << int(bytes[4])
<< setw(2) << int(bytes[5])
<< "-"
<< setw(2) << int(bytes[6])
<< setw(2) << int(bytes[7])
<< "-"
<< setw(2) << int(bytes[8])
<< setw(2) << int(bytes[9])
<< "-"
<< setw(2) << int(bytes[10])
<< setw(2) << int(bytes[11])
<< setw(2) << int(bytes[12])
<< setw(2) << int(bytes[13])
<< setw(2) << int(bytes[14])
<< setw(2) << int(bytes[15]);
out.flags(f);
return out;
}
istream& operator>>(istream& in, Uuid& uuid)
{
unsigned bytes[16];
char unparsed[UNPARSED_SIZE + 1] = {0};
istream::sentry s(in);
if ( !s ) return in;
in.get(unparsed, UNPARSED_SIZE+1);
// Check if we read enough characters
if ( in.gcount()!=UNPARSED_SIZE ) {
in.setstate(ios::failbit);
return in;
}
int r = ::sscanf(unparsed, "%2x%2x%2x%2x-"
"%2x%2x-"
"%2x%2x-"
"%2x%2x-"
"%2x%2x%2x%2x%2x%2x",
&bytes[0], &bytes[1], &bytes[2], &bytes[3],
&bytes[4], &bytes[5],
&bytes[6], &bytes[7],
&bytes[8], &bytes[9],
&bytes[10], &bytes[11], &bytes[12], &bytes[13], &bytes[14], &bytes[15]
);
// Check if we got enough converted input
if ( r!=int(Uuid::SIZE) ) {
in.setstate(ios::failbit);
return in;
}
for (unsigned i=0; i<16; ++i) {
uuid.bytes[i] = bytes[i];
}
return in;
}
std::string Uuid::str() const
{
std::ostringstream os;
os << *this;
return os.str();
}
size_t Uuid::hash() const {
std::size_t seed = 0;
for(size_t i = 0; i < SIZE; ++i)
seed ^= static_cast<std::size_t>(bytes[i]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
return seed;
}
}} // namespace qpid::types