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