blob: eefae06c3d62f5d105e0b0cf55dad1f5cb4af10e [file] [log] [blame]
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <algorithm>
#include <Objbase.h>
#include "Guid.h"
#include "ErrorHandling.h"
// Code in this file requires linking with ole32
Guid::Guid(const std::string& str) {
*this = Guid(std::wstring(str.begin(), str.end()));
}
namespace {
void initGuid(const std::wstring& str, GUID& v) {
if (S_OK != IIDFromString(str.c_str(), &v)) {
JP_THROW(tstrings::any() << "IIDFromString(" << str << ") failed");
}
}
} //namespace
Guid::Guid(const std::wstring& str) {
enum { StdGuildLength = 38 };
if ((str.size() == StdGuildLength && str.front() == L'{' && str.back() == L'}')) {
initGuid(str, value);
return;
}
enum { BracketCount = 2 };
enum { DashCount = 4 };
std::wstring buf(str);
if (str.size() >= (StdGuildLength - (BracketCount + DashCount))) {
if (str.front() != L'{' && str.back() != L'}') {
buf = L"{" + str + L"}";
}
if (str.find(L'-') == std::wstring::npos) {
const size_t positions[] = { 9, 14, 19, 24 };
for (int i = 0; i < DashCount; ++i) {
buf.insert(positions[i], 1, L'-');
}
}
if (buf.size() != StdGuildLength) {
// Still no good, drop all tweaks.
// Let parsing function fail on the original string.
buf = str;
}
}
initGuid(buf, value);
}
Guid::Guid(const GUID& v): value(v) {
}
Guid::Guid() {
memset(&value, 0, sizeof(value));
}
bool Guid::operator < (const Guid& other) const {
return toString() < other.toString();
}
bool Guid::operator == (const Guid& other) const {
return IsEqualGUID(value, other.value) != FALSE;
}
tstring Guid::toString(int flags) const {
wchar_t buffer[128];
const int chars = StringFromGUID2(value, buffer, _countof(buffer));
if (chars < 3 /* strlen("{}") + 1 */) {
JP_THROW("StringFromGUID2() failed");
}
tstring reply(tstrings::fromUtf16(buffer));
if (flags & NoCurlyBrackets) {
reply = reply.substr(1, reply.size() - 2);
}
if (flags & NoDashes) {
// Drop all '-'.
reply = tstring(reply.begin(), std::remove(reply.begin(), reply.end(), _T('-')));
}
if (flags & LowerCase) {
reply = tstrings::toLower(reply);
}
return reply;
}
Guid Guid::generate() {
GUID guid = { 0 };
if (S_OK != CoCreateGuid(&guid)) {
JP_THROW("CoCreateGuid() failed");
}
return Guid(guid);
}