X-Git-Url: https://gitweb.ps.run/toc/blobdiff_plain/9f94b672a5dc32da5ad01742bd4e976315a30d9c..c6ad2948bb98d42f8e0883ef82cd14cd2d5eda60:/antlr4-cpp-runtime-4.9.2-source/runtime/src/support/guid.cpp diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/support/guid.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/support/guid.cpp new file mode 100644 index 0000000..b6105d7 --- /dev/null +++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/support/guid.cpp @@ -0,0 +1,303 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Graeme Hill (http://graemehill.ca) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +#include "guid.h" + +#ifdef GUID_LIBUUID +#include +#endif + +#ifdef GUID_CFUUID +#include +#endif + +#ifdef GUID_WINDOWS +#include +#endif + +#ifdef GUID_ANDROID +#include +#endif + +using namespace std; + +// overload << so that it's easy to convert to a string +ostream &operator<<(ostream &s, const Guid &guid) +{ + return s << hex << setfill('0') + << setw(2) << (int)guid._bytes[0] + << setw(2) << (int)guid._bytes[1] + << setw(2) << (int)guid._bytes[2] + << setw(2) << (int)guid._bytes[3] + << "-" + << setw(2) << (int)guid._bytes[4] + << setw(2) << (int)guid._bytes[5] + << "-" + << setw(2) << (int)guid._bytes[6] + << setw(2) << (int)guid._bytes[7] + << "-" + << setw(2) << (int)guid._bytes[8] + << setw(2) << (int)guid._bytes[9] + << "-" + << setw(2) << (int)guid._bytes[10] + << setw(2) << (int)guid._bytes[11] + << setw(2) << (int)guid._bytes[12] + << setw(2) << (int)guid._bytes[13] + << setw(2) << (int)guid._bytes[14] + << setw(2) << (int)guid._bytes[15]; +} + +// create a guid from vector of bytes +Guid::Guid(const vector &bytes) +{ + _bytes = bytes; +} + +// create a guid from array of bytes +Guid::Guid(const unsigned char *bytes) +{ + _bytes.assign(bytes, bytes + 16); +} + +// create a guid from array of words +Guid::Guid(const uint16_t *bytes, bool reverse) +{ + if (reverse) { + for (size_t i = 8; i > 0; --i) + { + _bytes.push_back(bytes[i - 1] >> 8); + _bytes.push_back(bytes[i - 1] & 0xFF); + } + } else { + for (size_t i = 0; i < 8; ++i) + { + _bytes.push_back(bytes[i] & 0xFF); + _bytes.push_back(bytes[i] >> 8); + } + } +} + +// converts a single hex char to a number (0 - 15) +static unsigned char hexDigitToChar(char ch) +{ + if (ch > 47 && ch < 58) + return (unsigned char)(ch - 48); + + if (ch > 96 && ch < 103) + return (unsigned char)(ch - 87); + + if (ch > 64 && ch < 71) + return (unsigned char)(ch - 55); + + return 0; +} + +// converts the two hexadecimal characters to an unsigned char (a byte) +static unsigned char hexPairToChar(char a, char b) +{ + return hexDigitToChar(a) * 16 + hexDigitToChar(b); +} + +// create a guid from string +Guid::Guid(const string &fromString) +{ + _bytes.clear(); + + char charOne = 0, charTwo; + bool lookingForFirstChar = true; + + for (const char &ch : fromString) + { + if (ch == '-') + continue; + + if (lookingForFirstChar) + { + charOne = ch; + lookingForFirstChar = false; + } + else + { + charTwo = ch; + auto byte = hexPairToChar(charOne, charTwo); + _bytes.push_back(byte); + lookingForFirstChar = true; + } + } + +} + +// create empty guid +Guid::Guid() +{ + _bytes = vector(16, 0); +} + +// copy constructor +Guid::Guid(const Guid &other) +{ + _bytes = other._bytes; +} + +// overload assignment operator +Guid &Guid::operator=(const Guid &other) +{ + _bytes = other._bytes; + return *this; +} + +// overload equality operator +bool Guid::operator==(const Guid &other) const +{ + return _bytes == other._bytes; +} + +// overload inequality operator +bool Guid::operator!=(const Guid &other) const +{ + return !((*this) == other); +} + +const std::string Guid::toString() const +{ + std::stringstream os; + os << *this; + return os.str(); +} + +// This is the linux friendly implementation, but it could work on other +// systems that have libuuid available +#ifdef GUID_LIBUUID +Guid GuidGenerator::newGuid() +{ + uuid_t id; + uuid_generate(id); + return id; +} +#endif + +// this is the mac and ios version +#ifdef GUID_CFUUID +Guid GuidGenerator::newGuid() +{ + auto newId = CFUUIDCreate(NULL); + auto bytes = CFUUIDGetUUIDBytes(newId); + CFRelease(newId); + + const unsigned char byteArray[16] = + { + bytes.byte0, + bytes.byte1, + bytes.byte2, + bytes.byte3, + bytes.byte4, + bytes.byte5, + bytes.byte6, + bytes.byte7, + bytes.byte8, + bytes.byte9, + bytes.byte10, + bytes.byte11, + bytes.byte12, + bytes.byte13, + bytes.byte14, + bytes.byte15 + }; + return byteArray; +} +#endif + +// obviously this is the windows version +#ifdef GUID_WINDOWS +Guid GuidGenerator::newGuid() +{ + GUID newId; + CoCreateGuid(&newId); + + const unsigned char bytes[16] = + { + (newId.Data1 >> 24) & 0xFF, + (newId.Data1 >> 16) & 0xFF, + (newId.Data1 >> 8) & 0xFF, + (newId.Data1) & 0xff, + + (newId.Data2 >> 8) & 0xFF, + (newId.Data2) & 0xff, + + (newId.Data3 >> 8) & 0xFF, + (newId.Data3) & 0xFF, + + newId.Data4[0], + newId.Data4[1], + newId.Data4[2], + newId.Data4[3], + newId.Data4[4], + newId.Data4[5], + newId.Data4[6], + newId.Data4[7] + }; + + return bytes; +} +#endif + +// android version that uses a call to a java api +#ifdef GUID_ANDROID +GuidGenerator::GuidGenerator(JNIEnv *env) +{ + _env = env; + _uuidClass = env->FindClass("java/util/UUID"); + _newGuidMethod = env->GetStaticMethodID(_uuidClass, "randomUUID", "()Ljava/util/UUID;"); + _mostSignificantBitsMethod = env->GetMethodID(_uuidClass, "getMostSignificantBits", "()J"); + _leastSignificantBitsMethod = env->GetMethodID(_uuidClass, "getLeastSignificantBits", "()J"); +} + +Guid GuidGenerator::newGuid() +{ + jobject javaUuid = _env->CallStaticObjectMethod(_uuidClass, _newGuidMethod); + jlong mostSignificant = _env->CallLongMethod(javaUuid, _mostSignificantBitsMethod); + jlong leastSignificant = _env->CallLongMethod(javaUuid, _leastSignificantBitsMethod); + + unsigned char bytes[16] = + { + (mostSignificant >> 56) & 0xFF, + (mostSignificant >> 48) & 0xFF, + (mostSignificant >> 40) & 0xFF, + (mostSignificant >> 32) & 0xFF, + (mostSignificant >> 24) & 0xFF, + (mostSignificant >> 16) & 0xFF, + (mostSignificant >> 8) & 0xFF, + (mostSignificant) & 0xFF, + (leastSignificant >> 56) & 0xFF, + (leastSignificant >> 48) & 0xFF, + (leastSignificant >> 40) & 0xFF, + (leastSignificant >> 32) & 0xFF, + (leastSignificant >> 24) & 0xFF, + (leastSignificant >> 16) & 0xFF, + (leastSignificant >> 8) & 0xFF, + (leastSignificant) & 0xFF, + }; + return bytes; +} +#endif