Codebase list crossguid / 45d6a47
New upstream snapshot. Debian Janitor 1 year, 4 months ago
68 changed file(s) with 1748 addition(s) and 1073 deletion(s). Raw diff Collapse all Expand all
+0
-63
.gitattributes less more
0 ###############################################################################
1 # Set default behavior to automatically normalize line endings.
2 ###############################################################################
3 * text=auto
4
5 ###############################################################################
6 # Set default behavior for command prompt diff.
7 #
8 # This is need for earlier builds of msysgit that does not have it on by
9 # default for csharp files.
10 # Note: This is only used by command line
11 ###############################################################################
12 #*.cs diff=csharp
13
14 ###############################################################################
15 # Set the merge driver for project and solution files
16 #
17 # Merging from the command prompt will add diff markers to the files if there
18 # are conflicts (Merging from VS is not affected by the settings below, in VS
19 # the diff markers are never inserted). Diff markers may cause the following
20 # file extensions to fail to load in VS. An alternative would be to treat
21 # these files as binary and thus will always conflict and require user
22 # intervention with every merge. To do so, just uncomment the entries below
23 ###############################################################################
24 #*.sln merge=binary
25 #*.csproj merge=binary
26 #*.vbproj merge=binary
27 #*.vcxproj merge=binary
28 #*.vcproj merge=binary
29 #*.dbproj merge=binary
30 #*.fsproj merge=binary
31 #*.lsproj merge=binary
32 #*.wixproj merge=binary
33 #*.modelproj merge=binary
34 #*.sqlproj merge=binary
35 #*.wwaproj merge=binary
36
37 ###############################################################################
38 # behavior for image files
39 #
40 # image files are treated as binary by default.
41 ###############################################################################
42 #*.jpg binary
43 #*.png binary
44 #*.gif binary
45
46 ###############################################################################
47 # diff behavior for common document formats
48 #
49 # Convert binary document formats to text before diffing them. This feature
50 # is only available from the command line. Turn it on by uncommenting the
51 # entries below.
52 ###############################################################################
53 #*.doc diff=astextplain
54 #*.DOC diff=astextplain
55 #*.docx diff=astextplain
56 #*.DOCX diff=astextplain
57 #*.dot diff=astextplain
58 #*.DOT diff=astextplain
59 #*.pdf diff=astextplain
60 #*.PDF diff=astextplain
61 #*.rtf diff=astextplain
62 #*.RTF diff=astextplain
+0
-40
.gitignore less more
0 *.o
1 *.so
2 *.a
3 *.dll
4 *.DLL
5 test
6 testmain
7 VisualStudio/*.user
8 VisualStudio/Debug/
9 VisualStudio/Release/
10 *.opensdf
11 *.sdf
12 *.suo
13 bin/
14 libs/
15 gen/
16 obj/
17 *.apk
18 *.ap_
19 *.dex
20 *.class
21 local.properties
22 *.pydevproject
23 .project
24 .metadata
25 bin/**
26 tmp/**
27 tmp/**/*
28 *.tmp
29 *.bak
30 *.swp
31 *~.nib
32 local.properties
33 .classpath
34 .settings/
35 .loadpath
36 .externalToolBuilders/
37 *.launch
38 .cproject
39 .buildpath
0 sudo: required
1 language: cpp
2 dist: trusty
3
4 matrix:
5 include:
6
7 - os: linux
8 addons:
9 apt:
10 sources:
11 - ubuntu-toolchain-r-test
12 packages:
13 - g++-8
14 env:
15 - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8"
16
17 - os: osx
18 osx_image: xcode9.2
19 compiler: clang
20
21 before_install:
22 # Make sure we set correct env for platform
23 - eval "$(MATRIX_EVAL)"
24
25 # Workaround for Travis CI macOS bug (https://github.com/travis-ci/travis-ci/issues/6307)
26 # See https://github.com/searchivarius/nmslib/pull/259
27 - |
28 if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
29 command curl -sSL https://rvm.io/mpapis.asc | gpg --import -;
30 rvm get head || true
31 fi
32
33 script:
34 - export CHECKOUT_PATH=`pwd`;
35 - echo "ROOT_PATH= $ROOT_PATH"
36 - echo "CHECKOUT_PATH= $CHECKOUT_PATH"
37
38 #######################################################################################
39 # Install a recent CMake (unless already installed on OS X)
40 #######################################################################################
41 - |
42 if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
43 CMAKE_URL="http://www.cmake.org/files/v3.10/cmake-3.10.2-Linux-x86_64.tar.gz"
44 mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
45 export PATH=${DEPS_DIR}/cmake/bin:${PATH}
46 else
47 brew upgrade cmake || echo "suppress failures in order to ignore warnings"
48 brew link --overwrite cmake
49 fi
50 - cmake --version
51
52 - |
53 if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
54 sudo apt-get install uuid-dev
55 fi
56 #######################################################################################
57 # Build the library
58 #######################################################################################
59 - |
60 cd "${CHECKOUT_PATH}"
61 mkdir build
62 cd build
63 cmake .. -DCMAKE_BUILD_TYPE="Debug"
64 sudo make install
65 #######################################################################################
66 # Run the tests
67 #######################################################################################
68 - ./crossguid-test
0 {
1 "variant": null,
2 "activeEnvironments": [],
3 "codeModel": null
4 }
0 cmake_minimum_required(VERSION 3.5.1)
1 project(CrossGuid VERSION 0.2.3)
2
3 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
4
5 option(CROSSGUID_TESTS "Build test runner" ON)
6
7 set(CMAKE_CXX_STANDARD 17)
8 set(CMAKE_CXX_EXTENSIONS OFF)
9 set(CMAKE_DEBUG_POSTFIX "-dgb")
10
11 # Set the build type if not set
12 if(NOT CMAKE_BUILD_TYPE)
13 set(CMAKE_BUILD_TYPE "Release")
14 endif()
15
16 add_library(crossguid ${CMAKE_CURRENT_SOURCE_DIR}/src/guid.cpp)
17 set_property(TARGET crossguid PROPERTY POSITION_INDEPENDENT_CODE ON)
18 target_include_directories(crossguid PUBLIC
19 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
20 $<INSTALL_INTERFACE:include>)
21
22 if(WIN32)
23 target_compile_definitions(crossguid PRIVATE GUID_WINDOWS)
24 elseif(APPLE)
25 find_library(CFLIB CoreFoundation)
26 target_link_libraries(crossguid ${CFLIB})
27 target_compile_definitions(crossguid PRIVATE GUID_CFUUID)
28 elseif(ANDROID)
29 # GUID_ANDROID is used in the headers, so make PUBLIC
30 target_compile_definitions(crossguid PUBLIC GUID_ANDROID)
31 else()
32 find_package(Libuuid REQUIRED)
33 if (NOT LIBUUID_FOUND)
34 message(FATAL_ERROR
35 "You might need to run 'sudo apt-get install uuid-dev' or similar")
36 endif()
37 target_include_directories(crossguid PRIVATE ${LIBUUID_INCLUDE_DIR})
38 target_link_libraries(crossguid ${LIBUUID_LIBRARY})
39 target_compile_definitions(crossguid PRIVATE GUID_LIBUUID)
40 endif()
41
42 if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
43 set(WARNINGS "-Werror" "-Wall")
44 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
45 set(WARNINGS "-Werror" "-Wall")
46 elseif(MSVC)
47 set(WARNINGS "/WX" "/W4")
48 endif()
49 target_compile_options(crossguid PRIVATE ${WARNINGS})
50
51 set_target_properties(crossguid
52 PROPERTIES
53 VERSION ${PROJECT_VERSION}
54 SOVERSION ${PROJECT_VERSION_MAJOR}
55 DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
56
57 if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
58 include(GNUInstallDirs)
59
60 set(CROSSGUID_INC_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}")
61 set(CROSSGUID_RUNTIME_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}")
62 set(CROSSGUID_LIBRARY_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}")
63 set(CROSSGUID_ARCHIVE_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}")
64 set(CROSSGUID_FRAMEWORK_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}")
65
66 set(CROSSGUID_CMAKE_CONFIG_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/crossguid/cmake")
67 set(CROSSGUID_ADDITIONAL_FILES_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/crossguid")
68
69 # Install target
70 install(TARGETS crossguid EXPORT crossguidTargets
71 RUNTIME DESTINATION ${CROSSGUID_RUNTIME_INSTALL_DIR}
72 LIBRARY DESTINATION ${CROSSGUID_LIBRARY_INSTALL_DIR}
73 ARCHIVE DESTINATION ${CROSSGUID_ARCHIVE_INSTALL_DIR}
74 FRAMEWORK DESTINATION ${CROSSGUID_FRAMEWORK_INSTALL_DIR})
75
76 # Install headers
77 install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/"
78 DESTINATION ${CROSSGUID_INC_INSTALL_DIR})
79
80 # Make cmake config files for all targets
81 install(EXPORT crossguidTargets
82 DESTINATION ${CROSSGUID_CMAKE_CONFIG_INSTALL_DIR}
83 FILE crossguid-config.cmake)
84
85 # Install readme and license
86 install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" "${CMAKE_CURRENT_SOURCE_DIR}/README.md"
87 DESTINATION ${CROSSGUID_ADDITIONAL_FILES_INSTALL_DIR})
88
89 configure_file(crossguid.pc.in ${PROJECT_BINARY_DIR}/crossguid.pc @ONLY)
90 install(FILES ${PROJECT_BINARY_DIR}/crossguid.pc DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig)
91 endif()
92
93 if (CROSSGUID_TESTS)
94 add_executable(crossguid-test test/TestMain.cpp test/Test.cpp)
95 target_link_libraries(crossguid-test crossguid)
96 endif()
0 # CrossGuid
0 # CrossGuid [![Build Status](https://travis-ci.org/graeme-hill/crossguid.svg?branch=master)](https://travis-ci.org/graeme-hill/crossguid)
11
22 CrossGuid is a minimal, cross platform, C++ GUID library. It uses the best
3 native GUID/UUID generator on the given platform and had a generic class for
4 parsing, stringifying, and comparing IDs. The intention is that anyone who
5 uses this code can simply copy `guid.h` and `guid.cpp` into their project and
6 define one of the following preprocessor flags to control the implementation:
7
8 * `GUID_LIBUUID` - Uses `libuuid` which is normally used on linux but possibly
9 usable elsewhere as well.
10 * `GUID_CFUUID` - Uses `CFCreateUUID` from Apple's `CoreFoundation` framework.
11 This works on both Mac OSX and iOS.
12 * `GUID_WINDOWS` - Uses the built in `CoCreateGuid` function in Windows.
13 * `GUID_ANDROID` - Uses JNI to invoke Java functions from Android SDK.
14
15 I recommend taking the time to actually look at the `guid.h` and `guid.cpp` so
16 that you can see how simple they are. It should be pretty trivial to modify
17 the code to match your naming conventions or drop it into a namespace so that it
18 fits in nicely with your code base.
3 native GUID/UUID generator on the given platform and has a generic class for
4 parsing, stringifying, and comparing IDs. The guid generation technique is
5 determined by your platform:
6
7 ## Linux
8
9 On linux you can use `libuuid` which is pretty standard. On distros like Ubuntu
10 it is available by default but to use it you need the header files so you have
11 to do:
12
13 sudo apt-get install uuid-dev
14
15 ## Mac/iOS
16
17 On Mac or iOS you can use `CFUUIDCreate` from `CoreFoundation`. Since it's a
18 plain C function you don't even need to compile as Objective-C++.
19
20 ## Windows
21
22 On Windows we just use the the built-in function `CoCreateGuid`. CMake can
23 generate a Visual Studio project if that's your thing.
24
25 ## Android
26
27 The Android version uses a handle to a `JNIEnv` object to invoke the
28 `randomUUID()` function on `java.util.UUID` from C++. The Android specific code
29 is all in the `android/` subdirectory. If you have an emulator already running,
30 then you can run the `android.sh` script in the root directory. It has the
31 following requirements:
32
33 - Android emulator is already running (or you have physical device connected).
34 - You're using bash.
35 - adb is in your path.
36 - You have an Android sdk setup including `ANDROID_HOME` environment variable.
37
38 ## Versions
39
40 This is version 0.2 of CrossGuid. If you all already using CrossGuid and your code
41 uses `GuidGenerator` then you are using version 0.1. Differences in version 0.2:
42
43 - Put everything inside the namespace `xg` instead of using the global
44 namespace.
45 - Removed `GuidGenerator` class and replaced with the free function
46 `xg::newGuid`. This is the way I originally wanted it to work but since Android
47 is a special snowflake requiring state (`JNIEnv *`) I introduced the
48 `GuidGenerator` class specifically so that there would be somewhere to store
49 the `JNIEnv *` when running on Android. However, this basically meant
50 complicating the library for the sake of one platform. In version 0.2 the goal is
51 to design for the normal platforms and let Android be weird. In Android you just
52 need to run `xg::initJni(JNIEnv *)` before you create any guids. The `JNIEnv *`
53 is just stored as a global variable.
54 - Added CMake build system. Instead of different scripts for each platform you
55 can just run cmake and it should handle each platform (except Android which
56 again is special).
57 - Actual guid bytes are stored in `std::array<unsigned char, 16>` instead of
58 `std::vector<unsigned char>`.
59 - More error checking (like if you try to create a guid with invalid number of
60 bytes).
61
62 If you're happily using version 0.1 then there's not really any reason to
63 change.
64
65 ## Compiling
66
67 Just do the normal cmake thing:
68
69 ```
70 mkdir build
71 cd build
72 cmake ..
73 make install
74 ```
75
76 ## Running tests
77
78 After compiling as described above you should get two files: `libcrossguid.a` (the
79 static library) and `crossguid-test` (the test runner). So to run the tests just do:
80
81 ```
82 ./crossguid-test
83 ```
1984
2085 ## Basic usage
2186
22 ### Tests
23
24 The tests are a simple way to figure out how the library works. There is a file
25 in the root of the repository called `test.cpp` that runs a simple set of tests
26 and outputs a few guid strings for a sanity check. This file does not have a
27 `main()` function entry point there, it is intended to be called from somewhere
28 else, and it takes a `GuidGenerator` as input. All platforms except for Android
29 use `testmain.cpp` to construct a `GuidGenerator` and run the tests. In Android
30 there is a special file called `android/jni/jnitest.cpp` which invokes the
31 tests.
32
33 ### Creating a guid generator
34
35 Creation of a guid generator is not exactly the same in every platform, but
36 this is an intentional feature. In Android the guid generation function has to
37 have access to a `JNIEnv` handle, but that handle is not necessarily the same
38 all the time. Therefore, there is a `GuidGenerator` class whose construction is
39 different depending on the platform, but client code can pass around a
40 `GuidGenerator` object and then use it the same on every platform. On every
41 platform except Android, you can create a guid generator like this:
42
43 GuidGenerator generator;
44
45 But on Android you need to pass a `JNIEnv *`:
46
47 GuidGenerator generator(env);
48
4987 ### Creating guids
5088
51 On every platform guid creation is the same:
52
53 void doGuidStuff(GuidGenerator generator)
54 {
55 auto myGuid = generator.newGuid();
56 }
89 Create a new random guid:
90
91 ```cpp
92 #include <crossguid/guid.hpp>
93 ...
94 auto g = xg::newGuid();
95 ```
96
97 **NOTE:** On Android you need to call `xg::initJni(JNIEnv *)` first so that it
98 is possible for `xg::newGuid()` to call back into java libraries. `initJni`
99 only needs to be called once when the process starts.
100
101 Create a new zero guid:
102
103 ```cpp
104 xg::Guid g;
105 ```
106
107 Create from a string:
108
109 ```cpp
110 xg::Guid g("c405c66c-ccbb-4ffd-9b62-c286c0fd7a3b");
111 ```
112
113 ### Checking validity
114
115 If you have some string value and you need to check whether it is a valid guid
116 then you can simply attempt to construct the guid:
117
118 ```cpp
119 xg::Guid g("bad-guid-string");
120 if (!g.isValid())
121 {
122 // do stuff
123 }
124 ```
125
126 If the guid string is not valid then all bytes are set to zero and `isValid()`
127 returns `false`.
57128
58129 ### Converting guid to string
59130
64135 utilize strings because the `<<` operator is overloaded. To print a guid to
65136 `std::cout`:
66137
67
68 void doGuidStuff(GuidGenerator generator)
69 {
70 auto myGuid = generator.newGuid();
71 std::cout << "Here is a guid: " << myGuid << std::endl;
72 }
138 ```cpp
139 void doGuidStuff()
140 {
141 auto myGuid = xg::newGuid();
142 std::cout << "Here is a guid: " << myGuid << std::endl;
143 }
144 ```
73145
74146 Or to store a guid in a `std::string`:
75147
76 void doGuidStuff(GuidGenerator generator)
77 {
78 auto myGuid = generator.newGuid();
79 std::stringstring stream;
80 stream << myGuid;
81 auto guidString = stream.str();
82 }
83
84 ### Parsing a string into a guid
85
86 There is a constructor that can be used to create a guid from a string without
87 needing any reference to a `GuidGenerator`:
88
89 void doGuidStuff()
90 {
91 Guid guid("e63e03a8-f3e5-4e0f-99bb-a3fc402d4fc8");
92 }
148 ```cpp
149 void doGuidStuff()
150 {
151 auto myGuid = xg::newGuid();
152 std::stringstream stream;
153 stream << myGuid;
154 auto guidString = stream.str();
155 }
156 ```
157
158 There is also a `str()` function that returns a `std::string`:
159
160 ```cpp
161 std::string guidStr = xg::newGuid().str();
162 ```
93163
94164 ### Creating a guid from raw bytes
95165
97167 internally to construct a `Guid` object from the raw data given by the system's
98168 built-in guid generation function. There are two key constructors for this:
99169
100 Guid(const vector<unsigned char> &bytes);
170 ```cpp
171 Guid(std::array<unsigned char, 16> &bytes);
172 ```
101173
102174 and
103175
104 Guid(const unsigned char *bytes);
105
106 In both cases the constructor expects to receive exactly 16 bytes.
176 ```cpp
177 Guid(const unsigned char * bytes);
178 ```
179
180 When possible prefer the `std::array` constructor because it is safer. If you
181 pass in an incorrectly sized C array then bad things will happen.
107182
108183 ### Comparing guids
109184
110185 `==` and `!=` are implemented, so the following works as expected:
111186
112 void doGuidStuff(GuidGenerator generator)
113 {
114 auto guid1 = generator.newGuid();
115 auto guid2 = generator.newGuid();
116
117 auto guidsAreEqual = guid1 == guid2;
118 auto guidsAreNotEqual = guid1 != guid2;
119 }
120
121 ## Linux
122
123 **The Linux version uses the proprocessor flag `GUID_LIBUUID`**
124
125 On linux you can use libuuid which is pretty standard. On distros like Ubuntu
126 it is available by default but to use it you need the header files so you have
127 to do:
128
129 sudo apt-get install uuid-dev
130
131 Then you can compile and run tests with:
132
133 ./linux.sh
134
135 ## Mac/iOS
136
137 **The Mac and iOS versions use the preprocessor flag `GUID_CFUUID`**
138
139 On Mac or iOS you can use `CFUUIDCreate` from `CoreFoundation`. Since it's a
140 plain C function you don't even need to compile as Objective-C++. If you have
141 the command line tools that come with Xcode installed, then you can compile and
142 run the tests like this:
143
144 ./mac.sh
145
146 ## Windows
147
148 **The Windows version uses the preprocessor flag `GUID_WINDOWS`**
149
150 On Windows we just the the built-in function `CoCreateGuid`. There is a Visual
151 Studio 2013 solution in the `VisualStudio` directory which you can use to
152 compile and run tests.
153
154 ## Android
155
156 **The Android version uses the preprocessor flag `GUID_ANDROID`**
157
158 The Android version uses a handle to a `JNIEnv` object to invoke the
159 `randomUUID()` function on `java.util.UUID` from C++. The Android specific code
160 is all in the `android/` subdirectory. If you have an emulator already running,
161 then you can run the `android.sh` script in the root directory. It has the
162 following requirements:
163
164 * Android emulator is already running (or you have physical device connected).
165 * You're using bash.
166 * adb is in your path.
167 * ndk-build and other ndk cross-compile tools are in your path.
168 * You have a jdk setup including `JAVA_HOME` environment variable.
187 ```cpp
188 void doGuidStuff()
189 {
190 auto guid1 = xg::newGuid();
191 auto guid2 = xg::newGuid();
192
193 auto guidsAreEqual = guid1 == guid2;
194 auto guidsAreNotEqual = guid1 != guid2;
195 }
196 ```
197
198 ### Hashing guids
199
200 Guids can be used directly in containers requireing `std::hash` such as `std::map,`std::unordered_map` etc.
169201
170202 ## License
171203
+0
-93
VisualStudio/CrossGuid-Test.vcxproj less more
0 <?xml version="1.0" encoding="utf-8"?>
1 <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <ItemGroup Label="ProjectConfigurations">
3 <ProjectConfiguration Include="Debug|Win32">
4 <Configuration>Debug</Configuration>
5 <Platform>Win32</Platform>
6 </ProjectConfiguration>
7 <ProjectConfiguration Include="Release|Win32">
8 <Configuration>Release</Configuration>
9 <Platform>Win32</Platform>
10 </ProjectConfiguration>
11 </ItemGroup>
12 <PropertyGroup Label="Globals">
13 <ProjectGuid>{C8233271-F319-4531-AEF6-3BD6420B55CD}</ProjectGuid>
14 <Keyword>Win32Proj</Keyword>
15 <RootNamespace>CrossGuid</RootNamespace>
16 <ProjectName>CrossGuid-Test</ProjectName>
17 </PropertyGroup>
18 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
19 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
20 <ConfigurationType>Application</ConfigurationType>
21 <UseDebugLibraries>true</UseDebugLibraries>
22 <PlatformToolset>v120</PlatformToolset>
23 <CharacterSet>Unicode</CharacterSet>
24 </PropertyGroup>
25 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
26 <ConfigurationType>Application</ConfigurationType>
27 <UseDebugLibraries>false</UseDebugLibraries>
28 <PlatformToolset>v120</PlatformToolset>
29 <WholeProgramOptimization>true</WholeProgramOptimization>
30 <CharacterSet>Unicode</CharacterSet>
31 </PropertyGroup>
32 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
33 <ImportGroup Label="ExtensionSettings">
34 </ImportGroup>
35 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
36 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
37 </ImportGroup>
38 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
39 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
40 </ImportGroup>
41 <PropertyGroup Label="UserMacros" />
42 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
43 <LinkIncremental>true</LinkIncremental>
44 </PropertyGroup>
45 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
46 <LinkIncremental>false</LinkIncremental>
47 </PropertyGroup>
48 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
49 <ClCompile>
50 <PrecompiledHeader>
51 </PrecompiledHeader>
52 <WarningLevel>Level3</WarningLevel>
53 <Optimization>Disabled</Optimization>
54 <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;GUID_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
55 </ClCompile>
56 <Link>
57 <SubSystem>Console</SubSystem>
58 <GenerateDebugInformation>true</GenerateDebugInformation>
59 <AdditionalDependencies>CrossGuidd.lib;%(AdditionalDependencies)</AdditionalDependencies>
60 <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)</AdditionalLibraryDirectories>
61 </Link>
62 </ItemDefinitionGroup>
63 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
64 <ClCompile>
65 <WarningLevel>Level3</WarningLevel>
66 <PrecompiledHeader>
67 </PrecompiledHeader>
68 <Optimization>MaxSpeed</Optimization>
69 <FunctionLevelLinking>true</FunctionLevelLinking>
70 <IntrinsicFunctions>true</IntrinsicFunctions>
71 <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;GUID_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
72 </ClCompile>
73 <Link>
74 <SubSystem>Console</SubSystem>
75 <GenerateDebugInformation>true</GenerateDebugInformation>
76 <EnableCOMDATFolding>true</EnableCOMDATFolding>
77 <OptimizeReferences>true</OptimizeReferences>
78 <AdditionalDependencies>CrossGuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
79 <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)</AdditionalLibraryDirectories>
80 </Link>
81 </ItemDefinitionGroup>
82 <ItemGroup>
83 <ClInclude Include="..\test.h" />
84 </ItemGroup>
85 <ItemGroup>
86 <ClCompile Include="..\test.cpp" />
87 <ClCompile Include="..\testmain.cpp" />
88 </ItemGroup>
89 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
90 <ImportGroup Label="ExtensionTargets">
91 </ImportGroup>
92 </Project>
+0
-30
VisualStudio/CrossGuid-Test.vcxproj.filters less more
0 <?xml version="1.0" encoding="utf-8"?>
1 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <ItemGroup>
3 <Filter Include="Source Files">
4 <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
5 <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
6 </Filter>
7 <Filter Include="Header Files">
8 <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
9 <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
10 </Filter>
11 <Filter Include="Resource Files">
12 <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
13 <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
14 </Filter>
15 </ItemGroup>
16 <ItemGroup>
17 <ClCompile Include="..\test.cpp">
18 <Filter>Source Files</Filter>
19 </ClCompile>
20 <ClCompile Include="..\testmain.cpp">
21 <Filter>Source Files</Filter>
22 </ClCompile>
23 </ItemGroup>
24 <ItemGroup>
25 <ClInclude Include="..\test.h">
26 <Filter>Header Files</Filter>
27 </ClInclude>
28 </ItemGroup>
29 </Project>
+0
-31
VisualStudio/CrossGuid.sln less more
0 
1 Microsoft Visual Studio Solution File, Format Version 12.00
2 # Visual Studio Express 2013 for Windows Desktop
3 VisualStudioVersion = 12.0.40629.0
4 MinimumVisualStudioVersion = 10.0.40219.1
5 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CrossGuid-Test", "CrossGuid-Test.vcxproj", "{C8233271-F319-4531-AEF6-3BD6420B55CD}"
6 ProjectSection(ProjectDependencies) = postProject
7 {AF365E5F-E35D-40A6-958A-C7B6988C994D} = {AF365E5F-E35D-40A6-958A-C7B6988C994D}
8 EndProjectSection
9 EndProject
10 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CrossGuid", "CrossGuid.vcxproj", "{AF365E5F-E35D-40A6-958A-C7B6988C994D}"
11 EndProject
12 Global
13 GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 Debug|Win32 = Debug|Win32
15 Release|Win32 = Release|Win32
16 EndGlobalSection
17 GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 {C8233271-F319-4531-AEF6-3BD6420B55CD}.Debug|Win32.ActiveCfg = Debug|Win32
19 {C8233271-F319-4531-AEF6-3BD6420B55CD}.Debug|Win32.Build.0 = Debug|Win32
20 {C8233271-F319-4531-AEF6-3BD6420B55CD}.Release|Win32.ActiveCfg = Release|Win32
21 {C8233271-F319-4531-AEF6-3BD6420B55CD}.Release|Win32.Build.0 = Release|Win32
22 {AF365E5F-E35D-40A6-958A-C7B6988C994D}.Debug|Win32.ActiveCfg = Debug|Win32
23 {AF365E5F-E35D-40A6-958A-C7B6988C994D}.Debug|Win32.Build.0 = Debug|Win32
24 {AF365E5F-E35D-40A6-958A-C7B6988C994D}.Release|Win32.ActiveCfg = Release|Win32
25 {AF365E5F-E35D-40A6-958A-C7B6988C994D}.Release|Win32.Build.0 = Release|Win32
26 EndGlobalSection
27 GlobalSection(SolutionProperties) = preSolution
28 HideSolutionNode = FALSE
29 EndGlobalSection
30 EndGlobal
+0
-79
VisualStudio/CrossGuid.vcxproj less more
0 <?xml version="1.0" encoding="utf-8"?>
1 <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <ItemGroup Label="ProjectConfigurations">
3 <ProjectConfiguration Include="Debug|Win32">
4 <Configuration>Debug</Configuration>
5 <Platform>Win32</Platform>
6 </ProjectConfiguration>
7 <ProjectConfiguration Include="Release|Win32">
8 <Configuration>Release</Configuration>
9 <Platform>Win32</Platform>
10 </ProjectConfiguration>
11 </ItemGroup>
12 <ItemGroup>
13 <ClCompile Include="..\guid.cpp" />
14 </ItemGroup>
15 <ItemGroup>
16 <ClInclude Include="..\guid.h" />
17 </ItemGroup>
18 <PropertyGroup Label="Globals">
19 <ProjectGuid>{AF365E5F-E35D-40A6-958A-C7B6988C994D}</ProjectGuid>
20 <RootNamespace>CrossGuid</RootNamespace>
21 </PropertyGroup>
22 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
23 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
24 <ConfigurationType>StaticLibrary</ConfigurationType>
25 <UseDebugLibraries>true</UseDebugLibraries>
26 <PlatformToolset>v120</PlatformToolset>
27 <CharacterSet>Unicode</CharacterSet>
28 </PropertyGroup>
29 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
30 <ConfigurationType>StaticLibrary</ConfigurationType>
31 <UseDebugLibraries>false</UseDebugLibraries>
32 <PlatformToolset>v120</PlatformToolset>
33 <WholeProgramOptimization>true</WholeProgramOptimization>
34 <CharacterSet>Unicode</CharacterSet>
35 </PropertyGroup>
36 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
37 <ImportGroup Label="ExtensionSettings">
38 </ImportGroup>
39 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
40 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
41 </ImportGroup>
42 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
43 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
44 </ImportGroup>
45 <PropertyGroup Label="UserMacros" />
46 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
47 <TargetName>$(ProjectName)d</TargetName>
48 </PropertyGroup>
49 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
50 <ClCompile>
51 <WarningLevel>Level3</WarningLevel>
52 <Optimization>Disabled</Optimization>
53 <SDLCheck>false</SDLCheck>
54 <PreprocessorDefinitions>_MBCS;GUID_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
55 </ClCompile>
56 <Link>
57 <GenerateDebugInformation>true</GenerateDebugInformation>
58 </Link>
59 </ItemDefinitionGroup>
60 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
61 <ClCompile>
62 <WarningLevel>Level3</WarningLevel>
63 <Optimization>MaxSpeed</Optimization>
64 <FunctionLevelLinking>true</FunctionLevelLinking>
65 <IntrinsicFunctions>true</IntrinsicFunctions>
66 <SDLCheck>true</SDLCheck>
67 <PreprocessorDefinitions>_MBCS;GUID_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
68 </ClCompile>
69 <Link>
70 <GenerateDebugInformation>true</GenerateDebugInformation>
71 <EnableCOMDATFolding>true</EnableCOMDATFolding>
72 <OptimizeReferences>true</OptimizeReferences>
73 </Link>
74 </ItemDefinitionGroup>
75 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
76 <ImportGroup Label="ExtensionTargets">
77 </ImportGroup>
78 </Project>
+0
-27
VisualStudio/CrossGuid.vcxproj.filters less more
0 <?xml version="1.0" encoding="utf-8"?>
1 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <ItemGroup>
3 <Filter Include="Source Files">
4 <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
5 <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
6 </Filter>
7 <Filter Include="Header Files">
8 <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
9 <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
10 </Filter>
11 <Filter Include="Resource Files">
12 <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
13 <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
14 </Filter>
15 </ItemGroup>
16 <ItemGroup>
17 <ClCompile Include="..\guid.cpp">
18 <Filter>Source Files</Filter>
19 </ClCompile>
20 </ItemGroup>
21 <ItemGroup>
22 <ClInclude Include="..\guid.h">
23 <Filter>Header Files</Filter>
24 </ClInclude>
25 </ItemGroup>
26 </Project>
0 *.iml
1 .gradle
2 /local.properties
3 /.idea/workspace.xml
4 /.idea/libraries
5 .DS_Store
6 /build
7 /captures
8 .externalNativeBuild
9 .idea
+0
-15
android/AndroidManifest.xml less more
0 <?xml version="1.0" encoding="utf-8"?>
1 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2 package="ca.graemehill.crossguid.testapp"
3 android:versionCode="1"
4 android:versionName="1.0">
5 <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
6 <activity android:name="MainActivity"
7 android:label="@string/app_name">
8 <intent-filter>
9 <action android:name="android.intent.action.MAIN" />
10 <category android:name="android.intent.category.LAUNCHER" />
11 </intent-filter>
12 </activity>
13 </application>
14 </manifest>
0 cmake_minimum_required(VERSION 3.4.1)
1
2 set(LIB_NAME crossguidtest)
3 set(XG_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
4 set(XG_TEST_DIR ${XG_DIR}/test)
5
6 add_library(${LIB_NAME} SHARED src/main/cpp/jnitest.cpp ${XG_TEST_DIR}/Test.cpp)
7
8 target_include_directories(${LIB_NAME} PRIVATE
9 ${XG_DIR}
10 ${XG_TEST_DIR})
11
12 target_compile_definitions(${LIB_NAME} PRIVATE GUID_ANDROID)
13
14 set(XG_TESTS OFF CACHE BOOL "disable tests")
15 add_subdirectory(${XG_DIR} ${XG_DIR}/cmake_build)
16
17 target_link_libraries(${LIB_NAME} xg)
0 apply plugin: 'com.android.application'
1
2 android {
3 compileSdkVersion 25
4 buildToolsVersion "26.0.0"
5 defaultConfig {
6 applicationId "ca.graemehill.crossguid.testapp"
7 minSdkVersion 14
8 targetSdkVersion 25
9 versionCode 1
10 versionName "1.0"
11 externalNativeBuild {
12 cmake {
13 cppFlags "-std=c++11 -frtti -fexceptions"
14 arguments "-DANDROID_TOOLCHAIN=clang"
15 }
16 }
17 }
18 buildTypes {
19 release {
20 minifyEnabled false
21 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 }
23 }
24 externalNativeBuild {
25 cmake {
26 path "CMakeLists.txt"
27 }
28 }
29 }
30
31 dependencies {
32 implementation fileTree(dir: 'libs', include: ['*.jar'])
33 androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.0', {
34 exclude group: 'com.android.support', module: 'support-annotations'
35 })
36 implementation 'com.android.support:appcompat-v7:25.4.0'
37 testImplementation 'junit:junit:4.12'
38 }
0 # Add project specific ProGuard rules here.
1 # By default, the flags in this file are appended to flags specified
2 # in /usr/local/Cellar/android-sdk/24.4.1_1/tools/proguard/proguard-android.txt
3 # You can edit the include path and order by changing the proguardFiles
4 # directive in build.gradle.
5 #
6 # For more details, see
7 # http://developer.android.com/guide/developing/tools/proguard.html
8
9 # Add any project specific keep options here:
10
11 # If your project uses WebView with JS, uncomment the following
12 # and specify the fully qualified class name to the JavaScript interface
13 # class:
14 #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
15 # public *;
16 #}
17
18 # Uncomment this to preserve the line number information for
19 # debugging stack traces.
20 #-keepattributes SourceFile,LineNumberTable
21
22 # If you keep the line number information, uncomment this to
23 # hide the original source file name.
24 #-renamesourcefileattribute SourceFile
0 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
1 package="ca.graemehill.crossguid.testapp">
2
3 <application
4 android:allowBackup="true"
5 android:icon="@mipmap/ic_launcher"
6 android:label="@string/app_name"
7 android:roundIcon="@mipmap/ic_launcher_round"
8 android:supportsRtl="true"
9 android:theme="@style/AppTheme">
10 <activity android:name="MainActivity"
11 android:label="@string/app_name">
12 <intent-filter>
13 <action android:name="android.intent.action.MAIN" />
14 <category android:name="android.intent.category.LAUNCHER" />
15 </intent-filter>
16 </activity>
17 </application>
18 </manifest>
0 #include <string>
1 #include <sstream>
2 #include <atomic>
3 #include <iostream>
4 #include <crossguid/guid.hpp
5 #include <jni.h>
6
7 #include "Test.hpp"
8
9 JavaVM *&javaVM() {
10 static JavaVM *jvm;
11 return jvm;
12 }
13
14 extern "C"
15 {
16
17 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void * /* reserved */) {
18 javaVM() = jvm;
19 return JNI_VERSION_1_6;
20 }
21
22 JNIEXPORT jstring JNICALL
23 Java_ca_graemehill_crossguid_testapp_MainActivity_test(
24 JNIEnv *env, jobject /*thiz*/)
25 {
26 std::stringstream resultStream;
27 xg::initJni(env);
28 test(resultStream);
29 return env->NewStringUTF(resultStream.str().c_str());
30 }
31
32 JNIEXPORT jstring JNICALL
33 Java_ca_graemehill_crossguid_testapp_MainActivity_newGuid(
34 JNIEnv *env, jobject /*thiz*/) {
35 return env->NewStringUTF(xg::newGuid(env).str().c_str());
36 }
37
38 JNIEXPORT jstring JNICALL
39 Java_ca_graemehill_crossguid_testapp_MainActivity_createGuidFromNativeThread(
40 JNIEnv *env, jobject /*thiz*/) {
41
42 // there is no promise<> in armeabi of ndk
43 // so ugly atomic_bool wait solution
44 std::atomic_bool ready { false };
45 std::string guid;
46
47 std::thread([&ready, &guid](){
48 JNIEnv *threadEnv;
49 javaVM()->AttachCurrentThread(&threadEnv, NULL);
50 guid = xg::newGuid(threadEnv);
51 javaVM()->DetachCurrentThread();
52
53 ready = true;
54 }).detach();
55
56 while (!ready);
57 return env->NewStringUTF(guid.c_str());
58 }
59
60 }
0 package ca.graemehill.crossguid.testapp;
1
2 import android.app.Activity;
3 import android.os.Bundle;
4 import android.widget.TextView;
5
6 import java.util.concurrent.CountDownLatch;
7
8 public class MainActivity extends Activity {
9
10 @Override
11 public void onCreate(Bundle savedInstanceState) {
12 super.onCreate(savedInstanceState);
13 setContentView(R.layout.main);
14
15 final TextView textView = (TextView)findViewById(R.id.mainTextView);
16 textView.setText(test());
17
18 final TextView javaThreadView = (TextView)findViewById(R.id.javaThreadView);
19 javaThreadView.setText(createGuidFromJavaThread());
20
21 final TextView nativeThreadView = (TextView)findViewById(R.id.nativeThreadView);
22 nativeThreadView.setText(createGuidFromNativeThread());
23 }
24
25 public native String test();
26
27 private static class StringCapture {
28 private String value;
29
30 public String getValue() {
31 return value;
32 }
33
34 public void setValue(String value) {
35 this.value = value;
36 }
37 }
38
39 public String createGuidFromJavaThread() {
40 final CountDownLatch created = new CountDownLatch(1);
41 final StringCapture result = new StringCapture();
42 new Thread(new Runnable() {
43 @Override
44 public void run() {
45 result.setValue(newGuid());
46 created.countDown();
47 }
48 }).start();
49 try {
50 created.await();
51 } catch (InterruptedException e) {
52 return "Could not get value: " + e.getMessage();
53 }
54 return result.getValue();
55 }
56
57 public native String newGuid();
58
59 public native String createGuidFromNativeThread();
60 static {
61 System.loadLibrary("crossguidtest");
62 }
63 }
0 <?xml version="1.0" encoding="utf-8"?>
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 android:orientation="vertical"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent"
5 >
6 <TextView
7 android:layout_width="match_parent"
8 android:layout_height="wrap_content"
9 android:text="@string/test_results_label"
10 android:textStyle="bold"/>
11 <TextView
12 android:id="@+id/mainTextView"
13 android:layout_width="match_parent"
14 android:layout_height="wrap_content" />
15 <TextView
16 android:layout_width="match_parent"
17 android:layout_height="wrap_content"
18 android:text="@string/java_thread_label"
19 android:textStyle="bold"/>
20 <TextView
21 android:layout_width="match_parent"
22 android:layout_height="wrap_content"
23 android:id="@+id/javaThreadView"/>
24 <TextView
25 android:layout_width="match_parent"
26 android:layout_height="wrap_content"
27 android:text="@string/native_thread_label"
28 android:textStyle="bold"/>
29 <TextView
30 android:layout_width="match_parent"
31 android:layout_height="wrap_content"
32 android:id="@+id/nativeThreadView"/>
33 </LinearLayout>
34
0 <?xml version="1.0" encoding="utf-8"?>
1 <resources>
2 <color name="colorPrimary">#3F51B5</color>
3 <color name="colorPrimaryDark">#303F9F</color>
4 <color name="colorAccent">#FF4081</color>
5 </resources>
0 <resources>
1 <string name="app_name">TestApp</string>
2 <string name="native_thread_label">GUID created from Native Thread</string>
3 <string name="java_thread_label">GUID created from Java Thread</string>
4 <string name="test_results_label">Test results</string>
5 </resources>
0 <resources>
1
2 <!-- Base application theme. -->
3 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
4 <!-- Customize your theme here. -->
5 <item name="colorPrimary">@color/colorPrimary</item>
6 <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
7 <item name="colorAccent">@color/colorAccent</item>
8 </style>
9
10 </resources>
0 // Top-level build file where you can add configuration options common to all sub-projects/modules.
1
2 buildscript {
3
4 repositories {
5 maven { url 'https://maven.google.com' }
6 jcenter()
7 }
8 dependencies {
9 classpath 'com.android.tools.build:gradle:3.0.0-alpha3'
10
11 // NOTE: Do not place your application dependencies here; they belong
12 // in the individual module build.gradle files
13 }
14 }
15
16 allprojects {
17 repositories {
18 maven { url 'https://maven.google.com' }
19 jcenter()
20 }
21 }
22
23 task clean(type: Delete) {
24 delete rootProject.buildDir
25 }
0 #Thu Aug 03 09:39:40 MSK 2017
1 distributionBase=GRADLE_USER_HOME
2 distributionPath=wrapper/dists
3 zipStoreBase=GRADLE_USER_HOME
4 zipStorePath=wrapper/dists
5 distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-milestone-1-all.zip
0 # Project-wide Gradle settings.
1
2 # IDE (e.g. Android Studio) users:
3 # Gradle settings configured through the IDE *will override*
4 # any settings specified in this file.
5
6 # For more details on how to configure your build environment visit
7 # http://www.gradle.org/docs/current/userguide/build_environment.html
8
9 # Specifies the JVM arguments used for the daemon process.
10 # The setting is particularly useful for tweaking memory settings.
11 org.gradle.jvmargs=-Xmx1536m
12
13 # When configured, Gradle will run in incubating parallel mode.
14 # This option should only be used with decoupled projects. More details, visit
15 # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
16 # org.gradle.parallel=true
17 android.enableAapt2=false
0 #!/usr/bin/env bash
1
2 ##############################################################################
3 ##
4 ## Gradle start up script for UN*X
5 ##
6 ##############################################################################
7
8 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
9 DEFAULT_JVM_OPTS=""
10 LC_NUMERIC="en_US.UTF-8"
11
12 APP_NAME="Gradle"
13 APP_BASE_NAME=`basename "$0"`
14
15 # Use the maximum available, or set MAX_FD != -1 to use that value.
16 MAX_FD="maximum"
17
18 warn ( ) {
19 echo "$*"
20 }
21
22 die ( ) {
23 echo
24 echo "$*"
25 echo
26 exit 1
27 }
28
29 # OS specific support (must be 'true' or 'false').
30 cygwin=false
31 msys=false
32 darwin=false
33 case "`uname`" in
34 CYGWIN* )
35 cygwin=true
36 ;;
37 Darwin* )
38 darwin=true
39 ;;
40 MINGW* )
41 msys=true
42 ;;
43 esac
44
45 # Attempt to set APP_HOME
46 # Resolve links: $0 may be a link
47 PRG="$0"
48 # Need this for relative symlinks.
49 while [ -h "$PRG" ] ; do
50 ls=`ls -ld "$PRG"`
51 link=`expr "$ls" : '.*-> \(.*\)$'`
52 if expr "$link" : '/.*' > /dev/null; then
53 PRG="$link"
54 else
55 PRG=`dirname "$PRG"`"/$link"
56 fi
57 done
58 SAVED="`pwd`"
59 cd "`dirname \"$PRG\"`/" >/dev/null
60 APP_HOME="`pwd -P`"
61 cd "$SAVED" >/dev/null
62
63 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64
65 # Determine the Java command to use to start the JVM.
66 if [ -n "$JAVA_HOME" ] ; then
67 if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 # IBM's JDK on AIX uses strange locations for the executables
69 JAVACMD="$JAVA_HOME/jre/sh/java"
70 else
71 JAVACMD="$JAVA_HOME/bin/java"
72 fi
73 if [ ! -x "$JAVACMD" ] ; then
74 die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75
76 Please set the JAVA_HOME variable in your environment to match the
77 location of your Java installation."
78 fi
79 else
80 JAVACMD="java"
81 which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82
83 Please set the JAVA_HOME variable in your environment to match the
84 location of your Java installation."
85 fi
86
87 # Increase the maximum file descriptors if we can.
88 if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 MAX_FD_LIMIT=`ulimit -H -n`
90 if [ $? -eq 0 ] ; then
91 if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 MAX_FD="$MAX_FD_LIMIT"
93 fi
94 ulimit -n $MAX_FD
95 if [ $? -ne 0 ] ; then
96 warn "Could not set maximum file descriptor limit: $MAX_FD"
97 fi
98 else
99 warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 fi
101 fi
102
103 # For Darwin, add options to specify how the application appears in the dock
104 if $darwin; then
105 GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 fi
107
108 # For Cygwin, switch paths to Windows format before running java
109 if $cygwin ; then
110 APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 JAVACMD=`cygpath --unix "$JAVACMD"`
113
114 # We build the pattern for arguments to be converted via cygpath
115 ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 SEP=""
117 for dir in $ROOTDIRSRAW ; do
118 ROOTDIRS="$ROOTDIRS$SEP$dir"
119 SEP="|"
120 done
121 OURCYGPATTERN="(^($ROOTDIRS))"
122 # Add a user-defined pattern to the cygpath arguments
123 if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 fi
126 # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 i=0
128 for arg in "$@" ; do
129 CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131
132 if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 else
135 eval `echo args$i`="\"$arg\""
136 fi
137 i=$((i+1))
138 done
139 case $i in
140 (0) set -- ;;
141 (1) set -- "$args0" ;;
142 (2) set -- "$args0" "$args1" ;;
143 (3) set -- "$args0" "$args1" "$args2" ;;
144 (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 esac
151 fi
152
153 # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 function splitJvmOpts() {
155 JVM_OPTS=("$@")
156 }
157 eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159
160 exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
0 @if "%DEBUG%" == "" @echo off
1 @rem ##########################################################################
2 @rem
3 @rem Gradle startup script for Windows
4 @rem
5 @rem ##########################################################################
6
7 @rem Set local scope for the variables with windows NT shell
8 if "%OS%"=="Windows_NT" setlocal
9
10 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
11 set DEFAULT_JVM_OPTS=
12
13 set DIRNAME=%~dp0
14 if "%DIRNAME%" == "" set DIRNAME=.
15 set APP_BASE_NAME=%~n0
16 set APP_HOME=%DIRNAME%
17
18 @rem Find java.exe
19 if defined JAVA_HOME goto findJavaFromJavaHome
20
21 set JAVA_EXE=java.exe
22 %JAVA_EXE% -version >NUL 2>&1
23 if "%ERRORLEVEL%" == "0" goto init
24
25 echo.
26 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
27 echo.
28 echo Please set the JAVA_HOME variable in your environment to match the
29 echo location of your Java installation.
30
31 goto fail
32
33 :findJavaFromJavaHome
34 set JAVA_HOME=%JAVA_HOME:"=%
35 set JAVA_EXE=%JAVA_HOME%/bin/java.exe
36
37 if exist "%JAVA_EXE%" goto init
38
39 echo.
40 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
41 echo.
42 echo Please set the JAVA_HOME variable in your environment to match the
43 echo location of your Java installation.
44
45 goto fail
46
47 :init
48 @rem Get command-line arguments, handling Windowz variants
49
50 if not "%OS%" == "Windows_NT" goto win9xME_args
51 if "%@eval[2+2]" == "4" goto 4NT_args
52
53 :win9xME_args
54 @rem Slurp the command line arguments.
55 set CMD_LINE_ARGS=
56 set _SKIP=2
57
58 :win9xME_args_slurp
59 if "x%~1" == "x" goto execute
60
61 set CMD_LINE_ARGS=%*
62 goto execute
63
64 :4NT_args
65 @rem Get arguments from the 4NT Shell from JP Software
66 set CMD_LINE_ARGS=%$
67
68 :execute
69 @rem Setup the command line
70
71 set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72
73 @rem Execute Gradle
74 "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
75
76 :end
77 @rem End local scope for the variables with windows NT shell
78 if "%ERRORLEVEL%"=="0" goto mainEnd
79
80 :fail
81 rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 rem the _cmd.exe /c_ return code!
83 if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 exit /b 1
85
86 :mainEnd
87 if "%OS%"=="Windows_NT" endlocal
88
89 :omega
+0
-11
android/jni/Android.mk less more
0 LOCAL_PATH := $(call my-dir)
1
2 include $(CLEAR_VARS)
3
4 LOCAL_MODULE := crossguidtest
5 LOCAL_CFLAGS := -Wall
6 LOCAL_SRC_FILES := ../../guid.cpp ../../test.cpp jnitest.cpp
7 LOCAL_CPP_FLAGS := -std=c++11
8 LOCAL_CPPFLAGS := -DGUID_ANDROID -Wno-c++11-extensions
9
10 include $(BUILD_SHARED_LIBRARY)
+0
-4
android/jni/Application.mk less more
0 APP_STL := stlport_static
1 NDK_TOOLCHAIN_VERSION := clang
2 LOCAL_CPP_FLAGS := -DGUID_ANDROID
3 APP_ABI := all
+0
-18
android/jni/jnitest.cpp less more
0 #include <string>
1 #include <sstream>
2 #include <jni.h>
3 #include <iostream>
4 #include "../../test.h"
5 #include "../../guid.h"
6
7 extern "C"
8 {
9
10 jstring Java_ca_graemehill_crossguid_testapp_MainActivity_test(JNIEnv *env, jobject thiz)
11 {
12 std::stringstream resultStream;
13 test(GuidGenerator(env), resultStream);
14 return env->NewStringUTF(resultStream.str().c_str());
15 }
16
17 }
android/res/drawable-hdpi/ic_launcher.png less more
Binary diff not shown
android/res/drawable-ldpi/ic_launcher.png less more
Binary diff not shown
android/res/drawable-mdpi/ic_launcher.png less more
Binary diff not shown
android/res/drawable-xhdpi/ic_launcher.png less more
Binary diff not shown
+0
-14
android/res/layout/main.xml less more
0 <?xml version="1.0" encoding="utf-8"?>
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 android:orientation="vertical"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent"
5 >
6 <TextView
7 android:id="@+id/mainTextView"
8 android:layout_width="fill_parent"
9 android:layout_height="wrap_content"
10 android:text="Graeme says hi"
11 />
12 </LinearLayout>
13
+0
-4
android/res/values/strings.xml less more
0 <?xml version="1.0" encoding="utf-8"?>
1 <resources>
2 <string name="app_name">MainActivity</string>
3 </resources>
0 include ':app'
+0
-24
android/src/ca/graemehill/crossguid/testapp/MainActivity.java less more
0 package ca.graemehill.crossguid.testapp;
1
2 import android.app.Activity;
3 import android.os.Bundle;
4 import android.widget.TextView;
5 import java.util.UUID;
6
7 public class MainActivity extends Activity {
8
9 @Override
10 public void onCreate(Bundle savedInstanceState) {
11 super.onCreate(savedInstanceState);
12 setContentView(R.layout.main);
13
14 final TextView textView = (TextView)findViewById(R.id.mainTextView);
15 textView.setText(test());
16 }
17
18 public native String test();
19
20 static {
21 System.loadLibrary("crossguidtest");
22 }
23 }
00 #!/usr/bin/env bash
11
2 export LC_NUMERIC="en_US.UTF-8"
3
24 pushd android
3 ndk-build clean || { exit 1; }
4 ndk-build || { exit 1; }
5 ant debug || { exit 1; }
5 ./gradlew clean assembleDebug
66 adb uninstall ca.graemehill.crossguid.testapp || { exit 1; }
7 adb install bin/TestApp-debug.apk || { exit 1; }
7 adb install app/build/outputs/apk/debug/app-debug.apk || { exit 1; }
88 adb shell am start -n ca.graemehill.crossguid.testapp/ca.graemehill.crossguid.testapp.MainActivity
99 popd
+0
-6
clean.sh less more
0 rm -f *.o
1 rm -f *.a
2 rm -f *.so
3 rm -f testmain
4 rm -f *.dll
5 rm -f *.DLL
0 find_package(PkgConfig)
1
2 pkg_check_modules(PKG_LIBUUID QUIET uuid)
3
4 set(LIBUUID_DEFINITIONS ${PKG_LIBUUID_CFLAGS_OTHER})
5 set(LIBUUID_VERSION ${PKG_LIBUUID_VERSION})
6
7 find_path(LIBUUID_INCLUDE_DIR
8 NAMES uuid/uuid.h
9 HINTS ${PKG_LIBUUID_INCLUDE_DIRS}
10 )
11 find_library(LIBUUID_LIBRARY
12 NAMES uuid
13 HINTS ${PKG_LIBUUID_LIBRARY_DIRS}
14 )
15
16 include(FindPackageHandleStandardArgs)
17 find_package_handle_standard_args(LibUUID
18 FOUND_VAR
19 LIBUUID_FOUND
20 REQUIRED_VARS
21 LIBUUID_LIBRARY
22 LIBUUID_INCLUDE_DIR
23 VERSION_VAR
24 LIBUUID_VERSION
25 )
26
27 if(LIBUUID_FOUND AND NOT TARGET LibUUID::UUID)
28 add_library(LibUUID::UUID UNKNOWN IMPORTED)
29 set_target_properties(LibUUID::UUID PROPERTIES
30 IMPORTED_LOCATION "${LIBUUID_LIBRARY}"
31 INTERFACE_COMPILE_OPTIONS "${LIBUUID_DEFINITIONS}"
32 INTERFACE_INCLUDE_DIRECTORIES "${LIBUUID_INCLUDE_DIR}"
33 )
34 endif()
35
36 mark_as_advanced(LIBUUID_INCLUDE_DIR LIBUUID_LIBRARY)
37
38 include(FeatureSummary)
39 set_package_properties(LIBUUID PROPERTIES
40 URL "http://www.kernel.org/pub/linux/utils/util-linux/"
41 DESCRIPTION "uuid library in util-linux"
42 )
0 prefix=@CMAKE_INSTALL_PREFIX@
1 exec_prefix=${prefix}
2 includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
3 libdir=@CMAKE_INSTALL_FULL_LIBDIR@
4
5 Name: crossguid
6 Description: Lightweight cross platform C++ GUID/UUID library
7 URL: https://github.com/graeme-hill/crossguid
8 Version: @PROJECT_VERSION@
9 Cflags: -I${includedir}
10 Libs: -L${libdir} -lcrossguid
0 crossguid (0.2.2+git20190529.1.ca1bf4b-1) UNRELEASED; urgency=low
1
2 * New upstream snapshot.
3
4 -- Debian Janitor <janitor@jelmer.uk> Fri, 25 Nov 2022 09:56:57 -0000
5
06 crossguid (0.0+git200150803-6) unstable; urgency=medium
17
28 * QA upload.
+0
-278
guid.cpp less more
0 /*
1 The MIT License (MIT)
2
3 Copyright (c) 2014 Graeme Hill (http://graemehill.ca)
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 THE SOFTWARE.
22 */
23
24 #include "guid.h"
25
26 #ifdef GUID_LIBUUID
27 #include <uuid/uuid.h>
28 #endif
29
30 #ifdef GUID_CFUUID
31 #include <CoreFoundation/CFUUID.h>
32 #endif
33
34 #ifdef GUID_WINDOWS
35 #include <objbase.h>
36 #endif
37
38 #ifdef GUID_ANDROID
39 #include <jni.h>
40 #endif
41
42 using namespace std;
43
44 // overload << so that it's easy to convert to a string
45 ostream &operator<<(ostream &s, const Guid &guid)
46 {
47 return s << hex << setfill('0')
48 << setw(2) << (int)guid._bytes[0]
49 << setw(2) << (int)guid._bytes[1]
50 << setw(2) << (int)guid._bytes[2]
51 << setw(2) << (int)guid._bytes[3]
52 << "-"
53 << setw(2) << (int)guid._bytes[4]
54 << setw(2) << (int)guid._bytes[5]
55 << "-"
56 << setw(2) << (int)guid._bytes[6]
57 << setw(2) << (int)guid._bytes[7]
58 << "-"
59 << setw(2) << (int)guid._bytes[8]
60 << setw(2) << (int)guid._bytes[9]
61 << "-"
62 << setw(2) << (int)guid._bytes[10]
63 << setw(2) << (int)guid._bytes[11]
64 << setw(2) << (int)guid._bytes[12]
65 << setw(2) << (int)guid._bytes[13]
66 << setw(2) << (int)guid._bytes[14]
67 << setw(2) << (int)guid._bytes[15];
68 }
69
70 // create a guid from vector of bytes
71 Guid::Guid(const vector<unsigned char> &bytes)
72 {
73 _bytes = bytes;
74 }
75
76 // create a guid from array of bytes
77 Guid::Guid(const unsigned char *bytes)
78 {
79 _bytes.assign(bytes, bytes + 16);
80 }
81
82 // converts a single hex char to a number (0 - 15)
83 unsigned char hexDigitToChar(char ch)
84 {
85 if (ch > 47 && ch < 58)
86 return ch - 48;
87
88 if (ch > 96 && ch < 103)
89 return ch - 87;
90
91 if (ch > 64 && ch < 71)
92 return ch - 55;
93
94 return 0;
95 }
96
97 // converts the two hexadecimal characters to an unsigned char (a byte)
98 unsigned char hexPairToChar(char a, char b)
99 {
100 return hexDigitToChar(a) * 16 + hexDigitToChar(b);
101 }
102
103 // create a guid from string
104 Guid::Guid(const string &fromString)
105 {
106 _bytes.clear();
107
108 char charOne, charTwo;
109 bool lookingForFirstChar = true;
110
111 for (const char &ch : fromString)
112 {
113 if (ch == '-')
114 continue;
115
116 if (lookingForFirstChar)
117 {
118 charOne = ch;
119 lookingForFirstChar = false;
120 }
121 else
122 {
123 charTwo = ch;
124 auto byte = hexPairToChar(charOne, charTwo);
125 _bytes.push_back(byte);
126 lookingForFirstChar = true;
127 }
128 }
129
130 }
131
132 // create empty guid
133 Guid::Guid()
134 {
135 _bytes = vector<unsigned char>(16, 0);
136 }
137
138 // copy constructor
139 Guid::Guid(const Guid &other)
140 {
141 _bytes = other._bytes;
142 }
143
144 // overload assignment operator
145 Guid &Guid::operator=(const Guid &other)
146 {
147 _bytes = other._bytes;
148 return *this;
149 }
150
151 // overload equality operator
152 bool Guid::operator==(const Guid &other) const
153 {
154 return _bytes == other._bytes;
155 }
156
157 // overload inequality operator
158 bool Guid::operator!=(const Guid &other) const
159 {
160 return !((*this) == other);
161 }
162
163 // This is the linux friendly implementation, but it could work on other
164 // systems that have libuuid available
165 #ifdef GUID_LIBUUID
166 Guid GuidGenerator::newGuid()
167 {
168 uuid_t id;
169 uuid_generate(id);
170 return id;
171 }
172 #endif
173
174 // this is the mac and ios version
175 #ifdef GUID_CFUUID
176 Guid GuidGenerator::newGuid()
177 {
178 auto newId = CFUUIDCreate(NULL);
179 auto bytes = CFUUIDGetUUIDBytes(newId);
180 CFRelease(newId);
181
182 const unsigned char byteArray[16] =
183 {
184 bytes.byte0,
185 bytes.byte1,
186 bytes.byte2,
187 bytes.byte3,
188 bytes.byte4,
189 bytes.byte5,
190 bytes.byte6,
191 bytes.byte7,
192 bytes.byte8,
193 bytes.byte9,
194 bytes.byte10,
195 bytes.byte11,
196 bytes.byte12,
197 bytes.byte13,
198 bytes.byte14,
199 bytes.byte15
200 };
201 return byteArray;
202 }
203 #endif
204
205 // obviously this is the windows version
206 #ifdef GUID_WINDOWS
207 Guid GuidGenerator::newGuid()
208 {
209 GUID newId;
210 CoCreateGuid(&newId);
211
212 const unsigned char bytes[16] =
213 {
214 (newId.Data1 >> 24) & 0xFF,
215 (newId.Data1 >> 16) & 0xFF,
216 (newId.Data1 >> 8) & 0xFF,
217 (newId.Data1) & 0xff,
218
219 (newId.Data2 >> 8) & 0xFF,
220 (newId.Data2) & 0xff,
221
222 (newId.Data3 >> 8) & 0xFF,
223 (newId.Data3) & 0xFF,
224
225 newId.Data4[0],
226 newId.Data4[1],
227 newId.Data4[2],
228 newId.Data4[3],
229 newId.Data4[4],
230 newId.Data4[5],
231 newId.Data4[6],
232 newId.Data4[7]
233 };
234
235 return bytes;
236 }
237 #endif
238
239 // android version that uses a call to a java api
240 #ifdef GUID_ANDROID
241 GuidGenerator::GuidGenerator(JNIEnv *env)
242 {
243 _env = env;
244 _uuidClass = env->FindClass("java/util/UUID");
245 _newGuidMethod = env->GetStaticMethodID(_uuidClass, "randomUUID", "()Ljava/util/UUID;");
246 _mostSignificantBitsMethod = env->GetMethodID(_uuidClass, "getMostSignificantBits", "()J");
247 _leastSignificantBitsMethod = env->GetMethodID(_uuidClass, "getLeastSignificantBits", "()J");
248 }
249
250 Guid GuidGenerator::newGuid()
251 {
252 jobject javaUuid = _env->CallStaticObjectMethod(_uuidClass, _newGuidMethod);
253 jlong mostSignificant = _env->CallLongMethod(javaUuid, _mostSignificantBitsMethod);
254 jlong leastSignificant = _env->CallLongMethod(javaUuid, _leastSignificantBitsMethod);
255
256 unsigned char bytes[16] =
257 {
258 (mostSignificant >> 56) & 0xFF,
259 (mostSignificant >> 48) & 0xFF,
260 (mostSignificant >> 40) & 0xFF,
261 (mostSignificant >> 32) & 0xFF,
262 (mostSignificant >> 24) & 0xFF,
263 (mostSignificant >> 16) & 0xFF,
264 (mostSignificant >> 8) & 0xFF,
265 (mostSignificant) & 0xFF,
266 (leastSignificant >> 56) & 0xFF,
267 (leastSignificant >> 48) & 0xFF,
268 (leastSignificant >> 40) & 0xFF,
269 (leastSignificant >> 32) & 0xFF,
270 (leastSignificant >> 24) & 0xFF,
271 (leastSignificant >> 16) & 0xFF,
272 (leastSignificant >> 8) & 0xFF,
273 (leastSignificant) & 0xFF,
274 };
275 return bytes;
276 }
277 #endif
+0
-102
guid.h less more
0 /*
1 The MIT License (MIT)
2
3 Copyright (c) 2014 Graeme Hill (http://graemehill.ca)
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 THE SOFTWARE.
22 */
23
24 #pragma once
25
26 #include <iostream>
27 #include <vector>
28 #include <sstream>
29 #include <string>
30 #include <iomanip>
31
32 #ifdef GUID_ANDROID
33 #include <jni.h>
34 #endif
35
36 // Class to represent a GUID/UUID. Each instance acts as a wrapper around a
37 // 16 byte value that can be passed around by value. It also supports
38 // conversion to string (via the stream operator <<) and conversion from a
39 // string via constructor.
40 class Guid
41 {
42 public:
43
44 // create a guid from vector of bytes
45 Guid(const std::vector<unsigned char> &bytes);
46
47 // create a guid from array of bytes
48 Guid(const unsigned char *bytes);
49
50 // create a guid from string
51 Guid(const std::string &fromString);
52
53 // create empty guid
54 Guid();
55
56 // copy constructor
57 Guid(const Guid &other);
58
59 // overload assignment operator
60 Guid &operator=(const Guid &other);
61
62 // overload equality and inequality operator
63 bool operator==(const Guid &other) const;
64 bool operator!=(const Guid &other) const;
65
66 private:
67
68 // actual data
69 std::vector<unsigned char> _bytes;
70
71 // make the << operator a friend so it can access _bytes
72 friend std::ostream &operator<<(std::ostream &s, const Guid &guid);
73 };
74
75 // Class that can create new guids. The only reason this exists instead of
76 // just a global "newGuid" function is because some platforms will require
77 // that there is some attached context. In the case of android, we need to
78 // know what JNIEnv is being used to call back to Java, but the newGuid()
79 // function would no longer be cross-platform if we parameterized the android
80 // version. Instead, construction of the GuidGenerator may be different on
81 // each platform, but the use of newGuid is uniform.
82 class GuidGenerator
83 {
84 public:
85 #ifdef GUID_ANDROID
86 GuidGenerator(JNIEnv *env);
87 #else
88 GuidGenerator() { }
89 #endif
90
91 Guid newGuid();
92
93 #ifdef GUID_ANDROID
94 private:
95 JNIEnv *_env;
96 jclass _uuidClass;
97 jmethodID _newGuidMethod;
98 jmethodID _mostSignificantBitsMethod;
99 jmethodID _leastSignificantBitsMethod;
100 #endif
101 };
0 /*
1 The MIT License (MIT)
2
3 Copyright (c) 2014 Graeme Hill (http://graemehill.ca)
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 THE SOFTWARE.
22 */
23
24 #pragma once
25
26 #ifdef GUID_ANDROID
27 #include <thread>
28 #include <jni.h>
29 #endif
30
31 #include <functional>
32 #include <iostream>
33 #include <array>
34 #include <sstream>
35 #include <string_view>
36 #include <utility>
37 #include <iomanip>
38
39 #define BEGIN_XG_NAMESPACE namespace xg {
40 #define END_XG_NAMESPACE }
41
42 BEGIN_XG_NAMESPACE
43
44 // Class to represent a GUID/UUID. Each instance acts as a wrapper around a
45 // 16 byte value that can be passed around by value. It also supports
46 // conversion to string (via the stream operator <<) and conversion from a
47 // string via constructor.
48 class Guid
49 {
50 public:
51 explicit Guid(const std::array<unsigned char, 16> &bytes);
52 explicit Guid(std::array<unsigned char, 16> &&bytes);
53
54 explicit Guid(std::string_view fromString);
55 Guid();
56
57 Guid(const Guid &other) = default;
58 Guid &operator=(const Guid &other) = default;
59 Guid(Guid &&other) = default;
60 Guid &operator=(Guid &&other) = default;
61
62 bool operator==(const Guid &other) const;
63 bool operator!=(const Guid &other) const;
64
65 std::string str() const;
66 operator std::string() const;
67 const std::array<unsigned char, 16>& bytes() const;
68 void swap(Guid &other);
69 bool isValid() const;
70
71 private:
72 void zeroify();
73
74 // actual data
75 std::array<unsigned char, 16> _bytes;
76
77 // make the << operator a friend so it can access _bytes
78 friend std::ostream &operator<<(std::ostream &s, const Guid &guid);
79 friend bool operator<(const Guid &lhs, const Guid &rhs);
80 };
81
82 Guid newGuid();
83
84 #ifdef GUID_ANDROID
85 struct AndroidGuidInfo
86 {
87 static AndroidGuidInfo fromJniEnv(JNIEnv *env);
88
89 JNIEnv *env;
90 jclass uuidClass;
91 jmethodID newGuidMethod;
92 jmethodID mostSignificantBitsMethod;
93 jmethodID leastSignificantBitsMethod;
94 std::thread::id initThreadId;
95 };
96
97 extern AndroidGuidInfo androidInfo;
98
99 void initJni(JNIEnv *env);
100
101 // overloading for multi-threaded calls
102 Guid newGuid(JNIEnv *env);
103 #endif
104
105 namespace details
106 {
107 template <typename...> struct hash;
108
109 template<typename T>
110 struct hash<T> : public std::hash<T>
111 {
112 using std::hash<T>::hash;
113 };
114
115
116 template <typename T, typename... Rest>
117 struct hash<T, Rest...>
118 {
119 inline std::size_t operator()(const T& v, const Rest&... rest) {
120 std::size_t seed = hash<Rest...>{}(rest...);
121 seed ^= hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
122 return seed;
123 }
124 };
125 }
126
127 END_XG_NAMESPACE
128
129 namespace std
130 {
131 // Template specialization for std::swap<Guid>() --
132 // See guid.cpp for the function definition
133 template <>
134 void swap(xg::Guid &guid0, xg::Guid &guid1) noexcept;
135
136 // Specialization for std::hash<Guid> -- this implementation
137 // uses std::hash<std::string> on the stringification of the guid
138 // to calculate the hash
139 template <>
140 struct hash<xg::Guid>
141 {
142 std::size_t operator()(xg::Guid const &guid) const
143 {
144 const uint64_t* p = reinterpret_cast<const uint64_t*>(guid.bytes().data());
145 return xg::details::hash<uint64_t, uint64_t>{}(p[0], p[1]);
146 }
147 };
148 }
+0
-10
linux.sh less more
0 #!/usr/bin/env bash
1
2 ./clean.sh
3
4 g++ -c guid.cpp -o guid.o -Wall -std=c++11 -DGUID_LIBUUID
5 g++ -c test.cpp -o test.o -Wall -std=c++11
6 g++ -c testmain.cpp -o testmain.o -Wall
7 g++ test.o guid.o testmain.o -o test -luuid
8 chmod +x test
9 ./test
+0
-10
mac.sh less more
0 #!/usr/bin/env bash
1
2 ./clean.sh
3
4 clang++ -c guid.cpp -o guid.o -Wall -std=c++11 -DGUID_CFUUID
5 clang++ -c test.cpp -o test.o -Wall -std=c++11
6 clang++ -c testmain.cpp -o testmain.o -Wall -std=c++11
7 clang++ test.o guid.o testmain.o -o test -framework CoreFoundation
8 chmod +x test
9 ./test
0 /*
1 The MIT License (MIT)
2
3 Copyright (c) 2014 Graeme Hill (http://graemehill.ca)
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 THE SOFTWARE.
22 */
23
24 #include <cstring>
25 #include "crossguid/guid.hpp"
26
27 #ifdef GUID_LIBUUID
28 #include <uuid/uuid.h>
29 #endif
30
31 #ifdef GUID_CFUUID
32 #include <CoreFoundation/CFUUID.h>
33 #endif
34
35 #ifdef GUID_WINDOWS
36 #include <objbase.h>
37 #endif
38
39 #ifdef GUID_ANDROID
40 #include <jni.h>
41 #include <cassert>
42 #endif
43
44 BEGIN_XG_NAMESPACE
45
46 #ifdef GUID_ANDROID
47 AndroidGuidInfo androidInfo;
48
49 AndroidGuidInfo AndroidGuidInfo::fromJniEnv(JNIEnv *env)
50 {
51 AndroidGuidInfo info;
52 info.env = env;
53 auto localUuidClass = env->FindClass("java/util/UUID");
54 info.uuidClass = (jclass)env->NewGlobalRef(localUuidClass);
55 env->DeleteLocalRef(localUuidClass);
56 info.newGuidMethod = env->GetStaticMethodID(
57 info.uuidClass, "randomUUID", "()Ljava/util/UUID;");
58 info.mostSignificantBitsMethod = env->GetMethodID(
59 info.uuidClass, "getMostSignificantBits", "()J");
60 info.leastSignificantBitsMethod = env->GetMethodID(
61 info.uuidClass, "getLeastSignificantBits", "()J");
62 info.initThreadId = std::this_thread::get_id();
63 return info;
64 }
65
66 void initJni(JNIEnv *env)
67 {
68 androidInfo = AndroidGuidInfo::fromJniEnv(env);
69 }
70 #endif
71
72 // overload << so that it's easy to convert to a string
73 std::ostream &operator<<(std::ostream &s, const Guid &guid)
74 {
75 std::ios_base::fmtflags f(s.flags()); // politely don't leave the ostream in hex mode
76 s << std::hex << std::setfill('0')
77 << std::setw(2) << (int)guid._bytes[0]
78 << std::setw(2) << (int)guid._bytes[1]
79 << std::setw(2) << (int)guid._bytes[2]
80 << std::setw(2) << (int)guid._bytes[3]
81 << "-"
82 << std::setw(2) << (int)guid._bytes[4]
83 << std::setw(2) << (int)guid._bytes[5]
84 << "-"
85 << std::setw(2) << (int)guid._bytes[6]
86 << std::setw(2) << (int)guid._bytes[7]
87 << "-"
88 << std::setw(2) << (int)guid._bytes[8]
89 << std::setw(2) << (int)guid._bytes[9]
90 << "-"
91 << std::setw(2) << (int)guid._bytes[10]
92 << std::setw(2) << (int)guid._bytes[11]
93 << std::setw(2) << (int)guid._bytes[12]
94 << std::setw(2) << (int)guid._bytes[13]
95 << std::setw(2) << (int)guid._bytes[14]
96 << std::setw(2) << (int)guid._bytes[15];
97 s.flags(f);
98 return s;
99 }
100
101 bool operator<(const xg::Guid &lhs, const xg::Guid &rhs)
102 {
103 return lhs.bytes() < rhs.bytes();
104 }
105
106 bool Guid::isValid() const
107 {
108 xg::Guid empty;
109 return *this != empty;
110 }
111
112 // convert to string using std::snprintf() and std::string
113 std::string Guid::str() const
114 {
115 char one[10], two[6], three[6], four[6], five[14];
116
117 snprintf(one, 10, "%02x%02x%02x%02x",
118 _bytes[0], _bytes[1], _bytes[2], _bytes[3]);
119 snprintf(two, 6, "%02x%02x",
120 _bytes[4], _bytes[5]);
121 snprintf(three, 6, "%02x%02x",
122 _bytes[6], _bytes[7]);
123 snprintf(four, 6, "%02x%02x",
124 _bytes[8], _bytes[9]);
125 snprintf(five, 14, "%02x%02x%02x%02x%02x%02x",
126 _bytes[10], _bytes[11], _bytes[12], _bytes[13], _bytes[14], _bytes[15]);
127 const std::string sep("-");
128 std::string out(one);
129
130 out += sep + two;
131 out += sep + three;
132 out += sep + four;
133 out += sep + five;
134
135 return out;
136 }
137
138 // conversion operator for std::string
139 Guid::operator std::string() const
140 {
141 return str();
142 }
143
144 // Access underlying bytes
145 const std::array<unsigned char, 16>& Guid::bytes() const
146 {
147 return _bytes;
148 }
149
150 // create a guid from vector of bytes
151 Guid::Guid(const std::array<unsigned char, 16> &bytes) : _bytes(bytes)
152 { }
153
154 // create a guid from vector of bytes
155 Guid::Guid(std::array<unsigned char, 16> &&bytes) : _bytes(std::move(bytes))
156 { }
157
158 // converts a single hex char to a number (0 - 15)
159 unsigned char hexDigitToChar(char ch)
160 {
161 // 0-9
162 if (ch > 47 && ch < 58)
163 return ch - 48;
164
165 // a-f
166 if (ch > 96 && ch < 103)
167 return ch - 87;
168
169 // A-F
170 if (ch > 64 && ch < 71)
171 return ch - 55;
172
173 return 0;
174 }
175
176 bool isValidHexChar(char ch)
177 {
178 // 0-9
179 if (ch > 47 && ch < 58)
180 return true;
181
182 // a-f
183 if (ch > 96 && ch < 103)
184 return true;
185
186 // A-F
187 if (ch > 64 && ch < 71)
188 return true;
189
190 return false;
191 }
192
193 // converts the two hexadecimal characters to an unsigned char (a byte)
194 unsigned char hexPairToChar(char a, char b)
195 {
196 return hexDigitToChar(a) * 16 + hexDigitToChar(b);
197 }
198
199 // create a guid from string
200 Guid::Guid(std::string_view fromString)
201 {
202 char charOne = '\0';
203 char charTwo = '\0';
204 bool lookingForFirstChar = true;
205 unsigned nextByte = 0;
206
207 for (const char &ch : fromString)
208 {
209 if (ch == '-')
210 continue;
211
212 if (nextByte >= 16 || !isValidHexChar(ch))
213 {
214 // Invalid string so bail
215 zeroify();
216 return;
217 }
218
219 if (lookingForFirstChar)
220 {
221 charOne = ch;
222 lookingForFirstChar = false;
223 }
224 else
225 {
226 charTwo = ch;
227 auto byte = hexPairToChar(charOne, charTwo);
228 _bytes[nextByte++] = byte;
229 lookingForFirstChar = true;
230 }
231 }
232
233 // if there were fewer than 16 bytes in the string then guid is bad
234 if (nextByte < 16)
235 {
236 zeroify();
237 return;
238 }
239 }
240
241 // create empty guid
242 Guid::Guid() : _bytes{ {0} }
243 { }
244
245 // set all bytes to zero
246 void Guid::zeroify()
247 {
248 std::fill(_bytes.begin(), _bytes.end(), static_cast<unsigned char>(0));
249 }
250
251 // overload equality operator
252 bool Guid::operator==(const Guid &other) const
253 {
254 return _bytes == other._bytes;
255 }
256
257 // overload inequality operator
258 bool Guid::operator!=(const Guid &other) const
259 {
260 return !((*this) == other);
261 }
262
263 // member swap function
264 void Guid::swap(Guid &other)
265 {
266 _bytes.swap(other._bytes);
267 }
268
269 // This is the linux friendly implementation, but it could work on other
270 // systems that have libuuid available
271 #ifdef GUID_LIBUUID
272 Guid newGuid()
273 {
274 std::array<unsigned char, 16> data;
275 static_assert(std::is_same<unsigned char[16], uuid_t>::value, "Wrong type!");
276 uuid_generate(data.data());
277 return Guid{std::move(data)};
278 }
279 #endif
280
281 // this is the mac and ios version
282 #ifdef GUID_CFUUID
283 Guid newGuid()
284 {
285 auto newId = CFUUIDCreate(NULL);
286 auto bytes = CFUUIDGetUUIDBytes(newId);
287 CFRelease(newId);
288
289 std::array<unsigned char, 16> byteArray =
290 {{
291 bytes.byte0,
292 bytes.byte1,
293 bytes.byte2,
294 bytes.byte3,
295 bytes.byte4,
296 bytes.byte5,
297 bytes.byte6,
298 bytes.byte7,
299 bytes.byte8,
300 bytes.byte9,
301 bytes.byte10,
302 bytes.byte11,
303 bytes.byte12,
304 bytes.byte13,
305 bytes.byte14,
306 bytes.byte15
307 }};
308 return Guid{std::move(byteArray)};
309 }
310 #endif
311
312 // obviously this is the windows version
313 #ifdef GUID_WINDOWS
314 Guid newGuid()
315 {
316 GUID newId;
317 CoCreateGuid(&newId);
318
319 std::array<unsigned char, 16> bytes =
320 {
321 (unsigned char)((newId.Data1 >> 24) & 0xFF),
322 (unsigned char)((newId.Data1 >> 16) & 0xFF),
323 (unsigned char)((newId.Data1 >> 8) & 0xFF),
324 (unsigned char)((newId.Data1) & 0xff),
325
326 (unsigned char)((newId.Data2 >> 8) & 0xFF),
327 (unsigned char)((newId.Data2) & 0xff),
328
329 (unsigned char)((newId.Data3 >> 8) & 0xFF),
330 (unsigned char)((newId.Data3) & 0xFF),
331
332 (unsigned char)newId.Data4[0],
333 (unsigned char)newId.Data4[1],
334 (unsigned char)newId.Data4[2],
335 (unsigned char)newId.Data4[3],
336 (unsigned char)newId.Data4[4],
337 (unsigned char)newId.Data4[5],
338 (unsigned char)newId.Data4[6],
339 (unsigned char)newId.Data4[7]
340 };
341
342 return Guid{std::move(bytes)};
343 }
344 #endif
345
346 // android version that uses a call to a java api
347 #ifdef GUID_ANDROID
348 Guid newGuid(JNIEnv *env)
349 {
350 assert(env != androidInfo.env || std::this_thread::get_id() == androidInfo.initThreadId);
351
352 jobject javaUuid = env->CallStaticObjectMethod(
353 androidInfo.uuidClass, androidInfo.newGuidMethod);
354 jlong mostSignificant = env->CallLongMethod(javaUuid,
355 androidInfo.mostSignificantBitsMethod);
356 jlong leastSignificant = env->CallLongMethod(javaUuid,
357 androidInfo.leastSignificantBitsMethod);
358
359 std::array<unsigned char, 16> bytes =
360 {
361 (unsigned char)((mostSignificant >> 56) & 0xFF),
362 (unsigned char)((mostSignificant >> 48) & 0xFF),
363 (unsigned char)((mostSignificant >> 40) & 0xFF),
364 (unsigned char)((mostSignificant >> 32) & 0xFF),
365 (unsigned char)((mostSignificant >> 24) & 0xFF),
366 (unsigned char)((mostSignificant >> 16) & 0xFF),
367 (unsigned char)((mostSignificant >> 8) & 0xFF),
368 (unsigned char)((mostSignificant) & 0xFF),
369 (unsigned char)((leastSignificant >> 56) & 0xFF),
370 (unsigned char)((leastSignificant >> 48) & 0xFF),
371 (unsigned char)((leastSignificant >> 40) & 0xFF),
372 (unsigned char)((leastSignificant >> 32) & 0xFF),
373 (unsigned char)((leastSignificant >> 24) & 0xFF),
374 (unsigned char)((leastSignificant >> 16) & 0xFF),
375 (unsigned char)((leastSignificant >> 8) & 0xFF),
376 (unsigned char)((leastSignificant) & 0xFF)
377 };
378
379 env->DeleteLocalRef(javaUuid);
380
381 return Guid{std::move(bytes)};
382 }
383
384 Guid newGuid()
385 {
386 return newGuid(androidInfo.env);
387 }
388 #endif
389
390
391 END_XG_NAMESPACE
392
393 // Specialization for std::swap<Guid>() --
394 // call member swap function of lhs, passing rhs
395 namespace std
396 {
397 template <>
398 void swap(xg::Guid &lhs, xg::Guid &rhs) noexcept
399 {
400 lhs.swap(rhs);
401 }
402 }
0 #include "Test.hpp"
1
2 int test(std::ostream &outStream)
3 {
4 int failed = 0;
5
6 /*************************************************************************
7 * HAPPY PATH TESTS
8 *************************************************************************/
9
10 auto r1 = xg::newGuid();
11 auto r2 = xg::newGuid();
12 auto r3 = xg::newGuid();
13
14 outStream << r1 << std::endl << r2 << std::endl << r3 << std::endl;
15
16 xg::Guid s1("7bcd757f-5b10-4f9b-af69-1a1f226f3b3e");
17 xg::Guid s2("16d1bd03-09a5-47d3-944b-5e326fd52d27");
18 xg::Guid s3("fdaba646-e07e-49de-9529-4499a5580c75");
19 xg::Guid s4("7bcd757f-5b10-4f9b-af69-1a1f226f3b3e");
20 xg::Guid s5("7bcd757f-5b10-4f9b-af69-1a1f226f3b31");
21
22 if (r1 == r2 || r1 == r3 || r2 == r3)
23 {
24 outStream << "FAIL - not all random guids are different" << std::endl;
25 failed++;
26 }
27
28 if (s1 == s2)
29 {
30 outStream << "FAIL - s1 and s2 should be different" << std::endl;
31 failed++;
32 }
33
34 if (s1 != s4)
35 {
36 outStream << "FAIL - s1 and s4 should be equal" << std::endl;
37 failed++;
38 }
39
40 if (s4 < s5) {
41 outStream << "FAIL - s5 should should less than s4" << std::endl;
42 failed++;
43 }
44
45 std::stringstream ss1;
46 ss1 << s1;
47 if (ss1.str() != "7bcd757f-5b10-4f9b-af69-1a1f226f3b3e")
48 {
49 outStream << "FAIL - string from s1 stream is wrong" << std::endl;
50 outStream << "--> " << ss1.str() << std::endl;
51 failed++;
52 }
53
54 if (s1.str() != "7bcd757f-5b10-4f9b-af69-1a1f226f3b3e")
55 {
56 outStream << "FAIL - string from s1.str() is wrong" << std::endl;
57 outStream << "--> " << s1.str() << std::endl;
58 failed++;
59 }
60
61 std::stringstream ss2;
62 ss2 << s2;
63 if (ss2.str() != "16d1bd03-09a5-47d3-944b-5e326fd52d27")
64 {
65 outStream << "FAIL - string generated from s2 is wrong" << std::endl;
66 outStream << "--> " << ss2.str() << std::endl;
67 return 1;
68 }
69
70 std::stringstream ss3;
71 ss3 << s3;
72 if (ss3.str() != "fdaba646-e07e-49de-9529-4499a5580c75")
73 {
74 outStream << "FAIL - string generated from s3 is wrong" << std::endl;
75 outStream << "--> " << ss3.str() << std::endl;
76 failed++;
77 }
78
79 auto swap1 = xg::newGuid();
80 auto swap2 = xg::newGuid();
81 auto swap3 = swap1;
82 auto swap4 = swap2;
83
84 if (swap1 != swap3 || swap2 != swap4 || swap1 == swap2)
85 {
86 outStream << "FAIL - swap guids have bad initial state" << std::endl;
87 failed++;
88 }
89
90 swap1.swap(swap2);
91
92 if (swap1 != swap4 || swap2 != swap3 || swap1 == swap2)
93 {
94 outStream << "FAIL - swap didn't swap" << std::endl;
95 failed++;
96 }
97
98 {
99 std::unordered_map<xg::Guid, int> m = {{s1, 1}, {s2, 2}};
100 auto it1 = m.find(s1);
101 auto it2 = m.find(s2);
102 if(!( it1 != m.end() && it1->first == s1 && it1->second == 1 && it2 != m.end() && it2->first == s2 && it2->second == 2))
103 {
104 outStream << "FAIL - map/hash failed!" << std::endl;
105 failed++;
106 }
107 auto it3 = m.find(s3);
108 if(it3 != m.end())
109 {
110 outStream << "FAIL - map/hash failed!" << std::endl;
111 failed++;
112 }
113 }
114 std::array<unsigned char, 16> bytes =
115 {{
116 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
117 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xdd
118 }};
119 xg::Guid guidFromBytes(bytes);
120 xg::Guid guidFromString("0102030405060708090a0b0c0d0e0fdd");
121 if (guidFromBytes != guidFromString)
122 {
123 outStream << "FAIL - String/bytes make different guids" << std::endl;
124 failed++;
125 }
126
127 if(!std::equal(guidFromBytes.bytes().begin(), guidFromBytes.bytes().end(), bytes.begin()))
128 {
129 outStream << "FAIL - array returned from bytes() is wrong" << std::endl;
130 failed++;
131 }
132
133 /*************************************************************************
134 * ERROR HANDLING
135 *************************************************************************/
136
137 xg::Guid empty;
138 xg::Guid twoTooFew("7bcd757f-5b10-4f9b-af69-1a1f226f3b");
139 if (twoTooFew != empty || twoTooFew.isValid())
140 {
141 outStream << "FAIL - Guid from two too few chars" << std::endl;
142 failed++;
143 }
144
145 xg::Guid oneTooFew("16d1bd03-09a5-47d3-944b-5e326fd52d2");
146 if (oneTooFew != empty || oneTooFew.isValid())
147 {
148 outStream << "FAIL - Guid from one too few chars" << std::endl;
149 failed++;
150 }
151
152 xg::Guid twoTooMany("7bcd757f-5b10-4f9b-af69-1a1f226f3beeff");
153 if (twoTooMany != empty || twoTooMany.isValid())
154 {
155 outStream << "FAIL - Guid from two too many chars" << std::endl;
156 failed++;
157 }
158
159 xg::Guid oneTooMany("16d1bd03-09a5-47d3-944b-5e326fd52d27a");
160 if (oneTooMany != empty || oneTooMany.isValid())
161 {
162 outStream << "FAIL - Guid from one too many chars" << std::endl;
163 failed++;
164 }
165
166 xg::Guid badString("!!bad-guid-string!!");
167 if (badString != empty || badString.isValid())
168 {
169 outStream << "FAIL - Guid from bad string" << std::endl;
170 failed++;
171 }
172
173 if (failed == 0)
174 {
175 outStream << "All tests passed!" << std::endl;
176 return 0;
177 }
178 else
179 {
180 outStream << failed << " tests failed." << std::endl;
181 return 1;
182 }
183 }
0 #pragma once
1
2 #include <crossguid/guid.hpp>
3 #include <iostream>
4 #include <unordered_map>
5
6 int test(std::ostream &outStream);
0 #include "Test.hpp"
1 #include <iostream>
2
3 int main()
4 {
5 return test(std::cout);
6 }
+0
-63
test.cpp less more
0 #include "guid.h"
1
2 using namespace std;
3
4 int test(GuidGenerator generator, std::ostream &outStream)
5 {
6 auto r1 = generator.newGuid();
7 auto r2 = generator.newGuid();
8 auto r3 = generator.newGuid();
9
10 outStream << r1 << endl << r2 << endl << r3 << endl;
11
12 Guid s1("7bcd757f-5b10-4f9b-af69-1a1f226f3b3e");
13 Guid s2("16d1bd03-09a5-47d3-944b-5e326fd52d27");
14 Guid s3("fdaba646-e07e-49de-9529-4499a5580c75");
15 Guid s4("7bcd757f-5b10-4f9b-af69-1a1f226f3b3e");
16
17 if (r1 == r2 || r1 == r3 || r2 == r3)
18 {
19 outStream << "FAIL - not all random guids are different" << endl;
20 return 1;
21 }
22
23 if (s1 == s2)
24 {
25 outStream << "FAIL - s1 and s2 should be different" << endl;
26 return 1;
27 }
28
29 if (s1 != s4)
30 {
31 outStream << "FAIL - s1 and s4 should be equal" << endl;
32 return 1;
33 }
34
35 stringstream ss1;
36 ss1 << s1;
37 if (ss1.str() != "7bcd757f-5b10-4f9b-af69-1a1f226f3b3e")
38 {
39 outStream << "FAIL - string generated from s1 is wrong" << endl;
40 return 1;
41 }
42
43 stringstream ss2;
44 ss2 << s2;
45 if (ss2.str() != "16d1bd03-09a5-47d3-944b-5e326fd52d27")
46 {
47 outStream << "FAIL - string generated from s2 is wrong" << endl;
48 return 1;
49 }
50
51 stringstream ss3;
52 ss3 << s3;
53 if (ss3.str() != "fdaba646-e07e-49de-9529-4499a5580c75")
54 {
55 outStream << "FAIL - string generated from s3 is wrong" << endl;
56 return 1;
57 }
58
59 outStream << "All tests passed!" << endl;
60
61 return 0;
62 }
+0
-6
test.h less more
0 #pragma once
1
2 #include "guid.h"
3 #include <iostream>
4
5 int test(GuidGenerator generator, std::ostream &outStream);
+0
-7
testmain.cpp less more
0 #include "test.h"
1 #include <iostream>
2
3 int main(int argc, char *argv[])
4 {
5 return test(GuidGenerator(), std::cout);
6 }