| /* | |
| * 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); | |
| } |