diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 5be11e2b0..c2817deb5 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,52 +1,8 @@ name: github-actions on: [push, pull_request] jobs: - windows-2019-dynamicLink: - runs-on: windows-2019 - steps: - - uses: actions/checkout@v4 - - name: HDF5 install - run: | - Invoke-WebRequest https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.12/hdf5-1.12.0/bin/hdf5-1.12.0-Std-win10_64-vs16.zip -OutFile ${{ runner.temp }}\hdf5-1.12.0-Std-win10_64-vs16.zip - Expand-Archive ${{ runner.temp }}\hdf5-1.12.0-Std-win10_64-vs16.zip -DestinationPath ${{ runner.temp }} - msiexec.exe /i "${{ runner.temp }}\hdf\HDF5-1.12.0-win64.msi" /qn INSTALL_ROOT=${{ runner.temp }}\hdf5-1.12.0-Std-win10_64-vs16 - - name: Minizip DLL install - run: | - git clone https://github.com/F2I-Consulting/Minizip.git ${{ runner.temp }}/Minizip - cd ${{ runner.temp }} - mkdir minizip-build - cd minizip-build - cmake -G"Visual Studio 16 2019" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DZLIB_ROOT=${{ runner.temp }}/hdf5-1.12.0-Std-win10_64-vs16 -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/minizip-install ${{ runner.temp }}/Minizip - cmake --build . --config Release -j2 - cmake --build . --config Release --target INSTALL - - name: Boost install - run: | - (New-Object System.Net.WebClient).DownloadFile("https://archives.boost.io/release/1.87.0/binaries/boost_1_87_0-msvc-14.2-64.exe", "${{ runner.temp }}\boost.exe") - Start-Process -Wait -FilePath "${{ runner.temp }}\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=${{ runner.temp }}\boost-install" - - name: CMake build and install - run: | - cd ${{ github.workspace }}/.. - mkdir build - cd build - cmake -G"Visual Studio 16 2019" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DHDF5_ROOT=${{ runner.temp }}\hdf5-1.12.0-Std-win10_64-vs16 -DMINIZIP_ROOT=${{ runner.temp }}/minizip-install -DZLIB_ROOT=${{ runner.temp }}\hdf5-1.12.0-Std-win10_64-vs16 -DSZIP_LIBRARY_RELEASE=${{ runner.temp }}\hdf5-1.12.0-Std-win10_64-vs16/lib/szip.lib -DBoost_INCLUDE_DIR=${{ runner.temp }}\boost-install -DWITH_EXAMPLE=TRUE -DWITH_RESQML2_2=TRUE -DWITH_TEST=TRUE -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/fesapi-install ${{ github.workspace }} - cmake --build . --config Release -j2 - cmake --build . --config Release --target INSTALL - - name: Copy hdf5 dll - run: | - Copy-Item ${{ runner.temp }}\hdf5-1.12.0-Std-win10_64-vs16\bin\hdf5.dll -Destination ${{ github.workspace }}\..\build\Release - Copy-Item ${{ runner.temp }}\hdf5-1.12.0-Std-win10_64-vs16\bin\zlib.dll -Destination ${{ github.workspace }}\..\build\Release - - name: Run Unit tests - run: | - ${{ github.workspace }}\..\build\Release\unitTest - - name: Run Cpp example - run: | - ${{ github.workspace }}\..\build\Release\example.exe - - uses: actions/upload-artifact@v4 - with: - name: windows-2019 - path: ${{ runner.temp }}/fesapi-install - windows-2019-staticLink-cs: - runs-on: windows-2019 + windows-2022-staticLink-cs: + runs-on: windows-2022 steps: - uses: actions/checkout@v4 - name: zlib install @@ -56,7 +12,7 @@ jobs: tar -xzf ${{ runner.temp }}\zlib.tar.gz mkdir zlib-build cd zlib-build - cmake -G"Visual Studio 16 2019" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/zlib-install ${{ runner.temp }}/zlib-1.3.1 + cmake -G"Visual Studio 17 2022" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/zlib-install ${{ runner.temp }}/zlib-1.3.1 cmake --build . --config Release -j2 cmake --build . --config Release --target INSTALL - name: Minizip static lib install @@ -65,33 +21,33 @@ jobs: cd ${{ runner.temp }} mkdir minizip-build cd minizip-build - cmake -G"Visual Studio 16 2019" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DBUILD_SHARED_LIBS=FALSE -DZLIB_ROOT=${{ runner.temp }}/zlib-install -DZLIB_USE_STATIC_LIBS=TRUE -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/minizip-install ${{ runner.temp }}/Minizip + cmake -G"Visual Studio 17 2022" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DBUILD_SHARED_LIBS=FALSE -DZLIB_ROOT=${{ runner.temp }}/zlib-install -DZLIB_USE_STATIC_LIBS=TRUE -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/minizip-install ${{ runner.temp }}/Minizip cmake --build . --config Release -j2 cmake --build . --config Release --target INSTALL - name: HDF5 install run: | - Invoke-WebRequest https://support.hdfgroup.org/releases/hdf5/v1_14/v1_14_5/downloads/hdf5-1.14.5.zip -OutFile ${{ runner.temp }}\hdf5-1.14.5.zip + Invoke-WebRequest https://support.hdfgroup.org/releases/hdf5/v1_14/v1_14_6/downloads/hdf5-1.14.6.zip -OutFile ${{ runner.temp }}\hdf5-1.14.6.zip cd ${{ runner.temp }} - Expand-Archive ${{ runner.temp }}\hdf5-1.14.5.zip -DestinationPath ${{ runner.temp }} + Expand-Archive ${{ runner.temp }}\hdf5-1.14.6.zip -DestinationPath ${{ runner.temp }} mkdir hdf5-build cd hdf5-build - cmake -G"Visual Studio 16 2019" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DHDF5_ENABLE_Z_LIB_SUPPORT:BOOL=ON -DZLIB_INCLUDE_DIR:PATH=${{ runner.temp }}/zlib-install/include -DZLIB_LIBRARY:PATH=${{ runner.temp }}/zlib-install/lib/zlibstatic.lib -DHDF5_BUILD_FORTRAN:BOOL=OFF -DHDF5_BUILD_JAVA:BOOL=OFF -DHDF5_ENABLE_PARALLEL:BOOL=OFF -DHDF5_BUILD_CPP_LIB:BOOL=OFF -DHDF5_BUILD_HL_LIB:BOOL=OFF -DHDF5_BUILD_EXAMPLES:BOOL=OFF -DHDF5_BUILD_GENERATORS:BOOL=OFF -DHDF5_BUILD_TOOLS:BOOL=OFF -DHDF5_BUILD_UTILS:BOOL=OFF -DBUILD_TESTING:BOOL=OFF -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/hdf5-install ${{ runner.temp }}/hdf5-1.14.5 + cmake -G"Visual Studio 17 2022" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DHDF5_ENABLE_Z_LIB_SUPPORT:BOOL=ON -DZLIB_INCLUDE_DIR:PATH=${{ runner.temp }}/zlib-install/include -DZLIB_LIBRARY:PATH=${{ runner.temp }}/zlib-install/lib/zlibstatic.lib -DHDF5_BUILD_FORTRAN:BOOL=OFF -DHDF5_BUILD_JAVA:BOOL=OFF -DHDF5_ENABLE_PARALLEL:BOOL=OFF -DHDF5_BUILD_CPP_LIB:BOOL=OFF -DHDF5_BUILD_HL_LIB:BOOL=OFF -DHDF5_BUILD_EXAMPLES:BOOL=OFF -DHDF5_BUILD_GENERATORS:BOOL=OFF -DHDF5_BUILD_TOOLS:BOOL=OFF -DHDF5_BUILD_UTILS:BOOL=OFF -DBUILD_TESTING:BOOL=OFF -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/hdf5-install ${{ runner.temp }}/hdf5-1.14.6 cmake --build . --config Release -j2 cmake --build . --config Release --target INSTALL - name: Boost install run: | - (New-Object System.Net.WebClient).DownloadFile("https://archives.boost.io/release/1.87.0/binaries/boost_1_87_0-msvc-14.2-64.exe", "${{ runner.temp }}\boost.exe") + (New-Object System.Net.WebClient).DownloadFile("https://archives.boost.io/release/1.88.0/binaries/boost_1_88_0-msvc-14.3-64.exe", "${{ runner.temp }}\boost.exe") Start-Process -Wait -FilePath "${{ runner.temp }}\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=${{ runner.temp }}\boost-install" - name: Swig install run: | - (New-Object System.Net.WebClient).DownloadFile("http://prdownloads.sourceforge.net/swig/swigwin-4.3.0.zip", "${{ runner.temp }}\swigwin-4.3.0.zip") - 7z x ${{ runner.temp }}\swigwin-4.3.0.zip -o${{ runner.temp }} + (New-Object System.Net.WebClient).DownloadFile("http://prdownloads.sourceforge.net/swig/swigwin-4.3.1.zip", "${{ runner.temp }}\swigwin-4.3.1.zip") + 7z x ${{ runner.temp }}\swigwin-4.3.1.zip -o${{ runner.temp }} - name: CMake build and install run: | cd ${{ github.workspace }}/.. mkdir build cd build - cmake -G"Visual Studio 16 2019" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DHDF5_ROOT=${{ runner.temp }}/hdf5-install -DHDF5_USE_STATIC_LIBRARIES=TRUE -DMINIZIP_ROOT=${{ runner.temp }}/minizip-install -DZLIB_ROOT=${{ runner.temp }}/zlib-install -DZLIB_USE_STATIC_LIBS=TRUE -DBoost_INCLUDE_DIR=${{ runner.temp }}/boost-install -DWITH_EXAMPLE=TRUE -DWITH_RESQML2_2=TRUE -DWITH_DOTNET_WRAPPING=TRUE -DSWIG_EXECUTABLE=${{ runner.temp }}/swigwin-4.3.0/swig.exe -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/fesapi-install ${{ github.workspace }} + cmake -G"Visual Studio 17 2022" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DHDF5_ROOT=${{ runner.temp }}/hdf5-install -DHDF5_USE_STATIC_LIBRARIES=TRUE -DMINIZIP_ROOT=${{ runner.temp }}/minizip-install -DZLIB_ROOT=${{ runner.temp }}/zlib-install -DZLIB_USE_STATIC_LIBS=TRUE -DBoost_INCLUDE_DIR=${{ runner.temp }}/boost-install -DWITH_EXAMPLE=TRUE -DWITH_RESQML2_2=TRUE -DWITH_DOTNET_WRAPPING=TRUE -DSWIG_EXECUTABLE=${{ runner.temp }}/swigwin-4.3.1/swig.exe -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/fesapi-install ${{ github.workspace }} cmake --build . --config Release -j2 cmake --build . --config Release --target INSTALL - name: Add msbuild to PATH @@ -109,21 +65,20 @@ jobs: - name: Run C# example run: | ${{ github.workspace }}\cs\example\bin\x64\Release\example.exe - ubuntu-20-java11: - runs-on: ubuntu-20.04 + ubuntu-22-java11: + runs-on: ubuntu-22.04 strategy: fail-fast: false # 'false' means Don't stop matrix workflows even if some matrix failed. matrix: include: [ { xcc_name: 'gcc 9', xcc_pkg: gcc-9, cc: gcc-9, cxx: g++-9 }, { xcc_name: 'gcc 10', xcc_pkg: gcc-10, cc: gcc-10, cxx: g++-10 }, - { xcc_name: 'clang 9', xcc_pkg: clang-9, cc: clang-9, cxx: clang++-9 }, - { xcc_name: 'clang 10', xcc_pkg: clang-10, cc: clang-10, cxx: clang++-10 }, { xcc_name: 'clang 11', xcc_pkg: clang-11, cc: clang-11, cxx: clang++-11 }, - # { xcc_name: 'clang 12', xcc_pkg: clang-12, cc: clang, cxx: clang++ }, + { xcc_name: 'clang 12', xcc_pkg: clang-12, cc: clang-12, cxx: clang++-12 }, + { xcc_name: 'clang 13', xcc_pkg: clang-13, cc: clang-13, cxx: clang++-13 }, ] env: - XCC: $${{ matrix.xcc_name }} + XCC: ${{ matrix.xcc_name }} CC: ${{ matrix.cc }} CXX: ${{ matrix.cxx }} steps: @@ -164,7 +119,7 @@ jobs: java -Djava.library.path=${{ runner.temp }}/fesapi-install/lib -cp `find ${{ runner.temp }}/fesapi-install -name fesapiJava*.jar`:. com.f2i_consulting.example.FesapiJavaExample - uses: actions/upload-artifact@v4 with: - name: ubuntu-20.04-${{ matrix.cxx }} + name: ubuntu-22.04-${{ matrix.cxx }} path: ${{ runner.temp }}/fesapi-install build_wheels_windows: name: Build wheels on windows-latest @@ -289,7 +244,7 @@ jobs: name: cibw-wheels-macosx_arm64 path: ./wheelhouse/*.whl ubuntu-20-mpi: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v4 @@ -333,7 +288,7 @@ jobs: ${{ github.workspace }}/../build/test/unitTest webassembly: if: false - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: mymindstorm/setup-emsdk@v11 - uses: actions/checkout@v4 diff --git a/CMakeLists.txt b/CMakeLists.txt index aa9981872..45f16b426 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,9 +12,9 @@ set (FESAPI_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) # version mechanism set (Fesapi_VERSION_MAJOR 2) -set (Fesapi_VERSION_MINOR 12) -set (Fesapi_VERSION_PATCH 2) -set (Fesapi_VERSION_TWEAK 1) +set (Fesapi_VERSION_MINOR 13) +set (Fesapi_VERSION_PATCH 0) +set (Fesapi_VERSION_TWEAK 0) set (Fesapi_VERSION ${Fesapi_VERSION_MAJOR}.${Fesapi_VERSION_MINOR}.${Fesapi_VERSION_PATCH}.${Fesapi_VERSION_TWEAK}) diff --git a/cmake/AssemblyInfo.cs b/cmake/AssemblyInfo.cs index f1258b33a..cc7b1206d 100644 --- a/cmake/AssemblyInfo.cs +++ b/cmake/AssemblyInfo.cs @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("F2I-CONSULTING")] [assembly: AssemblyProduct("FesapiCs")] -[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/cmake/FesapiJavaExample.java b/cmake/FesapiJavaExample.java index 2138cf654..537ede8c3 100644 --- a/cmake/FesapiJavaExample.java +++ b/cmake/FesapiJavaExample.java @@ -23,6 +23,7 @@ Licensed to the Apache Software Foundation (ASF) under one import java.util.stream.LongStream; import com.f2i_consulting.fesapi.SWIGTYPE_p_double; +import com.f2i_consulting.fesapi.SWIGTYPE_p_unsigned_char; import com.f2i_consulting.fesapi.SWIGTYPE_p_unsigned_int; import com.f2i_consulting.fesapi.SWIGTYPE_p_unsigned_short; import com.f2i_consulting.fesapi.StringVector; @@ -537,27 +538,27 @@ private static void serializeGraphicalInformationSet(DataObjectRepository repo, // associating a discrete color map to dicreteProp1 DiscreteColorMap discrColMap = repo.createDiscreteColorMap("3daf4661-ae8f-4357-adee-0b0159bdd0a9", "Discrete color map"); - SWIGTYPE_p_unsigned_int discrColMapRgbColors = fesapi.new_UInt32Array(18); + SWIGTYPE_p_unsigned_char discrColMapRgbColors = fesapi.new_UInt8Array(18); SWIGTYPE_p_double discrColMapAlphas = fesapi.new_DoubleArray(6); try { - fesapi.UInt32Array_setitem(discrColMapRgbColors, 0, 255); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 1, 0); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 2, 0); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 3, 0); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 4, 255); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 5, 0); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 6, 0); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 7, 0); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 8, 255); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 9, 169); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 10, 84); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 11, 27); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 12, 0); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 13, 0); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 14, 0); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 15, 255); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 16, 255); - fesapi.UInt32Array_setitem(discrColMapRgbColors, 17, 255); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 0L, (short) 255); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 1L, (short) 0); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 2L, (short) 0); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 3L, (short) 0); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 4L, (short) 255); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 5L, (short) 0); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 6L, (short) 0); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 7L, (short) 0); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 8L, (short) 255); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 9L, (short) 169); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 10L, (short) 84); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 11L, (short) 27); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 12L, (short) 0); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 13L, (short) 0); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 14L, (short) 0); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 15L, (short) 255); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 16L, (short) 255); + fesapi.UInt8Array_setitem(discrColMapRgbColors, 17L, (short) 255); fesapi.DoubleArray_setitem(discrColMapAlphas, 0, 1.); fesapi.DoubleArray_setitem(discrColMapAlphas, 1, 1.); @@ -574,10 +575,10 @@ private static void serializeGraphicalInformationSet(DataObjectRepository repo, discrColMapTitles.add("black"); discrColMapTitles.add("white"); - discrColMap.setRgbColors(6, discrColMapRgbColors, discrColMapAlphas, discrColMapTitles); + discrColMap.setRgbColors(6, discrColMapRgbColors, discrColMapAlphas, null, discrColMapTitles); } finally { - fesapi.delete_UInt32Array(discrColMapRgbColors); + fesapi.delete_UInt8Array(discrColMapRgbColors); fesapi.delete_DoubleArray(discrColMapAlphas); } @@ -627,15 +628,15 @@ private static void serializeGraphicalInformationSet(DataObjectRepository repo, contColMapContProp.pushBackDoubleHdf5Array2dOfValues(values, numPointInFastestDirection, numPointsInSlowestDirection, hdfProxy); ContinuousColorMap contColMap = repo.createContinuousColorMap("a207faa2-963e-48d6-b3ad-53f6c1fc4dd4", "Continuous color map", resqml22__InterpolationDomain.rgb, resqml22__InterpolationMethod.linear); - SWIGTYPE_p_unsigned_int contColMapRgbColors = fesapi.new_UInt32Array(6); + SWIGTYPE_p_unsigned_char contColMapRgbColors = fesapi.new_UInt8Array(6); SWIGTYPE_p_double contColMapAlphas = fesapi.new_DoubleArray(2); try { - fesapi.UInt32Array_setitem(contColMapRgbColors, 0, 0); - fesapi.UInt32Array_setitem(contColMapRgbColors, 1, 255); - fesapi.UInt32Array_setitem(contColMapRgbColors, 2, 0); - fesapi.UInt32Array_setitem(contColMapRgbColors, 3, 255); - fesapi.UInt32Array_setitem(contColMapRgbColors, 4, 0); - fesapi.UInt32Array_setitem(contColMapRgbColors, 5, 0); + fesapi.UInt8Array_setitem(contColMapRgbColors, 0L, (short) 0); + fesapi.UInt8Array_setitem(contColMapRgbColors, 1L, (short) 255); + fesapi.UInt8Array_setitem(contColMapRgbColors, 2L, (short) 0); + fesapi.UInt8Array_setitem(contColMapRgbColors, 3L, (short) 255); + fesapi.UInt8Array_setitem(contColMapRgbColors, 4L, (short) 0); + fesapi.UInt8Array_setitem(contColMapRgbColors, 5L, (short) 0); fesapi.DoubleArray_setitem(contColMapAlphas, 0, 1.); fesapi.DoubleArray_setitem(contColMapAlphas, 1, 1.); @@ -644,10 +645,10 @@ private static void serializeGraphicalInformationSet(DataObjectRepository repo, contColMapColTitles.add("green"); contColMapColTitles.add("red"); - contColMap.setRgbColors(2, contColMapRgbColors, contColMapAlphas, contColMapColTitles); + contColMap.setRgbColors(2, contColMapRgbColors, contColMapAlphas, null, contColMapColTitles); } finally { - fesapi.delete_UInt32Array(contColMapRgbColors); + fesapi.delete_UInt8Array(contColMapRgbColors); fesapi.delete_DoubleArray(contColMapAlphas); } @@ -672,20 +673,18 @@ private static void serialize() serializeGraphicalInformationSet(repo, hdfProxy); ${COMMENT_END} - try (EpcDocument pck = new EpcDocument(storageDirectory + File.separator + epcName + ".epc")) { - pck.serializeFrom(repo); - } + EpcDocument pck = new EpcDocument(storageDirectory + File.separator + epcName + ".epc"); + pck.serializeFrom(repo); } } private static void deserialize() { try (DataObjectRepository repo = new DataObjectRepository()) { - try (EpcDocument pck = new EpcDocument(storageDirectory + File.separator + epcName + ".epc")) { - String status = pck.deserializeInto(repo); - if (!status.isEmpty()) { - System.out.println("Status : " + status); - } + EpcDocument pck = new EpcDocument(storageDirectory + File.separator + epcName + ".epc"); + String status = pck.deserializeInto(repo); + if (!status.isEmpty()) { + System.out.println("Status : " + status); } LongStream.range(0, repo.getLocal3dCrsCount()).forEach(index -> System.out.println("CRS title is " + repo.getLocal3dCrs(index).getTitle())); @@ -769,12 +768,12 @@ private static void deserialize() if (graphicalInformationSet.hasDiscreteColorMap(targetObject)) { DiscreteColorMap discreteColorMap = graphicalInformationSet.getDiscreteColorMap(targetObject); System.out.println("discrete color map title: " + discreteColorMap.getTitle()); - SWIGTYPE_p_unsigned_int r = fesapi.new_UInt32Array(1); - SWIGTYPE_p_unsigned_int g = fesapi.new_UInt32Array(1); - SWIGTYPE_p_unsigned_int b = fesapi.new_UInt32Array(1); + SWIGTYPE_p_unsigned_char r = fesapi.new_UInt8Array(1); + SWIGTYPE_p_unsigned_char g = fesapi.new_UInt8Array(1); + SWIGTYPE_p_unsigned_char b = fesapi.new_UInt8Array(1); for (int colorIndex = 0; colorIndex < discreteColorMap.getColorCount(); ++colorIndex) { discreteColorMap.getRgbColor(colorIndex, r, g, b); - System.out.print(colorIndex + ": (" + fesapi.UInt32Array_getitem(r, 0) + ", " + fesapi.UInt32Array_getitem(g, 0) + ", " + fesapi.UInt32Array_getitem(b, 0) + ", "); + System.out.print(colorIndex + ": (" + fesapi.UInt8Array_getitem(r, 0) + ", " + fesapi.UInt8Array_getitem(g, 0) + ", " + fesapi.UInt8Array_getitem(b, 0) + ", "); System.out.print(discreteColorMap.getAlpha(colorIndex)); if (discreteColorMap.hasColorTitle(colorIndex)) { System.out.print(", " + discreteColorMap.getColorTitle(colorIndex)); diff --git a/cmake/Program.cs b/cmake/Program.cs index 1ef2d47cf..0d0267757 100644 --- a/cmake/Program.cs +++ b/cmake/Program.cs @@ -253,10 +253,6 @@ private static void serialize() dummyPoints.setitem(2, 3.0); repo.createPointSetRepresentation("", "").pushBackXyzGeometryPatch(1, dummyPoints.cast()); dummyPoints.Dispose(); - // ************************************** - // ************************************** - - epc_file.close(); } } diff --git a/cmake/fesapiCs.csproj.template b/cmake/fesapiCs.csproj.template index 6ff7f0353..bbc5ca954 100644 --- a/cmake/fesapiCs.csproj.template +++ b/cmake/fesapiCs.csproj.template @@ -10,7 +10,11 @@ Properties f2i.energisticsStandardsApi ${CS_LIBRARY_NAME} + + + v4.8 512 diff --git a/cs/CMakeLists.txt b/cs/CMakeLists.txt index 87530a02a..b362f4aac 100644 --- a/cs/CMakeLists.txt +++ b/cs/CMakeLists.txt @@ -65,3 +65,13 @@ endif () #file(TO_NATIVE_PATH "${FESAPI_ROOT_DIR}/cs/src" DOS_STYLE_SOURCE_DIR) configure_file(${FESAPI_ROOT_DIR}/cmake/fesapiCs.csproj.template ${FESAPI_ROOT_DIR}/cs/fesapiCs.csproj) # Overwrite if different configure_file(${FESAPI_ROOT_DIR}/cmake/AssemblyInfo.cs ${FESAPI_ROOT_DIR}/cs/Properties/AssemblyInfo.cs) # Overwrite if different + +install ( + DIRECTORY ${FESAPI_ROOT_DIR}/cs/ + DESTINATION ./csProject + PATTERN "bin" EXCLUDE + PATTERN "example" EXCLUDE + PATTERN "obj" EXCLUDE + PATTERN ".gitignore" EXCLUDE + PATTERN "CMakeLists.txt" EXCLUDE +) diff --git a/cs/example/example.csproj b/cs/example/example.csproj index f6d62634d..7b74c2478 100644 --- a/cs/example/example.csproj +++ b/cs/example/example.csproj @@ -8,8 +8,12 @@ Exe Properties example - example + + + v4.8 + example 512 publier\ diff --git a/example/example.cpp b/example/example.cpp index dd1140e34..df4032d13 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -302,6 +302,7 @@ void serializeWells(COMMON_NS::DataObjectRepository * repo, EML2_NS::AbstractHdf #if WITH_RESQML2_2 else { unitNumberPropType = repo->createPropertyKind("358aac23-b377-4349-9e72-bff99a6edf34", "Unit number", gsoap_eml2_3::eml23__QuantityClassKind::not_x0020a_x0020measure); + static_cast(unitNumberPropType)->setDeprecationDate(unitNumberPropType->getCreation() + 3600); } #endif @@ -617,7 +618,7 @@ void serializeBoundaries(COMMON_NS::DataObjectRepository * repo, EML2_NS::Abstra //************** // Horizon Representations //************** - RESQML2_NS::PolylineRepresentation* h1i1SinglePolylineRep = repo->createPolylineRepresentation(horizon1Interp1, "", "Horizon1 Interp1 SinglePolylineRep"); + RESQML2_NS::PolylineRepresentation* h1i1SinglePolylineRep = repo->createPolylineRepresentation(horizon1Interp1, "47f86668-27c4-4b28-a19e-bd0355321ecc", "Horizon1 Interp1 SinglePolylineRep"); double h1i1SinglePolylineRepPoints[12] = { 0, 100, 300, 150, 110, 300, 450, 130, 350, 600, 140, 350 }; h1i1SinglePolylineRep->setGeometry(h1i1SinglePolylineRepPoints, 4, hdfProxy); double seismicLineAbscissa[4] = { 0.0, 1.0, 3.0, 4.0 }; @@ -5107,7 +5108,6 @@ void deserialize(const string & inputFile) cerr << resqmlResult << endl; repo.clearWarnings(); } - epcDoc.close(); const unsigned int hdfProxyCount = repo.getHdfProxyCount(); cout << "There are " << hdfProxyCount << " hdf files associated to this epc document." << endl; @@ -5678,20 +5678,20 @@ void appendAContinuousProp(const string& filePath) } // filepath is defined in a macro to better check memory leak -#define filePath "../../testingPackageCpp.epc" +#define filePath u8"../../testingPackageCpp.epc" int main() { - //try { + try { if (serialize(filePath)) { appendAContinuousProp(filePath); deserialize(filePath); } - /*} + } catch (const std::invalid_argument & Exp) { std::cerr << "Error : " << Exp.what() << ".\n"; return 1; - }*/ + } #ifdef _WIN32 _CrtDumpMemoryLeaks(); diff --git a/example/exampleMPI.cpp b/example/exampleMPI.cpp index 557189890..b8e77b99b 100644 --- a/example/exampleMPI.cpp +++ b/example/exampleMPI.cpp @@ -97,7 +97,6 @@ void deserialize(const std::string filename) { std::cerr << resqmlResult << std::endl; repo.clearWarnings(); } - pck.close(); auto* unstructuredGrid_4cells = repo.getUnstructuredGridRepresentation(0); RESQML2_NS::ContinuousProperty* prop = dynamic_cast(unstructuredGrid_4cells->getValuesProperty(0)); diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index 877ab3bdc..3ac805eb6 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -32,9 +32,9 @@ file (REMOVE_RECURSE ${FESAPI_ROOT_DIR}/java/src/com/f2i_consulting/fesapi/prodm # The name of the library is different on Windows because it includes the version if (WIN32) if (SWIG_LINKED_TO_RELEASE) - set (ASSEMBLY_NAME ${CPP_LIBRARY_NAME}${CMAKE_RELEASE_POSTFIX}.${Fesapi_VERSION}) + set (ASSEMBLY_NAME ${CPP_LIBRARY_NAME}${CMAKE_RELEASE_POSTFIX}-${Fesapi_VERSION_MAJOR}.${Fesapi_VERSION_MINOR}) else (SWIG_LINKED_TO_RELEASE) - set (ASSEMBLY_NAME ${CPP_LIBRARY_NAME}${CMAKE_DEBUG_POSTFIX}.${Fesapi_VERSION}) + set (ASSEMBLY_NAME ${CPP_LIBRARY_NAME}${CMAKE_DEBUG_POSTFIX}-${Fesapi_VERSION_MAJOR}.${Fesapi_VERSION_MINOR}) endif (SWIG_LINKED_TO_RELEASE) else (WIN32) if (SWIG_LINKED_TO_RELEASE) diff --git a/python/example/example.py b/python/example/example.py index 7b5815282..11d32337f 100644 --- a/python/example/example.py +++ b/python/example/example.py @@ -62,7 +62,6 @@ def serialize(file_name: str): serialize_grid(repo) epc_file.serializeFrom(repo) - epc_file.close() def show_all_metadata(data_object: fesapi.AbstractObject): """ @@ -151,7 +150,6 @@ def deserialize(file_name: str): if not warnings: print(warnings) repo.clearWarnings() - epc_file.close() hdf_proxy_count = repo.getHdfProxyCount() print("There is/are " + str(hdf_proxy_count) + " hdf file(s) associated to this epc document.") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 41413b9f8..dffa13294 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -249,130 +249,141 @@ endif (WITH_PYTHON_WRAPPING) # Install FesapiCpp library # ============================================================================ -INSTALL ( - TARGETS ${CPP_LIBRARY_NAME} - EXPORT FESAPI_TARGETS - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} -) - -INSTALL ( - EXPORT FESAPI_TARGETS - FILE FesapiCppTargets.cmake - DESTINATION - "${CMAKE_INSTALL_LIBDIR}/cmake/fesapi" -) +# Only install include directory if we target CPP +if (NOT WITH_PYTHON_WRAPPING AND NOT WITH_DOTNET_WRAPPING AND NOT WITH_JAVA_WRAPPING) + INSTALL ( + TARGETS ${CPP_LIBRARY_NAME} + EXPORT FESAPI_TARGETS + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) -CONFIGURE_FILE(${FESAPI_ROOT_DIR}/cmake/FesapiCppConfig.cmake.in ${FESAPI_BINARY_DIR}/cmake/FesapiCppConfig.cmake @ONLY) -INSTALL( - FILES - "${FESAPI_BINARY_DIR}/cmake/FesapiCppConfig.cmake" - DESTINATION - "${CMAKE_INSTALL_LIBDIR}/cmake/fesapi" - ) + INSTALL ( + EXPORT FESAPI_TARGETS + FILE FesapiCppTargets.cmake + DESTINATION + "${CMAKE_INSTALL_LIBDIR}/cmake/${CPP_LIBRARY_NAME}" + ) -IF (WIN32) - #PDB for debug + CONFIGURE_FILE(${FESAPI_ROOT_DIR}/cmake/FesapiCppConfig.cmake.in ${FESAPI_BINARY_DIR}/cmake/FesapiCppConfig.cmake @ONLY) + INSTALL( + FILES + "${FESAPI_BINARY_DIR}/cmake/FesapiCppConfig.cmake" + DESTINATION + "${CMAKE_INSTALL_LIBDIR}/cmake/${CPP_LIBRARY_NAME}" + ) + + # namespaces INSTALL ( - FILES $ - CONFIGURATIONS Debug RelWithDebInfo - DESTINATION ${CMAKE_INSTALL_BINDIR} - OPTIONAL + FILES ${FESAPI_ROOT_DIR}/src/nsDefinitions.h ${FESAPI_ROOT_DIR}/src/version_config.h ${FESAPI_ROOT_DIR}/src/MacroDefinitions.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/ + COMPONENT fesapi_headers ) -ENDIF() -# namespaces -INSTALL ( - FILES ${FESAPI_ROOT_DIR}/src/nsDefinitions.h ${FESAPI_ROOT_DIR}/src/version_config.h ${FESAPI_ROOT_DIR}/src/MacroDefinitions.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/ - COMPONENT fesapi_headers -) + # proxies headers + INSTALL ( + FILES ${FESAPI_PROXIES_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/proxies/ + COMPONENT fesapi_headers + ) -# proxies headers -INSTALL ( - FILES ${FESAPI_PROXIES_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/proxies/ - COMPONENT fesapi_headers -) + # common headers + INSTALL ( + FILES ${FESAPI_COMMON_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/common + COMPONENT fesapi_headers + ) -# common headers -INSTALL ( - FILES ${FESAPI_COMMON_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/common - COMPONENT fesapi_headers -) + # EPC headers + INSTALL ( + FILES ${FESAPI_EPC_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/epc/ + COMPONENT fesapi_headers + ) -# EPC headers -INSTALL ( - FILES ${FESAPI_EPC_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/epc/ - COMPONENT fesapi_headers -) + # RESQML headers + INSTALL ( + FILES ${FESAPI_RESQML_2_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${RESQML_PREFIX_2}/ + COMPONENT fesapi_headers + ) -# RESQML headers -INSTALL ( - FILES ${FESAPI_RESQML_2_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${RESQML_PREFIX_2}/ - COMPONENT fesapi_headers -) + INSTALL ( + FILES ${FESAPI_RESQML_2_0_1_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${RESQML_PREFIX_2_0_1}/ + COMPONENT fesapi_headers + ) -INSTALL ( - FILES ${FESAPI_RESQML_2_0_1_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${RESQML_PREFIX_2_0_1}/ - COMPONENT fesapi_headers -) + if (WITH_RESQML2_2) + INSTALL ( + FILES ${FESAPI_RESQML_2_2_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${RESQML_PREFIX_2_2}/ + COMPONENT fesapi_headers + ) + endif (WITH_RESQML2_2) -if (WITH_RESQML2_2) INSTALL ( - FILES ${FESAPI_RESQML_2_2_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${RESQML_PREFIX_2_2}/ + FILES ${FESAPI_EML_2_3_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${EML_PREFIX_2_3}/ COMPONENT fesapi_headers ) -endif (WITH_RESQML2_2) -INSTALL ( - FILES ${FESAPI_EML_2_3_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${EML_PREFIX_2_3}/ - COMPONENT fesapi_headers -) + # WITSML headers + INSTALL ( + FILES ${FESAPI_WITSML_2_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${WITSML_PREFIX_2}/ + ) -# WITSML headers -INSTALL ( - FILES ${FESAPI_WITSML_2_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${WITSML_PREFIX_2}/ -) + INSTALL ( + FILES ${FESAPI_WITSML_2_1_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${WITSML_PREFIX_2_1}/ + COMPONENT fesapi_headers + ) -INSTALL ( - FILES ${FESAPI_WITSML_2_1_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${WITSML_PREFIX_2_1}/ - COMPONENT fesapi_headers -) + # PRODML headers + INSTALL ( + FILES ${FESAPI_PRODML_2_2_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${PRODML_PREFIX_2_2}/ + COMPONENT fesapi_headers + ) -# PRODML headers -INSTALL ( - FILES ${FESAPI_PRODML_2_2_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${PRODML_PREFIX_2_2}/ - COMPONENT fesapi_headers -) + # EML headers + INSTALL ( + FILES ${FESAPI_EML_2_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${EML_PREFIX_2}/ + COMPONENT fesapi_headers + ) -# EML headers -INSTALL ( - FILES ${FESAPI_EML_2_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${EML_PREFIX_2}/ - COMPONENT fesapi_headers -) + INSTALL ( + FILES ${FESAPI_EML_2_0_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${EML_PREFIX_2_0}/ + COMPONENT fesapi_headers + ) +else () + # Do not install DLL import libraries (on all Windows-based systems including Cygwin; they have extension .lib, in contrast to the .dll libraries that go to RUNTIME) + INSTALL ( + TARGETS ${CPP_LIBRARY_NAME} + EXPORT FESAPI_TARGETS + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif (NOT WITH_PYTHON_WRAPPING AND NOT WITH_DOTNET_WRAPPING AND NOT WITH_JAVA_WRAPPING) -INSTALL ( - FILES ${FESAPI_EML_2_0_HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/${EML_PREFIX_2_0}/ - COMPONENT fesapi_headers -) +if (WIN32) + #PDB for debug + INSTALL ( + FILES $ + CONFIGURATIONS Debug RelWithDebInfo + DESTINATION ${CMAKE_INSTALL_BINDIR} + OPTIONAL + ) +endif (WIN32) # PropertyTypeMapping.xml INSTALL ( FILES ${FESAPI_ROOT_DIR}/resources/PropertyKindMapping.xml - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fesapi/resources/ + DESTINATION ./resources/ COMPONENT fesapi_runtime ) diff --git a/src/common/AbstractObject.h b/src/common/AbstractObject.h index b811df6ea..33ab0c48c 100644 --- a/src/common/AbstractObject.h +++ b/src/common/AbstractObject.h @@ -28,7 +28,9 @@ under the License. namespace COMMON_NS { - /** @brief An abstract data object. */ + /** @brief An abstract data object is the super class of all FESAPI dataobjects which are contained in a DataObjectRepository. + * Its lifetime is controlled by a DataObjectRepository making it non copyable, non movable. + */ class AbstractObject { public: @@ -740,6 +742,10 @@ namespace COMMON_NS gsoapProxy2_3(proxy), repository(nullptr) {} + //This class is non copyable (non movable) since it is designed to be owned by a DataObjectRepository + AbstractObject(const AbstractObject&) = delete; + AbstractObject& operator=(const AbstractObject&) = delete; + friend bool COMMON_NS::DataObjectRepository::addDataObject(std::unique_ptr proxy); friend COMMON_NS::AbstractObject* COMMON_NS::DataObjectRepository::addOrReplaceDataObject(std::unique_ptr proxy, bool replaceOnlyContent); diff --git a/src/common/EpcDocument.cpp b/src/common/EpcDocument.cpp index ce9871e67..f1fc9a851 100644 --- a/src/common/EpcDocument.cpp +++ b/src/common/EpcDocument.cpp @@ -48,20 +48,6 @@ using namespace std; using namespace gsoap_resqml2_0_1; using namespace COMMON_NS; -void EpcDocument::open(const std::string & fileName) -{ - if (fileName.empty()) { - throw invalid_argument("The epc document name cannot be empty."); - } - if (package != nullptr) { - throw invalid_argument("The epc document must be closed before to be opened again."); - } - - setFilePath(fileName); - - package.reset(new epc::Package()); -} - void EpcDocument::setFilePath(const std::string & fp) { filePath = fp; @@ -249,11 +235,11 @@ namespace { } } -void EpcDocument::serializeFrom(DataObjectRepository& repo, bool useZip64) +void EpcDocument::serializeFrom(DataObjectRepository& repo) { addFakePropertyToEmptyPropertySet(repo); - package->openForWriting(filePath, APPEND_STATUS_CREATE, useZip64); + package->openForWriting(filePath, APPEND_STATUS_CREATE); for (auto const& uuidDataobjectPair : repo.getDataObjects()) { for (auto const& dataobject : uuidDataobjectPair.second) { @@ -359,6 +345,8 @@ string EpcDocument::deserializeInto(DataObjectRepository & repo, DataObjectRepos hdfProxy->setOpeningMode(hdfPermissionAccess); // Must repeat this setter in case of RESQML2.2 which is not an obj_EpcExternalPartReference } + package->close(); + return result; } @@ -440,6 +428,8 @@ std::string EpcDocument::deserializePartiallyInto(DataObjectRepository & repo, D hdfProxy->setOpeningMode(hdfPermissionAccess); // Must repeat this setter in case of RESQML2.2 which is not an obj_EpcExternalPartReference } + package->close(); + return result; } @@ -508,13 +498,12 @@ uint64_t EpcDocument::getExtendedCorePropertyCount() const return package->getExtendedCoreProperty().size(); } -std::string EpcDocument::getExtendedCoreProperty(const std::string & key) +std::string EpcDocument::getExtendedCoreProperty(const std::string & key) const { - if (package->getExtendedCoreProperty().find(key) != package->getExtendedCoreProperty().end()) { - return (package->getExtendedCoreProperty())[key]; - } - - return ""; + auto entry = package->getExtendedCoreProperty().find(key); + return entry != package->getExtendedCoreProperty().end() + ? entry->second + : ""; } std::string EpcDocument::resolvePartial(AbstractObject const * partialObj) const @@ -527,9 +516,12 @@ std::string EpcDocument::resolvePartial(AbstractObject const * partialObj) const for (auto it : package->getFileContentType().getAllContentType()) { if (it.first.find(partialObj->getUuid()) != std::string::npos) { - return package->extractFile(it.second.getExtensionOrPartName().substr(1)); + std::string result = package->extractFile(it.second.getExtensionOrPartName().substr(1)); + package->close(); + return result; } } + package->close(); return ""; } diff --git a/src/common/EpcDocument.h b/src/common/EpcDocument.h index ba520f536..a9f09c8c8 100644 --- a/src/common/EpcDocument.h +++ b/src/common/EpcDocument.h @@ -27,12 +27,12 @@ under the License. namespace COMMON_NS { - /** @brief EPC is an implementation of the Open Packaging Conventions (OPC), a widely used container-file technology + /** @brief EPC is an implementation of the Open Packaging Conventions (OPC), a widely used container-file technology * that allows multiple types of files to be bundled together into a single package. * Built on the widely used ZIP file structure and originally created by Microsoft, OPC is now an open standard supported by these standards organizations: * - Ecma International (http://www.ecma-international.org/publications/standards/Ecma-376.htm ) * - ISO/IEC 29500-2:2012, which has 4 parts, which are all freely available at this link (http://standards.iso.org/ittf/PubliclyAvailableStandards/index.html ). - * An EPC file (or package) is a ZIP file, which may be unzipped to view its components. + * An EPC file (or package) is a ZIP file, which may be "unzipped" to view its components. * When implemented as part of an Energistics standard, the zipping/unzipping is done using the OPC libraries (per the EPC Specification). */ class EpcDocument : public DataFeeder @@ -42,48 +42,30 @@ namespace COMMON_NS /** * Constructor * - * @param fileName Full pathname of the EPC document. + * @param fileName Full pathname of the EPC document in UTF-8 encoding. */ - DLL_IMPORT_OR_EXPORT EpcDocument(const std::string & fileName) { open(fileName); } + DLL_IMPORT_OR_EXPORT EpcDocument(const std::string& fileName) { open(fileName); } /** The destructor frees all allocated ressources. */ - DLL_IMPORT_OR_EXPORT ~EpcDocument() { close(); } + DLL_IMPORT_OR_EXPORT ~EpcDocument() = default; /** - * Opens an EPC document. If one is already opened, it must be closed before to open a new one. - * Don't forget to call {@link close()} before to destroy this object. + * Opens an EPC document. * - * @exception std::invalid_argument if the name of the EPC document is empty or if there is - * already an opened EPC document. - * - * @param fileName Full pathname of the EPC document. + * @param fileName Full pathname of the EPC document in UTF-8 encoding. */ - DLL_IMPORT_OR_EXPORT void open(const std::string & fileName); - - /** Free all ressources contained in this package. */ - DLL_IMPORT_OR_EXPORT void close() { - package.reset(); - filePath = ""; + DLL_IMPORT_OR_EXPORT void open(const std::string& fileName) + { + setFilePath(fileName); + package.reset(new epc::Package()); } - /** - * Sets the EPC document file path which will be used for future serialization and - * deserialization. This method will add the standard @c .epc extension if it is not already - * present. - * - * @exception std::invalid_argument if the HDF5 file error handling cannot be disabled. - * - * @param fp Full pathname of the EPC document. - */ - DLL_IMPORT_OR_EXPORT void setFilePath(const std::string & fp); - /** * Serializes the content of a data object repository into this EPC document. * * @param repo A data object repository (not const because we may create a Fake Property for solivng a RESQML2.0.1 empty PropertySet issue) - * @param useZip64 (Optional) True to zip the EPC document using Zip64 format, else (default) simply use Zip format. */ - DLL_IMPORT_OR_EXPORT void serializeFrom(DataObjectRepository& repo, bool useZip64 = false); + DLL_IMPORT_OR_EXPORT void serializeFrom(DataObjectRepository& repo); /** * Deserializes this package (data objects and relationships) into a data object repository @@ -118,10 +100,11 @@ namespace COMMON_NS /** * Gets the extended core properties of this package + * The EpcDocument must have been deserialized at least once to get the extended core proeprties information. * * @returns A map which associates keys and values of the extended core properties. */ - DLL_IMPORT_OR_EXPORT std::unordered_map< std::string, std::string > & getExtendedCoreProperty(); + DLL_IMPORT_OR_EXPORT std::unordered_map< std::string, std::string >& getExtendedCoreProperty(); /** * Sets or adds an extended core property @@ -129,10 +112,11 @@ namespace COMMON_NS * @param key The key of the property. * @param value The value of the property. */ - DLL_IMPORT_OR_EXPORT void setExtendedCoreProperty(const std::string & key, const std::string & value); + DLL_IMPORT_OR_EXPORT void setExtendedCoreProperty(const std::string& key, const std::string& value); /** * Gets extended core property count. + * The EpcDocument must have been deserialized at least once to get the extended core proeprties information. * * @returns The count of extended core properties in this EPC document */ @@ -140,20 +124,32 @@ namespace COMMON_NS /** * Gets an extended core property value according to its key. + * The EpcDocument must have been deserialized at least once to get the extended core proeprties information. * * @param key The key of the property. * * @returns An empty string if the extended core property does not exist. Or the extended core * property value if it exists. */ - DLL_IMPORT_OR_EXPORT std::string getExtendedCoreProperty(const std::string & key); + DLL_IMPORT_OR_EXPORT std::string getExtendedCoreProperty(const std::string& key) const; - DLL_IMPORT_OR_EXPORT std::string resolvePartial(AbstractObject const * partialObj) const; + DLL_IMPORT_OR_EXPORT std::string resolvePartial(AbstractObject const* partialObj) const; private : - static constexpr char const* DOCUMENT_EXTENSION = ".epc"; + /** + * Sets the EPC document file path which will be used for future serialization and + * deserialization. This method will add the standard @c .epc extension if it is not already + * present. + * + * @exception std::invalid_argument if the HDF5 file error handling cannot be disabled. + * + * @param fp Full pathname of the EPC document. + */ + void setFilePath(const std::string& fp); - void deserializeRelFiles(DataObjectRepository & repo); + void deserializeRelFiles(DataObjectRepository& repo); + + static constexpr char const* DOCUMENT_EXTENSION = ".epc"; /** The package */ std::unique_ptr package; diff --git a/src/eml2_3/PropertyKind.cpp b/src/eml2_3/PropertyKind.cpp index 05037e5eb..766323cc3 100644 --- a/src/eml2_3/PropertyKind.cpp +++ b/src/eml2_3/PropertyKind.cpp @@ -19,6 +19,7 @@ under the License. #include "PropertyKind.h" #include +#include "../tools/TimeTools.h" using namespace std; using namespace EML2_3_NS; @@ -113,6 +114,63 @@ COMMON_NS::DataObjectReference PropertyKind::getParentPropertyKindDor() const return COMMON_NS::DataObjectReference(static_cast(gsoapProxy2_3)->Parent); } +time_t PropertyKind::getDeprecationDate() const +{ + tm result = getDeprecationDateAsTimeStructure(); + + if (result.tm_mday == 0) { + return -1; + } + + return timeTools::timegm(result); +} + +tm PropertyKind::getDeprecationDateAsTimeStructure() const +{ + cannotBePartial(); + + if (gsoapProxy2_3 != nullptr && static_cast(gsoapProxy2_3)->DeprecationDate) + return *static_cast(gsoapProxy2_3)->DeprecationDate; + else { + tm result; + result.tm_hour = 0; + result.tm_isdst = 0; + result.tm_mday = 0; + result.tm_min = 0; + result.tm_mon = 0; + result.tm_sec = 0; + result.tm_wday = 0; + result.tm_yday = 0; + result.tm_year = 0; + return result; + } +} + +void PropertyKind::setDeprecationDate(time_t deprecationDate) +{ + cannotBePartial(); + + if (deprecationDate > 0) { + + if (deprecationDate < getCreation()) { + throw invalid_argument("Deprecation Date cannot be inferior to creation date."); + } + + std::tm tmConversion = timeTools::to_calendar_time(timeTools::from_time_t(deprecationDate)); + setDeprecationDate(tmConversion); + } +} + +void PropertyKind::setDeprecationDate(const tm& deprecationDate) +{ + cannotBePartial(); + + if (static_cast(gsoapProxy2_3)->DeprecationDate == nullptr) { + static_cast(gsoapProxy2_3)->DeprecationDate = (tm*)soap_malloc(gsoapProxy2_3->soap, sizeof(tm)); + } + *static_cast(gsoapProxy2_3)->DeprecationDate = deprecationDate; +} + void PropertyKind::loadTargetRelationships() { COMMON_NS::DataObjectReference dor = getParentPropertyKindDor(); diff --git a/src/eml2_3/PropertyKind.h b/src/eml2_3/PropertyKind.h index 343afecb4..07baed513 100644 --- a/src/eml2_3/PropertyKind.h +++ b/src/eml2_3/PropertyKind.h @@ -124,6 +124,44 @@ namespace EML2_3_NS */ COMMON_NS::DataObjectReference getParentPropertyKindDor() const final; + /** + * Gets the date and time at which this property dictionary entry must no longer be used. + * Files generated before this date would have used this entry so it is left here for reference. + * + * @exception std::invalid_argument If this instance is actually a partial object. + * + * @returns deprecationDate The deprecation date and time of this data object. + */ + DLL_IMPORT_OR_EXPORT time_t getDeprecationDate() const; + + /** + * Same as {@link getDeprecationDate()}. Please use this method if you want to read some dates out of + * the range of @c time_t + * + * @exception std::invalid_argument If this instance is actually a partial object. + * + * @returns The deprecation date and time of the data object. + */ + DLL_IMPORT_OR_EXPORT tm getDeprecationDateAsTimeStructure() const; + + /** + * Sets the date and time at which this property dictionary entry must no longer be used. + * Files generated before this date would have used this entry so it is left here for reference. + * + * @exception std::invalid_argument If this instance is actually a partial object. + * + * @param deprecationDate The deprecation date and time to set to this data object. + */ + DLL_IMPORT_OR_EXPORT void setDeprecationDate(time_t deprecationDate); + + /** + * Same as {@link setDeprecationDate()}. Please use this method if you want to read some dates out of + * the range of @c time_t + * + * @param lastUpdate The deprecation date and time to set to this data object. + */ + DLL_IMPORT_OR_EXPORT void setDeprecationDate(const tm& lastUpdate); + /** Loads target relationships */ void loadTargetRelationships() final; diff --git a/src/epc/Package.cpp b/src/epc/Package.cpp index ef30ad2b5..48c71a574 100644 --- a/src/epc/Package.cpp +++ b/src/epc/Package.cpp @@ -36,6 +36,9 @@ under the License. #include #include +#ifdef _WIN32 +#include +#endif #include "FilePart.h" @@ -100,7 +103,7 @@ Package::~Package() delete d_ptr; } -void Package::openForWriting(const std::string & pkgPathName, int append, bool useZip64) +void Package::openForWriting(const std::string & pkgPathName, int append) { d_ptr->allFileParts.clear(); d_ptr->fileContentType.clear(); @@ -118,8 +121,21 @@ void Package::openForWriting(const std::string & pkgPathName, int append, bool u addRelationship(Relationship("docProps/core.xml", CORE_PROP_REL_TYPE, "CoreProperties")); - d_ptr->isZip64 = useZip64; - d_ptr->zf = useZip64 ? zipOpen64(d_ptr->pathName.c_str(), append) : zipOpen(d_ptr->pathName.c_str(), append); + d_ptr->isZip64 = true; +#ifdef WIN32 + zlib_filefunc64_def ffunc; + fill_win32_filefunc64W(&ffunc); + + // Convert path from UTF-8 to Unicode + const int count = MultiByteToWideChar(CP_UTF8, 0, d_ptr->pathName.c_str(), static_cast(d_ptr->pathName.size()), NULL, 0); + std::wstring unicodePath(count, 0); + MultiByteToWideChar(CP_UTF8, 0, d_ptr->pathName.c_str(), static_cast(d_ptr->pathName.size()), &unicodePath[0], count); + + d_ptr->zf = zipOpen2_64(unicodePath.c_str(), append, NULL, &ffunc); +#else + // Unix systems handles path in the UTF-8 by default + d_ptr->zf = zipOpen64(d_ptr->pathName.c_str(), append); +#endif if (d_ptr->zf == nullptr) { throw invalid_argument("The file " + pkgPathName + " could not be opened"); @@ -136,7 +152,20 @@ std::vector Package::openForReading(const std::string & pkgPathName std::vector result; d_ptr->pathName.assign(pkgPathName); +#ifdef WIN32 + zlib_filefunc64_def ffunc; + fill_win32_filefunc64W(&ffunc); + + // Convert path from UTF-8 to Unicode + const int count = MultiByteToWideChar(CP_UTF8, 0, d_ptr->pathName.c_str(), static_cast(d_ptr->pathName.size()), NULL, 0); + std::wstring unicodePath(count, 0); + MultiByteToWideChar(CP_UTF8, 0, d_ptr->pathName.c_str(), static_cast(d_ptr->pathName.size()), &unicodePath[0], count); + + d_ptr->unzipped = unzOpen2_64(unicodePath.c_str(), &ffunc); +#else + // Unix systems handles path in the UTF-8 by default d_ptr->unzipped = unzOpen64(d_ptr->pathName.c_str()); +#endif if (d_ptr->unzipped == nullptr) { throw invalid_argument("Cannot unzip " + pkgPathName + ". Please verify the path of the file and if you can open it with a third party archiver."); diff --git a/src/epc/Package.h b/src/epc/Package.h index f8b949972..7a2fa069f 100644 --- a/src/epc/Package.h +++ b/src/epc/Package.h @@ -86,9 +86,8 @@ namespace epc * add files in existing zip (be sure you don't add file that doesn't * exist). Else an ovewrite or a creation of the file will be done. If the * zipfile cannot be opened, an invalid_argument exception is thrown. - * @param useZip64 (Optional) True to use zip 64. */ - void openForWriting(const std::string & pkgPathName, int append, bool useZip64 = false); + void openForWriting(const std::string & pkgPathName, int append); /** * Check if the package is already opened for writing. @@ -98,7 +97,7 @@ namespace epc /** * Open the package for reading purpose * - * @param pkgPathName Full pathname of the package file. + * @param pkgPathName Full pathname of the package file in UTF-8 encoding. * * @returns empty vector if nothing went wrong. Otherwise, return warnings. */ diff --git a/src/resqml2/AbstractColorMap.h b/src/resqml2/AbstractColorMap.h index 7bf92ccd9..7be01322f 100644 --- a/src/resqml2/AbstractColorMap.h +++ b/src/resqml2/AbstractColorMap.h @@ -57,7 +57,7 @@ namespace RESQML2_NS * @param colorCount the size (number of colors) of the color map * @param rgbColors array (of size colorCount * 3) of RGB colors with hsvColors[3*i] is red component, hsvColors[3*i + 1] is green component and hsvColors[3*i + 2] is blue component of the ith color (red, green and blue are in range [0, 255]) * @param alphas array (of size colorCount) of numeric values in the range [0, 1] for alpha transparency channel (0 means transparent and 1 means opaque). If alphas == nullptr (default value), default alpha value is 1. - * @param indices array (of size solorCount) of color indices. These indices are cast to unsigned int in the case of a discrete color map. If indices == nullptr (default value), indices are set from 0 to colorCount - 1 + * @param indices array (of size colorCount) of color indices. These indices are cast to unsigned int in the case of a discrete color map. If indices == nullptr (default value), indices are set from 0 to colorCount - 1 * @param colorTitles vector (of size colorCount) of color titles. Titles are not set if colorTitles is empty (default value) */ DLL_IMPORT_OR_EXPORT void setRgbColors(uint64_t colorCount, diff --git a/src/resqml2/AbstractProperty.cpp b/src/resqml2/AbstractProperty.cpp index fa55929da..4667cdb51 100644 --- a/src/resqml2/AbstractProperty.cpp +++ b/src/resqml2/AbstractProperty.cpp @@ -525,14 +525,18 @@ gsoap_resqml2_0_1::resqml20__ResqmlPropertyKind AbstractProperty::getEnergistics throw invalid_argument("The property kind of this property is not an Energistics one."); } -uint64_t AbstractProperty::getValuesCountOfPatch(unsigned int patchIndex) const +uint64_t AbstractProperty::getValuesCountOfPatch(uint64_t patchIndex) const { - uint64_t result = 1; - - size_t dimCount = getDimensionsCountOfPatch(patchIndex); - for (size_t dimIndex = 0; dimIndex < dimCount; ++dimIndex) { - result *= getValuesCountOfDimensionOfPatch(dimIndex, patchIndex); - } + auto valuescountPerDim = getValuesCountPerDimensionOfPatch(patchIndex); + return std::accumulate(std::begin(valuescountPerDim), std::end(valuescountPerDim), static_cast(1), std::multiplies()); +} - return result; +uint64_t AbstractProperty::getValuesCountOfDimensionOfPatch(uint64_t dimIndex, uint64_t patchIndex) const +{ + return getValuesCountPerDimensionOfPatch(patchIndex).at(dimIndex); } + +uint64_t AbstractProperty::getDimensionsCountOfPatch(uint64_t patchIndex) const +{ + return getValuesCountPerDimensionOfPatch(patchIndex).size(); +} \ No newline at end of file diff --git a/src/resqml2/AbstractProperty.h b/src/resqml2/AbstractProperty.h index c7289c8d2..c5767234d 100644 --- a/src/resqml2/AbstractProperty.h +++ b/src/resqml2/AbstractProperty.h @@ -101,6 +101,13 @@ namespace RESQML2_NS */ DLL_IMPORT_OR_EXPORT virtual COMMON_NS::AbstractObject::numericalDatatypeEnum getValuesHdfDatatype() const = 0; + /** + * Get the number of values in each dimension into the underlying HDF5 dataset. + * uint32_t is returned instead of uint64_t cause of some SWIG usage. I cannot SWIG port std::vector + * @param patchIndex The index of the patch we want to count the values from. + */ + DLL_IMPORT_OR_EXPORT virtual std::vector getValuesCountPerDimensionOfPatch(uint64_t patchIndex) const = 0; + /** * Gets the count of all values contained into the underlying HDF5 dataset of a given patch of * this property. @@ -111,7 +118,7 @@ namespace RESQML2_NS * * @returns The count of values of the @p patchIndex patch. */ - DLL_IMPORT_OR_EXPORT uint64_t getValuesCountOfPatch(unsigned int patchIndex) const; + DLL_IMPORT_OR_EXPORT uint64_t getValuesCountOfPatch(uint64_t patchIndex) const; /** * Gets the count of values on a specific dimension of the underlying HDF5 dataset of a given @@ -125,7 +132,7 @@ namespace RESQML2_NS * * @returns The count of values in the @p dimIndex dimension of @p patchIndex patch. */ - DLL_IMPORT_OR_EXPORT virtual uint64_t getValuesCountOfDimensionOfPatch(uint64_t dimIndex, uint64_t patchIndex) const = 0; + DLL_IMPORT_OR_EXPORT uint64_t getValuesCountOfDimensionOfPatch(uint64_t dimIndex, uint64_t patchIndex) const; /** * Gets the count of dimensions of the underlying HDF5 dataset of a given patch of this property. @@ -136,7 +143,7 @@ namespace RESQML2_NS * * @returns The number of values, 0 otherwise. */ - DLL_IMPORT_OR_EXPORT virtual uint64_t getDimensionsCountOfPatch(uint64_t patchIndex) const = 0; + DLL_IMPORT_OR_EXPORT uint64_t getDimensionsCountOfPatch(uint64_t patchIndex) const; //********************************************* //************* PROPERTY SET ****************** diff --git a/src/resqml2/AbstractValuesProperty.cpp b/src/resqml2/AbstractValuesProperty.cpp index c423308cf..e5dcb847e 100644 --- a/src/resqml2/AbstractValuesProperty.cpp +++ b/src/resqml2/AbstractValuesProperty.cpp @@ -84,108 +84,70 @@ COMMON_NS::AbstractObject::numericalDatatypeEnum AbstractValuesProperty::getValu return hdfProxy->getNumericalDatatype(dsPath); } -uint64_t AbstractValuesProperty::getValuesCountOfDimensionOfPatch(uint64_t dimIndex, uint64_t patchIndex) const +std::vector AbstractValuesProperty::getValuesCountPerDimensionOfPatch(uint64_t patchIndex) const { cannotBePartial(); if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__PatchOfValues* patch = static_cast(gsoapProxy2_0_1)->PatchOfValues[patchIndex]; + gsoap_resqml2_0_1::resqml20__PatchOfValues const* patch = static_cast(gsoapProxy2_0_1)->PatchOfValues[patchIndex]; switch (patch->Values->soap_type()) { case SOAP_TYPE_gsoap_resqml2_0_1_resqml20__DoubleConstantArray: { - return static_cast(patch->Values)->Count; + return std::vector(1, static_cast(patch->Values)->Count); } case SOAP_TYPE_gsoap_resqml2_0_1_resqml20__DoubleLatticeArray: { - return static_cast(patch->Values)->Offset[dimIndex]->Count + 1; + auto const* arrayDef = static_cast(patch->Values); + std::vector result; + for (auto offset : arrayDef->Offset) { + result.push_back(offset->Count + 1); + } + return result; } case SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerConstantArray: { - return static_cast(patch->Values)->Count; + return std::vector(1, static_cast(patch->Values)->Count); } case SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerLatticeArray: { - return static_cast(patch->Values)->Offset[dimIndex]->Count + 1; + auto const* arrayDef = static_cast(patch->Values); + std::vector result; + for (auto offset : arrayDef->Offset) { + result.push_back(offset->Count + 1); + } + return result; } } } else if (gsoapProxy2_3 != nullptr) { - auto patch = static_cast(gsoapProxy2_3)->ValuesForPatch[patchIndex]; + auto const* patch = static_cast(gsoapProxy2_3)->ValuesForPatch[patchIndex]; switch (patch->soap_type()) { case SOAP_TYPE_gsoap_eml2_3_eml23__FloatingPointConstantArray: { - return static_cast(patch)->Count; + return std::vector(1, static_cast(patch)->Count); } case SOAP_TYPE_gsoap_eml2_3_eml23__FloatingPointLatticeArray: { - return static_cast(patch)->Offset[dimIndex]->Count + 1; - } - case SOAP_TYPE_gsoap_eml2_3_eml23__IntegerConstantArray: - { - return static_cast(patch)->Count; - } - case SOAP_TYPE_gsoap_eml2_3_eml23__IntegerLatticeArray: - { - return static_cast(patch)->Offset[dimIndex]->Count + 1; - } - } - } - else { - throw logic_error("Only RESQML 2.2 and 2.0.1 are supported for now."); - } - - int64_t nullValue = (numeric_limits::min)(); - std::string dsPath; - EML2_NS::AbstractHdfProxy * hdfProxy = getDatasetOfPatch(patchIndex, nullValue, dsPath); - - std::vector dims = hdfProxy->getElementCountPerDimension(dsPath); - - if (dimIndex < dims.size()) { - return dims[dimIndex]; - } - - throw out_of_range("The dim index to get the count is out of range."); -} - -uint64_t AbstractValuesProperty::getDimensionsCountOfPatch(uint64_t patchIndex) const -{ - cannotBePartial(); - - if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__PatchOfValues* patch = static_cast(gsoapProxy2_0_1)->PatchOfValues[patchIndex]; - - switch (patch->Values->soap_type()) { - case SOAP_TYPE_gsoap_resqml2_0_1_resqml20__DoubleConstantArray: - case SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerConstantArray: - { - return 1; - } - case SOAP_TYPE_gsoap_resqml2_0_1_resqml20__DoubleLatticeArray: - { - return static_cast(patch->Values)->Offset.size(); + auto const* arrayDef = static_cast(patch); + std::vector result; + for (auto offset : arrayDef->Offset) { + result.push_back(offset->Count + 1); + } + return result; } - case SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerLatticeArray: - { - return static_cast(patch->Values)->Offset.size(); - } - } - } - else if (gsoapProxy2_3 != nullptr) { - auto patch = static_cast(gsoapProxy2_3)->ValuesForPatch[patchIndex]; - switch (patch->soap_type()) { - case SOAP_TYPE_gsoap_eml2_3_eml23__FloatingPointConstantArray: case SOAP_TYPE_gsoap_eml2_3_eml23__IntegerConstantArray: { - return 1; - } - case SOAP_TYPE_gsoap_eml2_3_eml23__FloatingPointLatticeArray: - { - return static_cast(patch)->Offset.size(); + return std::vector(1, static_cast(patch)->Count); } case SOAP_TYPE_gsoap_eml2_3_eml23__IntegerLatticeArray: { - return static_cast(patch)->Offset.size(); + auto const* arrayDef = static_cast(patch); + std::vector result; + for (auto offset : arrayDef->Offset) { + result.push_back(offset->Count + 1); + } + return result; } } } @@ -195,19 +157,15 @@ uint64_t AbstractValuesProperty::getDimensionsCountOfPatch(uint64_t patchIndex) int64_t nullValue = (numeric_limits::min)(); std::string dsPath; - EML2_NS::AbstractHdfProxy * hdfProxy = getDatasetOfPatch(patchIndex, nullValue, dsPath); + EML2_NS::AbstractHdfProxy* hdfProxy = getDatasetOfPatch(patchIndex, nullValue, dsPath); - return hdfProxy->getDimensionCount(dsPath); + return hdfProxy->getElementCountPerDimension(dsPath); } -EML2_NS::AbstractHdfProxy * AbstractValuesProperty::getDatasetOfPatch(uint64_t patchIndex, int64_t & nullValue, std::string & dsPath) const +EML2_NS::AbstractHdfProxy * AbstractValuesProperty::getDatasetOfPatch(uint64_t patchIndex, int64_t& nullValue, std::string& dsPath) const { - if (patchIndex >= getPatchCount()) { - throw out_of_range("The values property patch is out of range"); - } - if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__PatchOfValues* patch = static_cast(gsoapProxy2_0_1)->PatchOfValues[patchIndex]; + gsoap_resqml2_0_1::resqml20__PatchOfValues const* patch = static_cast(gsoapProxy2_0_1)->PatchOfValues.at(patchIndex); nullValue = (numeric_limits::min)(); int valuesType = patch->Values->soap_type(); @@ -234,7 +192,7 @@ EML2_NS::AbstractHdfProxy * AbstractValuesProperty::getDatasetOfPatch(uint64_t p } else if (gsoapProxy2_3 != nullptr) { nullValue = (numeric_limits::min)(); - auto patch = static_cast(gsoapProxy2_3)->ValuesForPatch[patchIndex]; + auto patch = static_cast(gsoapProxy2_3)->ValuesForPatch.at(patchIndex); if (dynamic_cast(patch) != nullptr) { dsPath = static_cast(patch)->Values->ExternalDataArrayPart[0]->PathInExternalFile; return getOrCreateHdfProxyFromDataArrayPart(static_cast(patch)->Values->ExternalDataArrayPart[0]); diff --git a/src/resqml2/AbstractValuesProperty.h b/src/resqml2/AbstractValuesProperty.h index 25bffcdd0..55ac8d830 100644 --- a/src/resqml2/AbstractValuesProperty.h +++ b/src/resqml2/AbstractValuesProperty.h @@ -51,29 +51,11 @@ namespace RESQML2_NS DLL_IMPORT_OR_EXPORT COMMON_NS::AbstractObject::numericalDatatypeEnum getValuesHdfDatatype() const final; /** - * Gets the count of values on a specific dimension of the underlying HDF5 dataset of a given - * patch of this property. - * - * @exception std::out_of_range If @p dimIndex is strictly greater than dimension count. - * @exception std::range_error If @p patchIndex is strictly greater than patch count. - * - * @param dimIndex The index of the dimension we want to count the values from. + * Get the number of values in each dimension into the underlying HDF5 dataset. + * uint32_t is returned instead of uint64_t cause of some SWIG usage. I cannot SWIG port std::vector * @param patchIndex The index of the patch we want to count the values from. - * - * @returns The count of values in the @p dimIndex dimension of @p patchIndex patch. - */ - DLL_IMPORT_OR_EXPORT uint64_t getValuesCountOfDimensionOfPatch(uint64_t dimIndex, uint64_t patchIndex) const final; - - /** - * Gets the count of dimensions of the underlying HDF5 dataset of a given patch of this property. - * - * @exception std::range_error If @p patchIndex is strictly greater than patch count. - * - * @param patchIndex The index of the patch we want to count the dimensions from. - * - * @returns The number of values, 0 otherwise. */ - DLL_IMPORT_OR_EXPORT uint64_t getDimensionsCountOfPatch(uint64_t patchIndex) const final; + DLL_IMPORT_OR_EXPORT std::vector getValuesCountPerDimensionOfPatch(uint64_t patchIndex) const final; /** * Pushes back a new facet to this instance. Facets are qualifiers for property values which diff --git a/src/resqml2/PointsProperty.cpp b/src/resqml2/PointsProperty.cpp index fd4ab2b55..4c8f77e08 100644 --- a/src/resqml2/PointsProperty.cpp +++ b/src/resqml2/PointsProperty.cpp @@ -28,9 +28,7 @@ const char* PointsProperty::XML_TAG = "PointsProperty"; COMMON_NS::AbstractObject::numericalDatatypeEnum PointsProperty::getValuesHdfDatatype() const { - if (isPartial()) { - throw logic_error("You cannot get values from a partial property."); - } + cannotBePartial(); int64_t nullValue = (numeric_limits::min)(); std::string dsPath; @@ -39,36 +37,15 @@ COMMON_NS::AbstractObject::numericalDatatypeEnum PointsProperty::getValuesHdfDat return hdfProxy->getNumericalDatatype(dsPath); } -uint64_t PointsProperty::getValuesCountOfDimensionOfPatch(uint64_t dimIndex, uint64_t patchIndex) const +std::vector PointsProperty::getValuesCountPerDimensionOfPatch(uint64_t patchIndex) const { - if (isPartial()) { - throw logic_error("You cannot get values from a partial property."); - } - - int64_t nullValue = (numeric_limits::min)(); - std::string dsPath; - EML2_NS::AbstractHdfProxy * hdfProxy = getDatasetOfPatch(patchIndex, nullValue, dsPath); - - std::vector dims = hdfProxy->getElementCountPerDimension(dsPath); - - if (dimIndex < dims.size()) { - return dims[dimIndex]; - } - - throw out_of_range("The dim index to get the count is out of range."); -} - -uint64_t PointsProperty::getDimensionsCountOfPatch(uint64_t patchIndex) const -{ - if (isPartial()) { - throw logic_error("You cannot get values from a partial property."); - } + cannotBePartial(); int64_t nullValue = (numeric_limits::min)(); std::string dsPath; - EML2_NS::AbstractHdfProxy * hdfProxy = getDatasetOfPatch(patchIndex, nullValue, dsPath); + EML2_NS::AbstractHdfProxy* hdfProxy = getDatasetOfPatch(patchIndex, nullValue, dsPath); - return hdfProxy->getDimensionCount(dsPath); + return hdfProxy->getElementCountPerDimension(dsPath); } uint64_t PointsProperty::getXyzPointCountOfAllPatches() const @@ -140,13 +117,13 @@ void PointsProperty::pushBackArray3dOfXyzPoints(const double * points, uint64_t pushBackArrayOfXyzPoints(points, pointCountPerDimension, 3, proxy); } -void PointsProperty::pushBackArrayOfXyzPoints(double const * points, uint64_t const * pointCountByDimension, unsigned int numArrayDimensions, EML2_NS::AbstractHdfProxy * proxy) +void PointsProperty::pushBackArrayOfXyzPoints(double const * points, uint64_t const * pointCountByDimension, uint32_t numArrayDimensions, EML2_NS::AbstractHdfProxy * proxy) { const string datasetName = "points_patch" + std::to_string(getPatchCount()); // HDF std::unique_ptr coordinateCountByDimension(new uint64_t[numArrayDimensions + 1]); - for (unsigned int i = 0; i < numArrayDimensions; ++i) { + for (size_t i = 0; i < numArrayDimensions; ++i) { coordinateCountByDimension[i] = pointCountByDimension[i]; } coordinateCountByDimension[numArrayDimensions] = 3; // For the XYZ triplet diff --git a/src/resqml2/PointsProperty.h b/src/resqml2/PointsProperty.h index 679edb174..8d07d3f00 100644 --- a/src/resqml2/PointsProperty.h +++ b/src/resqml2/PointsProperty.h @@ -40,29 +40,11 @@ namespace RESQML2_NS DLL_IMPORT_OR_EXPORT COMMON_NS::AbstractObject::numericalDatatypeEnum getValuesHdfDatatype() const final; /** - * Gets the count of values on a specific dimension of the underlying HDF5 dataset of a given - * patch of this property. - * - * @exception std::out_of_range If @p dimIndex is strictly greater than dimension count. - * @exception std::range_error If @p patchIndex is strictly greater than patch count. - * - * @param dimIndex The index of the dimension we want to count the values from. + * Get the number of values in each dimension into the underlying HDF5 dataset. + * uint32_t is returned instead of uint64_t cause of some SWIG usage. I cannot SWIG port std::vector * @param patchIndex The index of the patch we want to count the values from. - * - * @returns The count of values in the @p dimIndex dimension of @p patchIndex patch. - */ - DLL_IMPORT_OR_EXPORT uint64_t getValuesCountOfDimensionOfPatch(uint64_t dimIndex, uint64_t patchIndex) const final; - - /** - * Gets the count of dimensions of the underlying HDF5 dataset of a given patch of this property. - * - * @exception std::range_error If @p patchIndex is strictly greater than patch count. - * - * @param patchIndex The index of the patch we want to count the dimensions from. - * - * @returns The number of values, 0 otherwise. */ - DLL_IMPORT_OR_EXPORT uint64_t getDimensionsCountOfPatch(uint64_t patchIndex) const final; + DLL_IMPORT_OR_EXPORT std::vector getValuesCountPerDimensionOfPatch(uint64_t patchIndex) const final; /** * Get the xyz point count in a given patch of this property. @@ -211,7 +193,7 @@ namespace RESQML2_NS * then a default HDF proxy must be defined in the * repository. */ - DLL_IMPORT_OR_EXPORT void pushBackArrayOfXyzPoints(double const * xyzPoints, uint64_t const * pointCountByDimension, unsigned int numArrayDimensions, EML2_NS::AbstractHdfProxy* proxy = nullptr); + DLL_IMPORT_OR_EXPORT void pushBackArrayOfXyzPoints(double const * xyzPoints, uint64_t const * pointCountByDimension, uint32_t numArrayDimensions, EML2_NS::AbstractHdfProxy* proxy = nullptr); /** * Pushes back a reference to an existing (or a "to exist") HDF dataset in a particular HDF diff --git a/src/resqml2/WellboreTrajectoryRepresentation.cpp b/src/resqml2/WellboreTrajectoryRepresentation.cpp index c9cfa9a2b..bd580bcae 100644 --- a/src/resqml2/WellboreTrajectoryRepresentation.cpp +++ b/src/resqml2/WellboreTrajectoryRepresentation.cpp @@ -150,6 +150,11 @@ RESQML2_NS::MdDatum * WellboreTrajectoryRepresentation::getMdDatum() const return getRepository()->getDataObjectByUuid(getMdDatumDor().getUuid()); } +std::string WellboreTrajectoryRepresentation::getMdUomAsString() const +{ + return gsoap_resqml2_0_1::soap_eml20__LengthUom2s(gsoapProxy2_0_1->soap, getMdUom()); +} + void WellboreTrajectoryRepresentation::convertMdValuesToXyzValues(double* mdValues, uint64_t mdCount, double* xyzPoints) const { auto const* mdDatum = getMdDatum(); diff --git a/src/resqml2/WellboreTrajectoryRepresentation.h b/src/resqml2/WellboreTrajectoryRepresentation.h index dd8ef7958..c7b22e7da 100644 --- a/src/resqml2/WellboreTrajectoryRepresentation.h +++ b/src/resqml2/WellboreTrajectoryRepresentation.h @@ -273,6 +273,13 @@ namespace RESQML2_NS */ DLL_IMPORT_OR_EXPORT virtual gsoap_resqml2_0_1::eml20__LengthUom getMdUom() const = 0; + /** + * Gets the unit of measure of the MDs along this trajectory as a string. + * + * @returns The unit of measure of the MDs along this trajectory as a string. + */ + DLL_IMPORT_OR_EXPORT std::string getMdUomAsString() const; + /** * Gets the MD double values associated to each trajectory station of this trajectory. * diff --git a/src/resqml2_2/WellboreTrajectoryRepresentation.cpp b/src/resqml2_2/WellboreTrajectoryRepresentation.cpp index 0085f9a2f..718612e9b 100644 --- a/src/resqml2_2/WellboreTrajectoryRepresentation.cpp +++ b/src/resqml2_2/WellboreTrajectoryRepresentation.cpp @@ -271,7 +271,7 @@ bool WellboreTrajectoryRepresentation::hasMdValues() const gsoap_resqml2_0_1::eml20__LengthUom WellboreTrajectoryRepresentation::getMdUom() const { gsoap_resqml2_0_1::eml20__LengthUom result; - gsoap_resqml2_0_1::soap_s2eml20__LengthUom(gsoapProxy2_3->soap, getMdDatum()->getLocalCrs()->getVerticalCrsUnitAsString().c_str(), &result); + gsoap_resqml2_0_1::soap_s2eml20__LengthUom(gsoapProxy2_3->soap, static_cast(gsoapProxy2_3)->MdInterval->Uom.c_str(), &result); return result; } diff --git a/src/witsml2_1/WellboreCompletion.cpp b/src/witsml2_1/WellboreCompletion.cpp index 2f0c5f80d..64c3a4a91 100644 --- a/src/witsml2_1/WellboreCompletion.cpp +++ b/src/witsml2_1/WellboreCompletion.cpp @@ -745,7 +745,7 @@ void WellboreCompletion::setConnectionHistoryEndDate(uint64_t historyIndex, if (statusHistory->EndDate == nullptr) { statusHistory->EndDate = soap_new_tm(gsoapProxy2_3->soap); } - *statusHistory->StartDate = timeTools::to_calendar_time(timeTools::from_time_t(endDate)); + *statusHistory->EndDate = timeTools::to_calendar_time(timeTools::from_time_t(endDate)); } } diff --git a/swig/swigEml2_3Include.i b/swig/swigEml2_3Include.i index f9ca362be..20293fb71 100644 --- a/swig/swigEml2_3Include.i +++ b/swig/swigEml2_3Include.i @@ -2042,6 +2042,26 @@ namespace EML2_3_NS class PropertyKind : public EML2_NS::PropertyKind { public: + + /** + * Gets the date and time at which this property dictionary entry must no longer be used. + * Files generated before this date would have used this entry so it is left here for reference. + * + * @exception std::invalid_argument If this instance is actually a partial object. + * + * @returns deprecationDate The deprecation date and time of this data object. + */ + time_t getDeprecationDate() const; + + /** + * Sets the date and time at which this property dictionary entry must no longer be used. + * Files generated before this date would have used this entry so it is left here for reference. + * + * @exception std::invalid_argument If this instance is actually a partial object. + * + * @param deprecationDate The deprecation date and time to set to this data object. + */ + void setDeprecationDate(time_t deprecationDate); }; #if defined(SWIGJAVA) || defined(SWIGPYTHON) diff --git a/swig/swigModule.i b/swig/swigModule.i index 0de258aeb..4dd0debf3 100644 --- a/swig/swigModule.i +++ b/swig/swigModule.i @@ -3950,24 +3950,13 @@ import com.f2i_consulting.fesapi.*; %template(createPartialChannelSet) createPartial; %template(createPartialChannel) createPartial; }; - -%typemap(javaimports) COMMON_NS::EpcDocument %{ -import java.lang.AutoCloseable; -%} -%typemap(javainterfaces) COMMON_NS::EpcDocument "AutoCloseable" -%typemap(javacode) COMMON_NS::EpcDocument %{ - @Override - public void close() { - closeNativeResource(); - delete(); - } -%} - /** @brief EPC is an implementation of the Open Packaging Conventions (OPC), a widely used container-file technology + + /** @brief EPC is an implementation of the Open Packaging Conventions (OPC), a widely used container-file technology * that allows multiple types of files to be bundled together into a single package. * Built on the widely used ZIP file structure and originally created by Microsoft, OPC is now an open standard supported by these standards organizations: * - Ecma International (http://www.ecma-international.org/publications/standards/Ecma-376.htm ) * - ISO/IEC 29500-2:2012, which has 4 parts, which are all freely available at this link (http://standards.iso.org/ittf/PubliclyAvailableStandards/index.html ). - * An EPC file (or package) is a ZIP file, which may be “unzipped” to view its components. + * An EPC file (or package) is a ZIP file, which may be "unzipped" to view its components. * When implemented as part of an Energistics standard, the zipping/unzipping is done using the OPC libraries (per the EPC Specification). */ class EpcDocument @@ -3977,28 +3966,23 @@ import java.lang.AutoCloseable; /** * Constructor * - * @param fileName Full pathname of the EPC document. + * @param fileName Full pathname of the EPC document in UTF-8 encoding. */ - EpcDocument(const std::string & fileName); + EpcDocument(const std::string& fileName); /** - * Sets the EPC document file path which will be used for future serialization and - * deserialization. This method will add the standard @c .epc extension if it is not already - * present. - * - * @exception std::invalid_argument if the HDF5 file error handling cannot be disabled. + * Opens an EPC document. * - * @param fp Full pathname of the EPC document. + * @param fileName Full pathname of the EPC document in UTF-8 encoding. */ - void setFilePath(const std::string & fp); + void open(const std::string& fileName); /** * Serializes the content of a data object repository into this EPC document. * * @param repo A data object repository. - * @param useZip64 (Optional) True to zip the EPC document using Zip64 format, else (default) simply use Zip format. */ - void serializeFrom(DataObjectRepository& repo, bool useZip64 = false); + void serializeFrom(DataObjectRepository& repo); /** * Deserializes this package (data objects and relationships) into a data object repository @@ -4011,13 +3995,6 @@ import java.lang.AutoCloseable; */ virtual std::string deserializeInto(DataObjectRepository& repo, DataObjectRepository::openingMode hdfPermissionAccess = DataObjectRepository::openingMode::READ_ONLY); -// JAVA uses autocloseable and consequently cannot use a second "close" method -#ifdef SWIGJAVA - %javamethodmodifiers close() "private"; - %rename(closeNativeResource) close(); -#endif - void close(); - /** * Gets the absolute path of the directory where the EPC document is stored. * @@ -4038,10 +4015,11 @@ import java.lang.AutoCloseable; * @param key The key of the property. * @param value The value of the property. */ - void setExtendedCoreProperty(const std::string & key, const std::string & value); + void setExtendedCoreProperty(const std::string& key, const std::string& value); /** * Gets extended core property count. + * The EpcDocument must have been deserialized at least once to get the extended core proeprties information. * * @returns The count of extended core properties in this EPC document */ @@ -4049,13 +4027,14 @@ import java.lang.AutoCloseable; /** * Gets an extended core property value according to its key. + * The EpcDocument must have been deserialized at least once to get the extended core proeprties information. * * @param key The key of the property. * * @returns An empty string if the extended core property does not exist. Or the extended core * property value if it exists. */ - std::string getExtendedCoreProperty(const std::string & key); + std::string getExtendedCoreProperty(const std::string& key) const; }; class EnumStringMapper diff --git a/swig/swigResqml2Include.i b/swig/swigResqml2Include.i index c0eb10b2e..e810f1f3e 100644 --- a/swig/swigResqml2Include.i +++ b/swig/swigResqml2Include.i @@ -2058,7 +2058,7 @@ namespace RESQML2_NS * @param colorCount the size (number of colors) of the color map * @param rgbColors array (of size colorCount * 3) of RGB colors with hsvColors[3*i] is red componant, hsvColors[3*i + 1] is green component and hsvColors[3*i + 2] is blue component of the ith color (red, green and blue are in range [0, 255]) * @param alphas array (of size colorCount) of numeric values in the range [0, 1] for alpha transparency channel (0 means transparent and 1 means opaque). If alphas == nullptr (default value), default alpha value is 1. - * @param indices array (of size solorCount) of color indices. These indices are cast to unsigned int in the case of a discrete color map. If indices == nullptr (default value), indices are set from 0 to colorCount - 1 + * @param indices array (of size colorCount) of color indices. These indices are cast to unsigned int in the case of a discrete color map. If indices == nullptr (default value), indices are set from 0 to colorCount - 1 * @param colorTitles vector (of size colorCount) of color titles. Titles are not set if colorTitles is empty (default value) */ void setRgbColors(uint64_t colorCount, @@ -5901,6 +5901,13 @@ namespace RESQML2_NS * @returns The data type of the values if successful, else @c UNKNOWN. */ COMMON_NS::AbstractObject::numericalDatatypeEnum getValuesHdfDatatype() const; + + /** + * Get the number of values in each dimension into the underlying HDF5 dataset. + * uint32_t is returned instead of uint64_t cause of some SWIG usage. I cannot SWIG port std::vector + * @param patchIndex The index of the patch we want to count the values from. + */ + std::vector getValuesCountPerDimensionOfPatch(uint64_t patchIndex) const; /** * Gets the count of all values contained into the underlying HDF5 dataset of a given patch of @@ -5912,7 +5919,7 @@ namespace RESQML2_NS * * @returns The count of values of the @p patchIndex patch. */ - uint64_t getValuesCountOfPatch(unsigned int patchIndex) const; + uint64_t getValuesCountOfPatch(uint64_t patchIndex) const; /** * Gets the count of values on a specific dimension of the underlying HDF5 dataset of a given @@ -5926,7 +5933,7 @@ namespace RESQML2_NS * * @returns The count of values in the @p dimIndex dimension of @p patchIndex patch. */ - uint64_t getValuesCountOfDimensionOfPatch(uint64_t dimIndex, unsigned int patchIndex) const; + uint64_t getValuesCountOfDimensionOfPatch(uint64_t dimIndex, uint64_t patchIndex) const; /** * Gets the count of dimensions of the underlying HDF5 dataset of a given patch of this property. @@ -5937,7 +5944,7 @@ namespace RESQML2_NS * * @returns The number of values, 0 otherwise. */ - uint64_t getDimensionsCountOfPatch(unsigned int patchIndex) const; + uint64_t getDimensionsCountOfPatch(uint64_t patchIndex) const; std::string getPropertyKindDescription() const; std::string getPropertyKindAsString() const; @@ -8668,7 +8675,7 @@ namespace RESQML2_NS * then a default HDF proxy must be defined in the * repository. */ - void pushBackArrayOfXyzPoints(double const * xyzPoints, uint64_t const * pointCountByDimension, unsigned int numArrayDimensions, EML2_NS::AbstractHdfProxy* proxy = nullptr); + void pushBackArrayOfXyzPoints(double const * xyzPoints, uint64_t const * pointCountByDimension, uint32_t numArrayDimensions, EML2_NS::AbstractHdfProxy* proxy = nullptr); /** * Pushes back a reference to an existing (or a "to exist") HDF dataset in a particular HDF @@ -8997,6 +9004,13 @@ namespace RESQML2_NS * @returns The unit of measure of the MDs along this trajectory. */ gsoap_resqml2_0_1::eml20__LengthUom getMdUom() const; + + /** + * Gets the unit of measure of the MDs along this trajectory as a string. + * + * @returns The unit of measure of the MDs along this trajectory as a string. + */ + std::string getMdUomAsString() const; /** * Gets the MD double values associated to each trajectory station of this trajectory. diff --git a/test/AbstractTest.cpp b/test/AbstractTest.cpp index af29768f5..a3d031c66 100644 --- a/test/AbstractTest.cpp +++ b/test/AbstractTest.cpp @@ -45,7 +45,6 @@ void AbstractTest::serialize() { initRepo(); epcDocument.serializeFrom(*repo); - epcDocument.close(); delete repo; } @@ -61,7 +60,6 @@ void AbstractTest::deserialize() { } readRepo(); - epcDocument.close(); delete repo; } diff --git a/test/resqml2_test/ContinuousProperty.cpp b/test/resqml2_test/ContinuousProperty.cpp index 73426256e..a2daa2d4b 100644 --- a/test/resqml2_test/ContinuousProperty.cpp +++ b/test/resqml2_test/ContinuousProperty.cpp @@ -114,6 +114,8 @@ void ContinuousProperty::readRepo() { REQUIRE(noMinMaxFltProperty->getElementCountPerValue() == 1); REQUIRE(noMinMaxFltProperty->getAttachmentKind() == gsoap_eml2_3::eml23__IndexableElement::cells); REQUIRE(noMinMaxFltProperty->getUom() == gsoap_resqml2_0_1::resqml20__ResqmlUom::Pa); + auto valuesCount = noMinMaxFltProperty->getValuesCountPerDimensionOfPatch(0); + REQUIRE(std::equal(std::begin(valuesCount), std::end(valuesCount), std::begin({ 4, 3, 2 }))); REQUIRE(noMinMaxFltProperty->getValuesCountOfPatch(0) == 24); float fltValues[24]; noMinMaxFltProperty->getFloatValuesOfPatch(0, fltValues); @@ -193,6 +195,8 @@ void ContinuousProperty::readRepo() { REQUIRE(!forcingMinMaxDblProperty->hasConstantValues(0)); RESQML2_NS::ContinuousProperty* constantFloatingPointProperty = repo->getDataObjectByUuid("3ce662a6-c94b-4d19-b9df-b241693dba41"); + valuesCount = constantFloatingPointProperty->getValuesCountPerDimensionOfPatch(0); + REQUIRE(std::equal(std::begin(valuesCount), std::end(valuesCount), std::begin({ 3 }))); REQUIRE(constantFloatingPointProperty->getValuesCountOfPatch(0) == 3); double constantFloatingPointValues[3]; constantFloatingPointProperty->getDoubleValuesOfPatch(0, constantFloatingPointValues); @@ -202,5 +206,4 @@ void ContinuousProperty::readRepo() { REQUIRE(constantFloatingPointProperty->hasConstantValues(0)); REQUIRE_THROWS(constantFloatingPointProperty->getInt64ConstantValuesOfPatch(0)); REQUIRE(constantFloatingPointProperty->getDoubleConstantValuesOfPatch(0) == 3.33); - } diff --git a/test/unitTest.cpp b/test/unitTest.cpp index f44d0489c..276cec26d 100644 --- a/test/unitTest.cpp +++ b/test/unitTest.cpp @@ -1,4 +1,4 @@ -/*----------------------------------------------------------------------- +/*----------------------------------------------------------------------- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information @@ -23,6 +23,7 @@ under the License. #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file #include "catch.hpp" +#include #include "common/DataObjectRepository.h" #include "eml2/AbstractHdfProxy.h" @@ -80,6 +81,7 @@ under the License. #include "witsml2_test/Trajectory.h" #include "witsml2_test/Perforation.h" #include "witsml2_test/WellboreGeometryTest.h" +#include "witsml2_test/WellboreCompletion.h" #if WITH_RESQML2_2 #include "eml2_3test/GraphicalInformationSetTest.h" #include "resqml2_2test/DiscreteColorMapTest.h" @@ -97,7 +99,7 @@ using namespace witsml2_test; #define FESAPI_TEST2_2(name, tags, classTest) TEST_CASE(#name " 2_2", tags)\ {\ - classTest test("../../" #classTest "2_2.epc");\ + classTest test(u8"../../" #classTest "2_2.epc");\ test.defaultEmlVersion = COMMON_NS::DataObjectRepository::EnergisticsStandard::EML2_3;\ test.defaultResqmlVersion = COMMON_NS::DataObjectRepository::EnergisticsStandard::RESQML2_2;\ test.serialize();\ @@ -106,7 +108,7 @@ using namespace witsml2_test; #define FESAPI_TEST2_0(name, tags, classTest) TEST_CASE(#name " 2_0", tags)\ {\ - classTest test("../../" #classTest "2_0.epc");\ + classTest test(u8"../../" #classTest "2_0.epc");\ test.defaultEmlVersion = COMMON_NS::DataObjectRepository::EnergisticsStandard::EML2_0;\ test.defaultResqmlVersion = COMMON_NS::DataObjectRepository::EnergisticsStandard::RESQML2_0_1;\ test.serialize();\ @@ -132,15 +134,26 @@ FESAPI_TEST2_2("Export and import regular seismic wellbore frame", "[well]", Sei #endif TEST_CASE("Export and import an empty EPC document", "[epc]") { - EpcDocumentTest testIn("../../EpcDocumentTest"); + EpcDocumentTest testIn(u8"../../EpcDocumentTest"); testIn.serialize(); // Check that the epc file extension has properly been added at previous step. - EpcDocumentTest testOut("../../EpcDocumentTest.epc"); + EpcDocumentTest testOut(u8"../../EpcDocumentTest.epc"); testOut.deserialize(); } +TEST_CASE("Export and import an empty UTF8 EPC document", "[epc]") +{ + std::filesystem::create_directory(std::filesystem::u8path(u8"../../UTF8_Test_µŋß")); + + EpcDocumentTest testIn(u8"../../UTF8_Test_µŋß/UTF8_Test_çéè.epc"); + testIn.serialize(); + + EpcDocumentTest testOut(u8"../../UTF8_Test_µŋß/UTF8_Test_çéè.epc"); + testOut.deserialize(); +} + TEST_CASE("Set a wrong UUID", "[UUID]") { COMMON_NS::DataObjectRepository repo; @@ -149,7 +162,7 @@ TEST_CASE("Set a wrong UUID", "[UUID]") TEST_CASE("Test hdf5 opening mode", "[hdf]") { - std::remove("../../testingFile.h5"); + std::filesystem::remove("../../testingFile.h5"); COMMON_NS::DataObjectRepository repo; EML2_NS::AbstractHdfProxy* hdfProxy = repo.createHdfProxy("", "Hdf Proxy Test", "../../", "testingFile.h5", COMMON_NS::DataObjectRepository::openingMode::READ_ONLY); @@ -273,6 +286,7 @@ FESAPI_TEST("Export and import a WITSML well", "[well]", WellTest) FESAPI_TEST("Export and import a WITSML trajectory", "[well]", Trajectory) FESAPI_TEST("Export and import a WITSML perforation", "[well]", Perforation) FESAPI_TEST("Export and import a WITSML Wellbore Geometry", "[well]", WellboreGeometryTest) +FESAPI_TEST("Export and import a WITSML Wellbore Completion", "[well]", WellboreCompletion) // SEISMIC FESAPI_TEST("Export and import a seismic lattice feature", "[seismic]", SeismicLatticeRepresentationTest) diff --git a/test/witsml2_test/WellboreCompletion.cpp b/test/witsml2_test/WellboreCompletion.cpp new file mode 100644 index 000000000..883fc13d8 --- /dev/null +++ b/test/witsml2_test/WellboreCompletion.cpp @@ -0,0 +1,92 @@ +/*----------------------------------------------------------------------- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"; you may not use this file except in compliance +with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +-----------------------------------------------------------------------*/ +#include "WellboreCompletion.h" + +#include + +#include "../catch.hpp" + +#include "witsml2_1/Wellbore.h" +#include "witsml2_1/WellboreCompletion.h" + +using namespace std; +using namespace witsml2_test; +using namespace COMMON_NS; + +WellboreCompletion::WellboreCompletion(const string& epcDocPath) + : AbstractTest(epcDocPath) { +} + +void WellboreCompletion::initRepo() { + WITSML2_NS::Wellbore* wellbore = repo->createPartial("", ""); + WITSML2_1_NS::WellboreCompletion* witsmlWbCompletion = repo->createWellboreCompletion(wellbore, defaultUuid, defaultTitle); + + witsmlWbCompletion->pushBackConnection(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, gsoap_eml2_3::eml23__LengthUom::m, 1000, 1100, "uid0"); + witsmlWbCompletion->pushBackConnection(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::GRAVEL_PACK, gsoap_eml2_3::eml23__LengthUom::m, 1200, 1300, "uid1"); + witsmlWbCompletion->pushBackConnection(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::OPEN_HOLE, gsoap_eml2_3::eml23__LengthUom::m, 1300, 1400, "uid2"); + witsmlWbCompletion->pushBackConnection(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::SLOTS, gsoap_eml2_3::eml23__LengthUom::ft, 5500, 5600, "uid3"); + witsmlWbCompletion->pushBackConnection(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, gsoap_eml2_3::eml23__LengthUom::m, 10000, 11000, "uid4"); + + witsmlWbCompletion->pushBackConnectionHistory(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1); + witsmlWbCompletion->pushBackConnectionHistory(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1); + witsmlWbCompletion->pushBackConnectionHistory(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::GRAVEL_PACK, 0); + witsmlWbCompletion->pushBackConnectionHistory(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::OPEN_HOLE, 0); + witsmlWbCompletion->pushBackConnectionExtraMetadata(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::SLOTS, 0, "testingExtraMetadataKey", "testingExtraMetadataValue"); + + witsmlWbCompletion->setConnectionHistoryMdInterval(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1, gsoap_eml2_3::eml23__LengthUom::m, 1000, 1100); + witsmlWbCompletion->setConnectionHistoryMdInterval(1, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1, gsoap_eml2_3::eml23__LengthUom::m, 1000, 1100); + witsmlWbCompletion->setConnectionHistoryStatus(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1, gsoap_eml2_3::witsml21__PhysicalStatus::open); + witsmlWbCompletion->setConnectionHistoryStatus(1, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1, gsoap_eml2_3::witsml21__PhysicalStatus::closed); + witsmlWbCompletion->setConnectionHistoryStartDate(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1, 0); + witsmlWbCompletion->setConnectionHistoryEndDate(1, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1, 3600); + witsmlWbCompletion->setConnectionHistoryStartDate(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::GRAVEL_PACK, 0, 7200); + witsmlWbCompletion->setConnectionHistoryEndDate(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::GRAVEL_PACK, 0, 8000); +} + +void WellboreCompletion::readRepo() { + WITSML2_1_NS::WellboreCompletion* witsmlWbCompletion = repo->getDataObjectByUuid(defaultUuid); + REQUIRE (witsmlWbCompletion != nullptr); + + REQUIRE(witsmlWbCompletion->getConnectionCount(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION) == 2); + REQUIRE(witsmlWbCompletion->getConnectionCount(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::GRAVEL_PACK) == 1); + REQUIRE(witsmlWbCompletion->getConnectionCount(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::OPEN_HOLE) == 1); + REQUIRE(witsmlWbCompletion->getConnectionCount(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::SLOTS) == 1); + + REQUIRE(witsmlWbCompletion->getConnectionHistoryCount(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 0) == 0); + REQUIRE(witsmlWbCompletion->getConnectionHistoryCount(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1) == 2); + REQUIRE(witsmlWbCompletion->getConnectionHistoryCount(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::GRAVEL_PACK, 0) == 1); + REQUIRE(witsmlWbCompletion->getConnectionHistoryCount(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::OPEN_HOLE, 0) == 1); + REQUIRE(witsmlWbCompletion->getConnectionHistoryCount(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::SLOTS, 0) == 0); + REQUIRE(witsmlWbCompletion->getConnectionExtraMetadata(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::SLOTS, 0, "testingExtraMetadataKey").size() == 1); + REQUIRE(witsmlWbCompletion->getConnectionExtraMetadata(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::SLOTS, 0, "testingExtraMetadataKey")[0] == "testingExtraMetadataValue"); + REQUIRE_THROWS(witsmlWbCompletion->getConnectionHistoryCount(WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::GRAVEL_PACK, 1) == 0); + + REQUIRE(witsmlWbCompletion->getConnectionHistoryTopMd(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1) == 1000); + REQUIRE(witsmlWbCompletion->getConnectionHistoryBaseMd(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1) == 1100); + REQUIRE(witsmlWbCompletion->getConnectionHistoryTopMd(1, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1) == 1000); + REQUIRE(witsmlWbCompletion->getConnectionHistoryBaseMd(1, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1) == 1100); + REQUIRE(witsmlWbCompletion->getConnectionHistoryStatus(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1) == gsoap_eml2_3::witsml21__PhysicalStatus::open); + REQUIRE(witsmlWbCompletion->getConnectionHistoryStatus(1, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1) == gsoap_eml2_3::witsml21__PhysicalStatus::closed); + REQUIRE(witsmlWbCompletion->getConnectionHistoryStartDate(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1) == 0); + REQUIRE(!witsmlWbCompletion->hasConnectionHistoryEndDate(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1)); + REQUIRE(witsmlWbCompletion->getConnectionHistoryEndDate(1, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1) == 3600); + REQUIRE(!witsmlWbCompletion->hasConnectionHistoryStartDate(1, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::PERFORATION, 1)); + REQUIRE(witsmlWbCompletion->getConnectionHistoryStartDate(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::GRAVEL_PACK, 0) == 7200); + REQUIRE(witsmlWbCompletion->getConnectionHistoryEndDate(0, WITSML2_1_NS::WellboreCompletion::WellReservoirConnectionType::GRAVEL_PACK, 0) == 8000); +} diff --git a/test/witsml2_test/WellboreGeometry.h b/test/witsml2_test/WellboreCompletion.h similarity index 64% rename from test/witsml2_test/WellboreGeometry.h rename to test/witsml2_test/WellboreCompletion.h index 1ff7925ee..9149e15d6 100644 --- a/test/witsml2_test/WellboreGeometry.h +++ b/test/witsml2_test/WellboreCompletion.h @@ -21,33 +21,21 @@ under the License. #include "../AbstractTest.h" #include -namespace COMMON_NS { - class DataObjectRepository; -} - namespace witsml2_test { - class WellboreGeometryTest : public commontest::AbstractTest { + class WellboreCompletion : public commontest::AbstractTest { public: - static const char* defaultUuid; - static const char* defaultTitle; + static constexpr char const* defaultUuid = "27ff6ec3-ad84-4ac2-baa1-1f050259404d"; + static constexpr char const* defaultTitle = "testing wellbore completion"; /** * Creation of a testing object from an EPC document path. At serialize() call, - * exising .epc file will be erased. + * existing .epc file will be erased. * @param epcDocPath the path of the .epc file (including .epc extension) */ - WellboreGeometryTest(const std::string & epcDocPath); + WellboreCompletion(const std::string& epcDocPath); - /** - * Creation of a testing object from an existing EPC document. - * @param repo an existing EPC document - * @param init true if this object is created for initialization purpose else false if it is - * created for reading purpose. According to init value a iniEpcDoc() or readRepo() is called. - */ - WellboreGeometryTest(COMMON_NS::DataObjectRepository* repo, bool init); protected: void initRepo(); void readRepo(); }; } - diff --git a/test/witsml2_test/WellboreGeometryTest.cpp b/test/witsml2_test/WellboreGeometryTest.cpp index 02e5b1039..ffc2cd791 100644 --- a/test/witsml2_test/WellboreGeometryTest.cpp +++ b/test/witsml2_test/WellboreGeometryTest.cpp @@ -17,11 +17,13 @@ specific language governing permissions and limitations under the License. -----------------------------------------------------------------------*/ #include "WellboreGeometryTest.h" + +#include + #include "../catch.hpp" -#include "witsml2_1/Well.h" + #include "witsml2_1/Wellbore.h" #include "witsml2_1/WellboreGeometry.h" -#include using namespace std; using namespace witsml2_test; @@ -35,7 +37,7 @@ WellboreGeometryTest::WellboreGeometryTest(const string & epcDocPath) } void WellboreGeometryTest::initRepo() { - WITSML2_1_NS::Wellbore* wellbore = repo->createPartial("", ""); + WITSML2_NS::Wellbore* wellbore = repo->createPartial("", ""); WITSML2_1_NS::WellboreGeometry* witsmlWbGeom = repo->createWellboreGeometry(wellbore, defaultUuid, "WellboreGeometry TEST", false); witsmlWbGeom->pushBackSection(0, 250, gsoap_eml2_3::eml23__LengthUom::m);