diff --git a/.gitmodules b/.gitmodules index 4e6ebfab1..c31ab3f6d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "Tests/googletest"] path = Tests/googletest url = https://github.com/google/googletest.git +[submodule "Tests/libressl"] + path = Tests/libressl + url = https://github.com/3MFConsortium/forks-libressl-distribution.git diff --git a/.travis.yml b/.travis.yml index dff705bf3..cb2a6434d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,13 +11,21 @@ services: matrix: include: - os: linux + dist: bionic compiler: gcc - env: BUILDMODE=cmake-make + env: BUILDMODE=cmake-make-linux + addons: + apt: + packages: + - valgrind + - os: osx + osx_image: xcode10.1 + env: BUILDMODE=cmake-make-osx - os: osx osx_image: xcode7.2 - env: BUILDMODE=cmake-make - - os: linux - env: BUILDMODE=ppcxenial + env: BUILDMODE=cmake-make-osx + - os: windows + env: BUILDMODE=windows - os: linux dist: trusty compiler: x86_64-w64-mingw32-g++ @@ -33,15 +41,12 @@ matrix: before_script: - if [[ "$BUILDMODE" = "cmake-mingw32" ]]; then sh cmake/GenerateMinGW.sh; cd build; fi - - if [[ "$BUILDMODE" = "cmake-make" ]]; then sh cmake/GenerateMake.sh; cd build; fi - - if [[ "$BUILDMODE" = "ppcxenial" ]]; then - docker pull multiarch/qemu-user-static ; - docker pull multiarch/ubuntu-debootstrap:powerpc-xenial ; - docker run --rm --privileged multiarch/qemu-user-static --reset -p y ; - docker build -t ppc-xenial -f CI/Dockerfile . ; - fi + - if [[ "$BUILDMODE" = "cmake-make-linux" ]]; then sh cmake/GenerateMake.sh; cd build; fi + - if [[ "$BUILDMODE" = "cmake-make-osx" ]]; then sh cmake/GenerateMake.sh; cd build; fi + - if [[ "$BUILDMODE" = "windows" ]]; then cmake/GenerateVS2017.bat; cd build; fi script: - - if [[ "$BUILDMODE" != "ppcxenial" ]]; then cmake --build . ; fi - - if [[ "$BUILDMODE" == "cmake-make" ]]; then ctest -V ; fi - - if [[ "$BUILDMODE" == "ppcxenial" ]]; then docker run ppc-xenial; fi + - if [[ "$BUILDMODE" != "ppcxenial" ]]; then cmake --build .; fi + - if [[ "$BUILDMODE" == "cmake-make-linux" ]]; then ctest -V; cmake --build . --target lib3mf_memcheck; fi + - if [[ "$BUILDMODE" == "cmake-make-osx" ]]; then ctest -V; fi + - if [[ "$BUILDMODE" == "windows" ]]; then ctest -V ; fi diff --git a/AutomaticComponentToolkit/lib3mf.xml b/AutomaticComponentToolkit/lib3mf.xml index 90da0379d..c0fb0fb57 100644 --- a/AutomaticComponentToolkit/lib3mf.xml +++ b/AutomaticComponentToolkit/lib3mf.xml @@ -1,5 +1,5 @@ - + @@ -76,6 +76,11 @@ + + + + + @@ -139,6 +144,12 @@ + + + @@ -225,6 +237,11 @@ + + + + + @@ -248,6 +265,13 @@ + + + + + + + @@ -277,6 +301,29 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -316,11 +363,41 @@ - + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + @@ -574,11 +651,11 @@ - + - + @@ -619,18 +696,26 @@ - + - + - + - + + + + + + + + + @@ -653,6 +738,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -666,11 +772,11 @@ - + - - + + @@ -727,6 +833,15 @@ + + + + + + + + + @@ -871,12 +986,15 @@ - + - + + + + @@ -952,8 +1070,8 @@ - - + + @@ -1066,7 +1184,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1087,44 +1411,44 @@ - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -1218,7 +1542,7 @@ - + @@ -1248,13 +1572,20 @@ - + - + + + + + + + + diff --git a/CI/script.sh b/CI/script.sh index bc13583b0..389ab6362 100644 --- a/CI/script.sh +++ b/CI/script.sh @@ -1,7 +1,7 @@ #!/bin/sh cd lib3mf-repo -sh cmake/GenerateMake.sh +sh cmake/GenerateMakeFast.sh cd build -make -j2 +make -j1 ctest -V . diff --git a/CMakeLists.txt b/CMakeLists.txt index fc30af280..9c8b4ba3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,23 +5,26 @@ cmake_policy(SET CMP0048 NEW) set_property(GLOBAL PROPERTY USE_FOLDERS ON) -project(lib3mf) - - include(GNUInstallDirs) # Define Version set(LIB3MF_VERSION_MAJOR 2) # increase on every backward-compatibility breaking change of the API -set(LIB3MF_VERSION_MINOR 0) # increase on every backward compatible change of the API +set(LIB3MF_VERSION_MINOR 1) # increase on every backward compatible change of the API set(LIB3MF_VERSION_MICRO 0) # increase on on every change that does not alter the API set(LIB3MF_VERSION_PRERELEASE "") # denotes pre-release information of a version of lib3mf +project(lib3mf + VERSION ${LIB3MF_VERSION_MAJOR}.${LIB3MF_VERSION_MINOR}.${LIB3MF_VERSION_MICRO} + DESCRIPTION "An implementation of the 3D Manufacturing Format file standard") + set(CMAKE_INSTALL_BINDIR bin CACHE PATH "directory for installing binary files") set(CMAKE_INSTALL_LIBDIR lib CACHE PATH "directory for installing library files") set(CMAKE_INSTALL_INCLUDEDIR include/lib3mf CACHE PATH "directory for installing header files") option(USE_INCLUDED_ZLIB "Use included zlib" ON) option(USE_INCLUDED_LIBZIP "Use included libzip" ON) +option(USE_INCLUDED_GTEST "Used included gtest" ON) +option(USE_INCLUDED_SSL "Use included libressl" ON) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # using GCC @@ -50,13 +53,13 @@ if (${MSVC}) endif() ### The API generation target -if(UNIX OR MINGW) +if(CMAKE_HOST_UNIX) if(APPLE) set(ACT_COMMANDENDING darwin) else() set(ACT_COMMANDENDING linux) endif() -elseif(WIN32) +elseif(CMAKE_HOST_WIN32) set(ACT_COMMANDENDING exe) endif() @@ -152,6 +155,18 @@ target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR_AU target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include/API) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include) +if (NOT USE_INCLUDED_LIBZIP) + find_package(PkgConfig REQUIRED) + pkg_check_modules(LIBZIP REQUIRED libzip) + target_link_libraries(${PROJECT_NAME} ${LIBZIP_LIBRARIES}) +endif() +if (NOT USE_INCLUDED_ZLIB) + find_package(PkgConfig REQUIRED) + pkg_check_modules(ZLIB REQUIRED zlib) + target_link_libraries(${PROJECT_NAME} ${ZLIB_LIBRARIES}) +endif() + + set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" IMPORT_PREFIX "" ) # This makes sure symbols are exported target_compile_options(${PROJECT_NAME} PRIVATE "-D__LIB3MF_EXPORTS") @@ -176,6 +191,8 @@ else() target_compile_options(${PROJECT_NAME} PUBLIC "$<$:/O2;/sdl;/WX;/Oi;/Gy;/FC;/wd4996>") endif() +configure_file(lib3mf.pc.in lib3mf.pc @ONLY) +install(FILES ${CMAKE_BINARY_DIR}/lib3mf.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" diff --git a/Documentation/conf.py b/Documentation/conf.py index 3e2a73883..056977299 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -22,7 +22,7 @@ author = '3MF Consortium' # The full version, including alpha/beta/rc tags -release = 'v2.0.0' +release = 'v2.1.0' master_doc = 'index' diff --git a/Documentation/index.rst b/Documentation/index.rst index 33c3d4516..1b1fbdcad 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -1,7 +1,7 @@ .. lib3mf documentation master file ********************************************* -lib3mf v2.0.0 documentation +lib3mf v2.1.0 documentation ********************************************* .. image:: https://travis-ci.org/3MFConsortium/lib3mf.svg?branch=master @@ -12,7 +12,7 @@ lib3mf v2.0.0 documentation :target: https://readthedocs.org/projects/lib3mf/ :alt: Documentation Status -.. image:: https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.0.0&color=green +.. image:: https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.1.0&color=green :alt: Version .. image:: https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey @@ -27,7 +27,7 @@ lib3mf v2.0.0 documentation :language: bash -Welcome! This is the documentation for lib3mf v2.0.0. +Welcome! This is the documentation for lib3mf v2.1.0. lib3mf is an implementation of the 3D Manufacturing Format file standard. diff --git a/Documentation/source/Cpp/lib3mf-types.rst b/Documentation/source/Cpp/lib3mf-types.rst index 236e038b3..f2667a6de 100644 --- a/Documentation/source/Cpp/lib3mf-types.rst +++ b/Documentation/source/Cpp/lib3mf-types.rst @@ -96,6 +96,12 @@ Enumerations .. cpp:enumerator:: Inside = 1 .. cpp:enumerator:: Outside = 2 + .. cpp:enum-class:: eBeamLatticeBallMode : Lib3MF_int32 + + .. cpp:enumerator:: None = 0 + .. cpp:enumerator:: Mixed = 1 + .. cpp:enumerator:: All = 2 + .. cpp:enum-class:: eProgressIdentifier : Lib3MF_int32 .. cpp:enumerator:: QUERYCANCELED = 0 @@ -121,6 +127,7 @@ Enumerations .. cpp:enumerator:: WRITENODES = 20 .. cpp:enumerator:: WRITETRIANGLES = 21 .. cpp:enumerator:: WRITESLICES = 22 + .. cpp:enumerator:: WRITEKEYSTORE = 23 .. cpp:enum-class:: eBlendMethod : Lib3MF_int32 @@ -128,6 +135,32 @@ Enumerations .. cpp:enumerator:: Mix = 1 .. cpp:enumerator:: Multiply = 2 + .. cpp:enum-class:: eEncryptionAlgorithm : Lib3MF_int32 + + .. cpp:enumerator:: AES256_GCM = 1 + + .. cpp:enum-class:: eWrappingAlgorithm : Lib3MF_int32 + + .. cpp:enumerator:: RSA_OAEP = 0 + + .. cpp:enum-class:: eMgfAlgorithm : Lib3MF_int32 + + .. cpp:enumerator:: MGF1_SHA1 = 160 + .. cpp:enumerator:: MGF1_SHA224 = 224 + .. cpp:enumerator:: MGF1_SHA256 = 256 + .. cpp:enumerator:: MGF1_SHA384 = 384 + .. cpp:enumerator:: MGF1_SHA512 = 512 + + .. cpp:enum-class:: eDigestMethod : Lib3MF_int32 + + .. cpp:enumerator:: SHA1 = 160 + .. cpp:enumerator:: SHA256 = 256 + + .. cpp:enum-class:: eCompression : Lib3MF_int32 + + .. cpp:enumerator:: NoCompression = 0 + .. cpp:enumerator:: Deflate = 1 + Structs -------------- @@ -213,6 +246,12 @@ Structs .. cpp:member:: eBeamLatticeCapMode m_CapModes[2] + .. cpp:struct:: sBall + + .. cpp:member:: Lib3MF_uint32 m_Index + + .. cpp:member:: Lib3MF_double m_Radius + Function types --------------- @@ -250,6 +289,41 @@ Function types :param nPosition: Position in the stream to move to :param pUserData: Userdata that is passed to the callback function + .. cpp:type:: RandomNumberCallback = void(*)(Lib3MF_uint64, Lib3MF_uint64, Lib3MF_pvoid, Lib3MF_uint64*) + + Callback to generate random numbers + + :param nByteData: Pointer to a buffer to read data into + :param nNumBytes: Size of available bytes in the buffer + :param pUserData: Userdata that is passed to the callback function + :return: Number of bytes generated when succeed. 0 or less if failed. + + .. cpp:type:: KeyWrappingCallback = void(*)(Lib3MF_AccessRight, Lib3MF_uint8 *, Lib3MF_uint8 **, Lib3MF_pvoid, Lib3MF_uint64*) + + A callback used to wrap (encrypt) the content key available in keystore resource group + + :param pKEKParams: The information about the parameters used used to wrap the key to the contents + :param nInBufferBufferSize: Buffer to the input value. When encrypting, this should be the plain key. When decrypting, this should be the key cipher. + :param nInBufferBufferSize: buffer of Buffer to the input value. When encrypting, this should be the plain key. When decrypting, this should be the key cipher. + :param nOutBufferBufferSize: Number of elements in buffer + :param pOutBufferNeededCount: will be filled with the count of the written elements, or needed buffer size. + :param pOutBufferBuffer: buffer of Buffer where the data will be placed. When encrypting, this will be the key cipher. When decrypting, this will be the plain key. When buffer is null, neededBytes contains the required bytes to run. + :param pUserData: Userdata that is passed to the callback function + :return: The needed/encrypted/decrypted bytes when succeed or zero when error. + + .. cpp:type:: ContentEncryptionCallback = void(*)(Lib3MF_ContentEncryptionParams, Lib3MF_uint8 *, Lib3MF_uint8 **, Lib3MF_pvoid, Lib3MF_uint64*) + + A callback to encrypt/decrypt content called on each resource encrypted. This might be called several times depending on content size. If Input is not available(either null or size is 0), clients must return the result of authenticated tag generation/validation. + + :param pCEKParams: The params of the encryption process. Client must set/check AuthenticationTag when closing the encryption/decryption process. + :param nInputBufferSize: Buffer to the original data. In encrypting, this will be the plain data. If decrypting, this will be the cipher data + :param nInputBufferSize: buffer of Buffer to the original data. In encrypting, this will be the plain data. If decrypting, this will be the cipher data + :param nOutputBufferSize: Number of elements in buffer + :param pOutputNeededCount: will be filled with the count of the written elements, or needed buffer size. + :param pOutputBuffer: buffer of Buffer to hold the transformed data. When encrypting, this will be the cipher data. When decrypting, this shall be the plain data. If buffer is null, neededBytes return the necessary amount of bytes. + :param pUserData: Userdata that is passed to the callback function + :return: The needed/encrypted/decrypted/verified bytes when succeed or zero when error. + ELib3MFException: The standard exception class of the 3MF Library diff --git a/Documentation/source/Cpp/lib3mf_AccessRight.rst b/Documentation/source/Cpp/lib3mf_AccessRight.rst new file mode 100644 index 000000000..8de03694f --- /dev/null +++ b/Documentation/source/Cpp/lib3mf_AccessRight.rst @@ -0,0 +1,44 @@ + +CAccessRight +==================================================================================================== + + +.. cpp:class:: Lib3MF::CAccessRight : public CBase + + + + + + + .. cpp:function:: PConsumer GetConsumer() + + Gets the consumer associated with this access right + + :returns: The consumer instance + + + .. cpp:function:: eWrappingAlgorithm GetWrappingAlgorithm() + + Gets the associated encryption algorithm + + :returns: The algorithm used for the key in this accessright + + + .. cpp:function:: eMgfAlgorithm GetMgfAlgorithm() + + Gets the associated mask generation function algorithm + + :returns: The MFG1 algorithm + + + .. cpp:function:: eDigestMethod GetDigestMethod() + + Gets the digest method assoicated + + :returns: The digest method for this accessright + + +.. cpp:type:: std::shared_ptr Lib3MF::PAccessRight + + Shared pointer to CAccessRight to easily allow reference counting. + diff --git a/Documentation/source/Cpp/lib3mf_Attachment.rst b/Documentation/source/Cpp/lib3mf_Attachment.rst index 2787d02b6..b09cf9308 100644 --- a/Documentation/source/Cpp/lib3mf_Attachment.rst +++ b/Documentation/source/Cpp/lib3mf_Attachment.rst @@ -12,18 +12,25 @@ CAttachment .. cpp:function:: std::string GetPath() - Retrieves an attachment's package path. + Retrieves an attachment's package path. This function will be removed in a later release. :returns: returns the attachment's package path string .. cpp:function:: void SetPath(const std::string & sPath) - Sets an attachment's package path. + Sets an attachment's package path. This function will be removed in a later release. :param sPath: new path of the attachment. + .. cpp:function:: PPackagePart PackagePart() + + Returns the PackagePart that is this attachment. + + :returns: The PackagePart of this attachment. + + .. cpp:function:: std::string GetRelationShipType() Retrieves an attachment's relationship type diff --git a/Documentation/source/Cpp/lib3mf_BeamLattice.rst b/Documentation/source/Cpp/lib3mf_BeamLattice.rst index 6d3889e80..0dd03ac5e 100644 --- a/Documentation/source/Cpp/lib3mf_BeamLattice.rst +++ b/Documentation/source/Cpp/lib3mf_BeamLattice.rst @@ -24,36 +24,51 @@ CBeamLattice :param dMinLength: minimal length of beams for the beamlattice - .. cpp:function:: void GetClipping(eBeamLatticeClipMode & eClipMode, Lib3MF_uint32 & nResourceID) + .. cpp:function:: void GetClipping(eBeamLatticeClipMode & eClipMode, Lib3MF_uint32 & nUniqueResourceID) Returns the clipping mode and the clipping-mesh for the beamlattice of this mesh. :param eClipMode: contains the clip mode of this mesh - :param nResourceID: filled with the resourceID of the clipping mesh-object or an undefined value if pClipMode is MODELBEAMLATTICECLIPMODE_NONE + :param nUniqueResourceID: filled with the UniqueResourceID of the clipping mesh-object or an undefined value if pClipMode is MODELBEAMLATTICECLIPMODE_NONE - .. cpp:function:: void SetClipping(const eBeamLatticeClipMode eClipMode, const Lib3MF_uint32 nResourceID) + .. cpp:function:: void SetClipping(const eBeamLatticeClipMode eClipMode, const Lib3MF_uint32 nUniqueResourceID) Sets the clipping mode and the clipping-mesh for the beamlattice of this mesh. :param eClipMode: contains the clip mode of this mesh - :param nResourceID: the resourceID of the clipping mesh-object. This mesh-object has to be defined before setting the Clipping. + :param nUniqueResourceID: the UniqueResourceID of the clipping mesh-object. This mesh-object has to be defined before setting the Clipping. - .. cpp:function:: bool GetRepresentation(Lib3MF_uint32 & nResourceID) + .. cpp:function:: bool GetRepresentation(Lib3MF_uint32 & nUniqueResourceID) Returns the representation-mesh for the beamlattice of this mesh. :returns: flag whether the beamlattice has a representation mesh. - :param nResourceID: filled with the resourceID of the clipping mesh-object. + :param nUniqueResourceID: filled with the UniqueResourceID of the clipping mesh-object. - .. cpp:function:: void SetRepresentation(const Lib3MF_uint32 nResourceID) + .. cpp:function:: void SetRepresentation(const Lib3MF_uint32 nUniqueResourceID) Sets the representation-mesh for the beamlattice of this mesh. - :param nResourceID: the resourceID of the representation mesh-object. This mesh-object has to be defined before setting the representation. + :param nUniqueResourceID: the UniqueResourceID of the representation mesh-object. This mesh-object has to be defined before setting the representation. + + + .. cpp:function:: void GetBallOptions(eBeamLatticeBallMode & eBallMode, Lib3MF_double & dBallRadius) + Returns the ball mode and the default ball radius for the beamlattice of this mesh.Returns the ball mode and the default ball radius for the beamlattice of this mesh. + + :param eBallMode: contains the ball mode of this mesh + :param dBallRadius: default ball radius of balls for the beamlattice + + + .. cpp:function:: void SetBallOptions(const eBeamLatticeBallMode eBallMode, const Lib3MF_double dBallRadius) + + Sets the ball mode and thedefault ball radius for the beamlattice. + + :param eBallMode: contains the ball mode of this mesh + :param dBallRadius: default ball radius of balls for the beamlattice .. cpp:function:: Lib3MF_uint32 GetBeamCount() @@ -100,6 +115,51 @@ CBeamLattice :param BeamInfoBuffer: contains information of all beams + .. cpp:function:: Lib3MF_uint32 GetBallCount() + + Returns the ball count of a mesh object. + + :returns: filled with the ball count. + + + .. cpp:function:: sBall GetBall(const Lib3MF_uint32 nIndex) + + Returns index and radius of a single ball of a mesh object. + + :param nIndex: Index of the ball (0 to ballcount - 1). + :returns: filled with the ball node index and radius. + + + .. cpp:function:: Lib3MF_uint32 AddBall(const sBall & BallInfo) + + Adds a single ball to a mesh object. + + :param BallInfo: contains the node index and radius. + :returns: filled with the new Index of the ball. + + + .. cpp:function:: void SetBall(const Lib3MF_uint32 nIndex, const sBall & BallInfo) + + Sets the index and radius of a single ball of a mesh object. + + :param nIndex: Index of the ball (0 to ballcount - 1). + :param BallInfo: filled with the ball node index and radius. + + + .. cpp:function:: void SetBalls(const CInputVector & BallInfoBuffer) + + Sets all ball indices and radii of a mesh object. + + :param BallInfoBuffer: contains information of a number of balls + + + .. cpp:function:: void GetBalls(std::vector & BallInfoBuffer) + + obtains all ball indices and radii of a mesh object. + + :param BallInfoBuffer: contains information of all balls + + .. cpp:function:: Lib3MF_uint32 GetBeamSetCount() Returns the number of beamsets of a mesh object. diff --git a/Documentation/source/Cpp/lib3mf_BeamSet.rst b/Documentation/source/Cpp/lib3mf_BeamSet.rst index 79550bb75..120ae5403 100644 --- a/Documentation/source/Cpp/lib3mf_BeamSet.rst +++ b/Documentation/source/Cpp/lib3mf_BeamSet.rst @@ -59,6 +59,27 @@ CBeamSet :param ReferencesBuffer: retrieves the indices of all beams in this beamset + .. cpp:function:: Lib3MF_uint32 GetBallReferenceCount() + + Retrieves the ball reference count of a beamset + + :returns: returns the ball reference count + + + .. cpp:function:: void SetBallReferences(const CInputVector & BallReferencesBuffer) + + Sets the ball references of a beamset + + :param BallReferencesBuffer: the new indices of all balls in this beamset + + + .. cpp:function:: void GetBallReferences(std::vector & BallReferencesBuffer) + + Retrieves the ball references of a beamset + + :param BallReferencesBuffer: retrieves the indices of all balls in this beamset + + .. cpp:type:: std::shared_ptr Lib3MF::PBeamSet Shared pointer to CBeamSet to easily allow reference counting. diff --git a/Documentation/source/Cpp/lib3mf_BuildItem.rst b/Documentation/source/Cpp/lib3mf_BuildItem.rst index 68b353160..245444746 100644 --- a/Documentation/source/Cpp/lib3mf_BuildItem.rst +++ b/Documentation/source/Cpp/lib3mf_BuildItem.rst @@ -34,9 +34,9 @@ CBuildItem .. cpp:function:: Lib3MF_uint32 GetObjectResourceID() - Retrieves the object resource id associated to a build item + Retrieves the object UniqueResourceID associated to a build item - :returns: eturns the ID of the object + :returns: returns the UniqueResourceID of the object .. cpp:function:: bool HasObjectTransform() diff --git a/Documentation/source/Cpp/lib3mf_Component.rst b/Documentation/source/Cpp/lib3mf_Component.rst index fdeca227d..3c42f5017 100644 --- a/Documentation/source/Cpp/lib3mf_Component.rst +++ b/Documentation/source/Cpp/lib3mf_Component.rst @@ -12,16 +12,16 @@ CComponent .. cpp:function:: PObject GetObjectResource() - Returns the Resource Instance of the component.. + Returns the Resource Instance of the component. :returns: filled with the Resource Instance. .. cpp:function:: Lib3MF_uint32 GetObjectResourceID() - Returns the Resource ID of the component. + Returns the UniqueResourceID of the component. - :returns: returns the Resource ID. + :returns: returns the UniqueResourceID. .. cpp:function:: std::string GetUUID(bool & bHasUUID) diff --git a/Documentation/source/Cpp/lib3mf_Consumer.rst b/Documentation/source/Cpp/lib3mf_Consumer.rst new file mode 100644 index 000000000..26fe0aab5 --- /dev/null +++ b/Documentation/source/Cpp/lib3mf_Consumer.rst @@ -0,0 +1,37 @@ + +CConsumer +==================================================================================================== + + +.. cpp:class:: Lib3MF::CConsumer : public CBase + + + + + + + .. cpp:function:: std::string GetConsumerID() + + Gets the consumerid + + :returns: A unique identifier for the consumers + + + .. cpp:function:: std::string GetKeyID() + + Getts the keyid + + :returns: The identifier for the key of this consumer + + + .. cpp:function:: std::string GetKeyValue() + + Gets the keyvalue associated with this consumer + + :returns: The public key, when available, of this consumer + + +.. cpp:type:: std::shared_ptr Lib3MF::PConsumer + + Shared pointer to CConsumer to easily allow reference counting. + diff --git a/Documentation/source/Cpp/lib3mf_ContentEncryptionParams.rst b/Documentation/source/Cpp/lib3mf_ContentEncryptionParams.rst new file mode 100644 index 000000000..902b9a225 --- /dev/null +++ b/Documentation/source/Cpp/lib3mf_ContentEncryptionParams.rst @@ -0,0 +1,72 @@ + +CContentEncryptionParams +==================================================================================================== + + +.. cpp:class:: Lib3MF::CContentEncryptionParams : public CBase + + + + + + + .. cpp:function:: eEncryptionAlgorithm GetEncryptionAlgorithm() + + Returns the encryption method to be used in this encryption process + + :returns: + + + .. cpp:function:: void GetKey(std::vector & ByteDataBuffer) + + Gets the key for the resource associated + + :param ByteDataBuffer: Pointer to a buffer where to place the key. + + + .. cpp:function:: void GetInitializationVector(std::vector & ByteDataBuffer) + + Gets the IV data + + :param ByteDataBuffer: Pointer to a buffer where to place the data. + + + .. cpp:function:: void GetAuthenticationTag(std::vector & ByteDataBuffer) + + A handler descriptor that uniquely identifies the context of the resource. Each resource will be assigned a different value + + :param ByteDataBuffer: Pointer to a buffer where to place the data. + + + .. cpp:function:: void SetAuthenticationTag(const CInputVector & ByteDataBuffer) + + Sets the authentication tag + + :param ByteDataBuffer: The authentication tag size + + + .. cpp:function:: void GetAdditionalAuthenticationData(std::vector & ByteDataBuffer) + + A handler descriptor that uniquely identifies the context of the resource. Each resource will be assigned a different value + + :param ByteDataBuffer: Buffer where the data will be placed + + + .. cpp:function:: Lib3MF_uint64 GetDescriptor() + + A handler descriptor that uniquely identifies the context of the resource. Each resource will be assigned a different value + + :returns: + + + .. cpp:function:: std::string GetKeyUUID() + + Gets the resourcedatagroup keyuuid + + :returns: The resourcedatagroup keyuuid that may be use to reference an external key + + +.. cpp:type:: std::shared_ptr Lib3MF::PContentEncryptionParams + + Shared pointer to CContentEncryptionParams to easily allow reference counting. + diff --git a/Documentation/source/Cpp/lib3mf_KeyStore.rst b/Documentation/source/Cpp/lib3mf_KeyStore.rst new file mode 100644 index 000000000..a60c35630 --- /dev/null +++ b/Documentation/source/Cpp/lib3mf_KeyStore.rst @@ -0,0 +1,150 @@ + +CKeyStore +==================================================================================================== + + +.. cpp:class:: Lib3MF::CKeyStore : public CBase + + + + + + + .. cpp:function:: PConsumer AddConsumer(const std::string & sConsumerID, const std::string & sKeyID, const std::string & sKeyValue) + + Adds a consumer to the keystore + + :param sConsumerID: A unique identifier for the consumer + :param sKeyID: The id of the key of the consumer + :param sKeyValue: The public key for this consumer in PEM format + :returns: The consumer instance + + + .. cpp:function:: Lib3MF_uint64 GetConsumerCount() + + Gets the number of consumers in the keystore + + :returns: The consumer count + + + .. cpp:function:: PConsumer GetConsumer(const Lib3MF_uint64 nConsumerIndex) + + Get a consumer from the keystore + + :param nConsumerIndex: The index of the consumer + :returns: The consumer instance + + + .. cpp:function:: void RemoveConsumer(CConsumer * pConsumer) + + Removes a consumer from the keystore + + :param pConsumer: The consumer instance to remove + + + .. cpp:function:: PConsumer FindConsumer(const std::string & sConsumerID) + + Finds a consumer by ID + + :param sConsumerID: The ID of the consumer + :returns: The consumer instance + + + .. cpp:function:: Lib3MF_uint64 GetResourceDataGroupCount() + + Gets the number of resource data group in the keysore + + :returns: The number of resource data available + + + .. cpp:function:: PResourceDataGroup AddResourceDataGroup() + + Adds a resource data group into the keystore. + + :returns: The resource data group instance + + + .. cpp:function:: PResourceDataGroup GetResourceDataGroup(const Lib3MF_uint64 nResourceDataIndex) + + Gets a resource data group + + :param nResourceDataIndex: The index of the resource data + :returns: The resource data group instance + + + .. cpp:function:: void RemoveResourceDataGroup(CResourceDataGroup * pResourceDataGroup) + + Removes a resource data group + + :param pResourceDataGroup: The resource data group instance + + + .. cpp:function:: PResourceDataGroup FindResourceDataGroup(CPackagePart * pPartPath) + + Finds a resource data group that contains a particular resourcedata + + :param pPartPath: The target path for the resourcedata hold by the resource data group + :returns: The data resource instance + + + .. cpp:function:: PResourceData AddResourceData(CResourceDataGroup * pResourceDataGroup, CPackagePart * pPartPath, const eEncryptionAlgorithm eAlgorithm, const eCompression eCompression, const CInputVector & AdditionalAuthenticationDataBuffer) + + Add resourcedata to resourcedatagroup element + + :param pResourceDataGroup: The resource data group where to add this resource data + :param pPartPath: The path of the part to be encrypted + :param eAlgorithm: The encryption algorithm to be used to encrypt this resource + :param eCompression: Whether compression should be used prior to encryption + :param AdditionalAuthenticationDataBuffer: Additional data to be encrypted along the contents for better security + :returns: The data resource instance + + + .. cpp:function:: void RemoveResourceData(CResourceData * pResourceData) + + Removes a resource data + + :param pResourceData: The resource data to be removed + + + .. cpp:function:: PResourceData FindResourceData(CPackagePart * pResourcePath) + + Finds a resource data on this resource group + + :param pResourcePath: The target path for the resourcedata + :returns: The resource data instance + + + .. cpp:function:: Lib3MF_uint64 GetResourceDataCount() + + Gets the number of resource data in the keysore + + :returns: The number of resource data available + + + .. cpp:function:: PResourceData GetResourceData(const Lib3MF_uint64 nResourceDataIndex) + + Gets a resource data + + :param nResourceDataIndex: The index of the resource data + :returns: The data resource instance + + + .. cpp:function:: std::string GetUUID(bool & bHasUUID) + + Gets the keystore UUID + + :param bHasUUID: flag whether the keystore has a UUID + :returns: returns the keystore uuid. + + + .. cpp:function:: void SetUUID(const std::string & sUUID) + + Sets the keystore UUID + + :param sUUID: The new keystore uuid. + + +.. cpp:type:: std::shared_ptr Lib3MF::PKeyStore + + Shared pointer to CKeyStore to easily allow reference counting. + diff --git a/Documentation/source/Cpp/lib3mf_MeshObject.rst b/Documentation/source/Cpp/lib3mf_MeshObject.rst index d3ac807b3..00cea2dd9 100644 --- a/Documentation/source/Cpp/lib3mf_MeshObject.rst +++ b/Documentation/source/Cpp/lib3mf_MeshObject.rst @@ -86,19 +86,19 @@ CMeshObject :param IndicesBuffer: contains the triangle indices. - .. cpp:function:: void SetObjectLevelProperty(const Lib3MF_uint32 nResourceID, const Lib3MF_uint32 nPropertyID) + .. cpp:function:: void SetObjectLevelProperty(const Lib3MF_uint32 nUniqueResourceID, const Lib3MF_uint32 nPropertyID) Sets the property at the object-level of the mesh object. - :param nResourceID: the object-level Property Resource ID. + :param nUniqueResourceID: the object-level Property UniqueResourceID. :param nPropertyID: the object-level PropertyID. - .. cpp:function:: bool GetObjectLevelProperty(Lib3MF_uint32 & nResourceID, Lib3MF_uint32 & nPropertyID) + .. cpp:function:: bool GetObjectLevelProperty(Lib3MF_uint32 & nUniqueResourceID, Lib3MF_uint32 & nPropertyID) Gets the property at the object-level of the mesh object. - :param nResourceID: the object-level Property Resource ID. + :param nUniqueResourceID: the object-level Property UniqueResourceID. :param nPropertyID: the object-level PropertyID. :returns: Has an object-level property been specified? diff --git a/Documentation/source/Cpp/lib3mf_Model.rst b/Documentation/source/Cpp/lib3mf_Model.rst index 63324bf34..40726b357 100644 --- a/Documentation/source/Cpp/lib3mf_Model.rst +++ b/Documentation/source/Cpp/lib3mf_Model.rst @@ -10,6 +10,21 @@ CModel + .. cpp:function:: PPackagePart RootModelPart() + + Returns the PackagePart within the OPC package that holds the root model. + + :returns: the PackagePart within the OPC package that holds the model-file + + + .. cpp:function:: PPackagePart FindOrCreatePackagePart(const std::string & sAbsolutePath) + + Returns a new PackagePart for use within the OPC package. + + :param sAbsolutePath: the absolute Path (physical location) within the OPC package + :returns: the new PackagePart within the OPC package + + .. cpp:function:: void SetUnit(const eModelUnit eUnit) sets the units of a model. @@ -54,83 +69,83 @@ CModel :returns: string identifier for the file type - .. cpp:function:: PTexture2D GetTexture2DByID(const Lib3MF_uint32 nResourceID) + .. cpp:function:: PTexture2D GetTexture2DByID(const Lib3MF_uint32 nUniqueResourceID) - finds a model texture by its id + finds a model texture by its UniqueResourceID - :param nResourceID: Resource ID + :param nUniqueResourceID: UniqueResourceID :returns: returns the texture2d instance - .. cpp:function:: ePropertyType GetPropertyTypeByID(const Lib3MF_uint32 nResourceID) + .. cpp:function:: ePropertyType GetPropertyTypeByID(const Lib3MF_uint32 nUniqueResourceID) returns a Property's type - :param nResourceID: Resource ID of the Property to Query + :param nUniqueResourceID: Resource ID of the Property to Query :returns: returns a Property's type - .. cpp:function:: PBaseMaterialGroup GetBaseMaterialGroupByID(const Lib3MF_uint32 nResourceID) + .. cpp:function:: PBaseMaterialGroup GetBaseMaterialGroupByID(const Lib3MF_uint32 nUniqueResourceID) - finds a model base material group by its id + finds a model base material group by its UniqueResourceID - :param nResourceID: Resource ID + :param nUniqueResourceID: UniqueResourceID :returns: returns the BaseMaterialGroup instance - .. cpp:function:: PTexture2DGroup GetTexture2DGroupByID(const Lib3MF_uint32 nResourceID) + .. cpp:function:: PTexture2DGroup GetTexture2DGroupByID(const Lib3MF_uint32 nUniqueResourceID) - finds a model texture2d group by its id + finds a model texture2d group by its UniqueResourceID - :param nResourceID: Resource ID + :param nUniqueResourceID: UniqueResourceID :returns: returns the Texture2DGroup instance - .. cpp:function:: PCompositeMaterials GetCompositeMaterialsByID(const Lib3MF_uint32 nResourceID) + .. cpp:function:: PCompositeMaterials GetCompositeMaterialsByID(const Lib3MF_uint32 nUniqueResourceID) - finds a model CompositeMaterials by its id + finds a model CompositeMaterials by its UniqueResourceID - :param nResourceID: Resource ID + :param nUniqueResourceID: UniqueResourceID :returns: returns the CompositeMaterials instance - .. cpp:function:: PMultiPropertyGroup GetMultiPropertyGroupByID(const Lib3MF_uint32 nResourceID) + .. cpp:function:: PMultiPropertyGroup GetMultiPropertyGroupByID(const Lib3MF_uint32 nUniqueResourceID) - finds a model MultiPropertyGroup by its id + finds a model MultiPropertyGroup by its UniqueResourceID - :param nResourceID: Resource ID + :param nUniqueResourceID: UniqueResourceID :returns: returns the MultiPropertyGroup instance - .. cpp:function:: PMeshObject GetMeshObjectByID(const Lib3MF_uint32 nResourceID) + .. cpp:function:: PMeshObject GetMeshObjectByID(const Lib3MF_uint32 nUniqueResourceID) - finds a mesh object by its id + finds a mesh object by its UniqueResourceID - :param nResourceID: Resource ID + :param nUniqueResourceID: UniqueResourceID :returns: returns the mesh object instance - .. cpp:function:: PComponentsObject GetComponentsObjectByID(const Lib3MF_uint32 nResourceID) + .. cpp:function:: PComponentsObject GetComponentsObjectByID(const Lib3MF_uint32 nUniqueResourceID) - finds a components object by its id + finds a components object by its UniqueResourceID - :param nResourceID: Resource ID + :param nUniqueResourceID: UniqueResourceID :returns: returns the components object instance - .. cpp:function:: PColorGroup GetColorGroupByID(const Lib3MF_uint32 nResourceID) + .. cpp:function:: PColorGroup GetColorGroupByID(const Lib3MF_uint32 nUniqueResourceID) - finds a model color group by its id + finds a model color group by its UniqueResourceID - :param nResourceID: Resource ID + :param nUniqueResourceID: UniqueResourceID :returns: returns the ColorGroup instance - .. cpp:function:: PSliceStack GetSliceStackByID(const Lib3MF_uint32 nResourceID) + .. cpp:function:: PSliceStack GetSliceStackByID(const Lib3MF_uint32 nUniqueResourceID) - finds a model slicestack by its id + finds a model slicestack by its UniqueResourceID - :param nResourceID: Resource ID + :param nUniqueResourceID: UniqueResourceID :returns: returns the slicestack instance @@ -339,7 +354,7 @@ CModel .. cpp:function:: PAttachment AddAttachment(const std::string & sURI, const std::string & sRelationShipType) - adds an attachment stream to the model. The OPC part will be related to the model stream with a certain relationship type.. + adds an attachment stream to the model. The OPC part will be related to the model stream with a certain relationship type. :param sURI: Path of the attachment :param sRelationShipType: Relationship type of the attachment @@ -405,7 +420,7 @@ CModel .. cpp:function:: void AddCustomContentType(const std::string & sExtension, const std::string & sContentType) - adds a new Content Type to the model. + Adds a new Content Type to the model. :param sExtension: File Extension :param sContentType: Content Type Identifier @@ -413,11 +428,26 @@ CModel .. cpp:function:: void RemoveCustomContentType(const std::string & sExtension) - removes a custom Content Type from the model (UTF8 version). + Removes a custom Content Type from the model (UTF8 version). :param sExtension: File Extension + .. cpp:function:: void SetRandomNumberCallback(const RandomNumberCallback pTheCallback, const Lib3MF_pvoid pUserData) + + Sets the random number generator callback for use in the library + + :param pTheCallback: The callback used to generate random numbers + :param pUserData: Userdata to be passed to the callback function + + + .. cpp:function:: PKeyStore GetKeyStore() + + Gets the keystore associated with this model + + :returns: The package keystore + + .. cpp:type:: std::shared_ptr Lib3MF::PModel Shared pointer to CModel to easily allow reference counting. diff --git a/Documentation/source/Cpp/lib3mf_PackagePart.rst b/Documentation/source/Cpp/lib3mf_PackagePart.rst new file mode 100644 index 000000000..197a54775 --- /dev/null +++ b/Documentation/source/Cpp/lib3mf_PackagePart.rst @@ -0,0 +1,30 @@ + +CPackagePart +==================================================================================================== + + +.. cpp:class:: Lib3MF::CPackagePart : public CBase + + + + + + + .. cpp:function:: std::string GetPath() + + Returns the absolute path of this PackagePart. + + :returns: Returns the absolute path of this PackagePart + + + .. cpp:function:: void SetPath(const std::string & sPath) + + Sets the absolute path of this PackagePart. + + :param sPath: Sets the absolute path of this PackagePart. + + +.. cpp:type:: std::shared_ptr Lib3MF::PPackagePart + + Shared pointer to CPackagePart to easily allow reference counting. + diff --git a/Documentation/source/Cpp/lib3mf_Reader.rst b/Documentation/source/Cpp/lib3mf_Reader.rst index 3f34ecfeb..45c024403 100644 --- a/Documentation/source/Cpp/lib3mf_Reader.rst +++ b/Documentation/source/Cpp/lib3mf_Reader.rst @@ -86,6 +86,23 @@ CReader :returns: filled with the count of the occurred warnings. + .. cpp:function:: void AddKeyWrappingCallback(const std::string & sConsumerID, const KeyWrappingCallback pTheCallback, const Lib3MF_pvoid pUserData) + + Registers a callback to deal with key wrapping mechanism from keystore + + :param sConsumerID: The ConsumerID to register for + :param pTheCallback: The callback used to decrypt data key + :param pUserData: Userdata that is passed to the callback function + + + .. cpp:function:: void SetContentEncryptionCallback(const ContentEncryptionCallback pTheCallback, const Lib3MF_pvoid pUserData) + + Registers a callback to deal with encryption of content + + :param pTheCallback: The callback used to encrypt content + :param pUserData: Userdata that is passed to the callback function + + .. cpp:type:: std::shared_ptr Lib3MF::PReader Shared pointer to CReader to easily allow reference counting. diff --git a/Documentation/source/Cpp/lib3mf_Resource.rst b/Documentation/source/Cpp/lib3mf_Resource.rst index d3b450efe..28156d560 100644 --- a/Documentation/source/Cpp/lib3mf_Resource.rst +++ b/Documentation/source/Cpp/lib3mf_Resource.rst @@ -12,9 +12,37 @@ CResource .. cpp:function:: Lib3MF_uint32 GetResourceID() - Retrieves the resource id of the resource instance. + Retrieves the unique id of this resource within a package. This function will be removed in a later release in favor of GetUniqueResourceID - :returns: Retrieves the ID of a Model Resource Instance. + :returns: Retrieves the unique id of this resource within a package. + + + .. cpp:function:: Lib3MF_uint32 GetUniqueResourceID() + + Retrieves the unique id of this resource within a package. + + :returns: Retrieves the unique id of this resource within a package. + + + .. cpp:function:: PPackagePart PackagePart() + + Returns the PackagePart within which this resource resides + + :returns: the PackagePart within which this resource resides. + + + .. cpp:function:: void SetPackagePart(CPackagePart * pPackagePart) + + Sets the new PackagePart within which this resource resides + + :param pPackagePart: the new PackagePart within which this resource resides. + + + .. cpp:function:: Lib3MF_uint32 GetModelResourceID() + + Retrieves the id of this resource within a model. + + :returns: Retrieves the id of this resource within a model. .. cpp:type:: std::shared_ptr Lib3MF::PResource diff --git a/Documentation/source/Cpp/lib3mf_ResourceData.rst b/Documentation/source/Cpp/lib3mf_ResourceData.rst new file mode 100644 index 000000000..8c1532ba2 --- /dev/null +++ b/Documentation/source/Cpp/lib3mf_ResourceData.rst @@ -0,0 +1,44 @@ + +CResourceData +==================================================================================================== + + +.. cpp:class:: Lib3MF::CResourceData : public CBase + + + + + + + .. cpp:function:: PPackagePart GetPath() + + Gets the encrypted part path + + :returns: The part path + + + .. cpp:function:: eEncryptionAlgorithm GetEncryptionAlgorithm() + + Gets the encryption algorithm used to encrypt this ResourceData + + :returns: The encryption algorithm + + + .. cpp:function:: eCompression GetCompression() + + Tells whether this ResourceData is compressed or not + + :returns: The compression method + + + .. cpp:function:: void GetAdditionalAuthenticationData(std::vector & ByteDataBuffer) + + Tells whether this ResourceData is compressed or not + + :param ByteDataBuffer: The compression method + + +.. cpp:type:: std::shared_ptr Lib3MF::PResourceData + + Shared pointer to CResourceData to easily allow reference counting. + diff --git a/Documentation/source/Cpp/lib3mf_ResourceDataGroup.rst b/Documentation/source/Cpp/lib3mf_ResourceDataGroup.rst new file mode 100644 index 000000000..eef15ab28 --- /dev/null +++ b/Documentation/source/Cpp/lib3mf_ResourceDataGroup.rst @@ -0,0 +1,49 @@ + +CResourceDataGroup +==================================================================================================== + + +.. cpp:class:: Lib3MF::CResourceDataGroup : public CBase + + + + + + + .. cpp:function:: std::string GetKeyUUID() + + Sets the resourcedatagroup keyuuid + + :returns: The new resourcedatagroup keyuuid. + + + .. cpp:function:: PAccessRight AddAccessRight(CConsumer * pConsumer, const eWrappingAlgorithm eWrappingAlgorithm, const eMgfAlgorithm eMgfAlgorithm, const eDigestMethod eDigestMethod) + + Add accessright to resourcedatagroup element + + :param pConsumer: The Consumer reference + :param eWrappingAlgorithm: The key wrapping algorithm to be used + :param eMgfAlgorithm: The mask generation function to be used + :param eDigestMethod: The digest mechanism to be used + :returns: The acess right instance + + + .. cpp:function:: PAccessRight FindAccessRightByConsumer(CConsumer * pConsumer) + + Finds the AccessRight associated with a Consumer + + :param pConsumer: The Consumer instance + :returns: The AcessRight instance + + + .. cpp:function:: void RemoveAccessRight(CConsumer * pConsumer) + + Removes access from a Consumer on this resource data group + + :param pConsumer: The Consumer instance + + +.. cpp:type:: std::shared_ptr Lib3MF::PResourceDataGroup + + Shared pointer to CResourceDataGroup to easily allow reference counting. + diff --git a/Documentation/source/Cpp/lib3mf_Writer.rst b/Documentation/source/Cpp/lib3mf_Writer.rst index 9bc5de7da..86d763b3b 100644 --- a/Documentation/source/Cpp/lib3mf_Writer.rst +++ b/Documentation/source/Cpp/lib3mf_Writer.rst @@ -62,6 +62,53 @@ CWriter :param nDecimalPrecision: The number of digits to be written in each vertex coordinate-value after the decimal point. + .. cpp:function:: void SetStrictModeActive(const bool bStrictModeActive) + + Activates (deactivates) the strict mode of the reader. + + :param bStrictModeActive: flag whether strict mode is active or not. + + + .. cpp:function:: bool GetStrictModeActive() + + Queries whether the strict mode of the reader is active or not + + :returns: returns flag whether strict mode is active or not. + + + .. cpp:function:: std::string GetWarning(const Lib3MF_uint32 nIndex, Lib3MF_uint32 & nErrorCode) + + Returns Warning and Error Information of the read process + + :param nIndex: Index of the Warning. Valid values are 0 to WarningCount - 1 + :param nErrorCode: filled with the error code of the warning + :returns: the message of the warning + + + .. cpp:function:: Lib3MF_uint32 GetWarningCount() + + Returns Warning and Error Count of the read process + + :returns: filled with the count of the occurred warnings. + + + .. cpp:function:: void AddKeyWrappingCallback(const std::string & sConsumerID, const KeyWrappingCallback pTheCallback, const Lib3MF_pvoid pUserData) + + Registers a callback to deal with data key encryption/decryption from keystore + + :param sConsumerID: The ConsumerID to register for + :param pTheCallback: The callback to be callede for wrapping and encryption key + :param pUserData: Userdata that is passed to the callback function + + + .. cpp:function:: void SetContentEncryptionCallback(const ContentEncryptionCallback pTheCallback, const Lib3MF_pvoid pUserData) + + Registers a callback to deal with encryption of content + + :param pTheCallback: The callback used to encrypt content + :param pUserData: Userdata that is passed to the callback function + + .. cpp:type:: std::shared_ptr Lib3MF::PWriter Shared pointer to CWriter to easily allow reference counting. diff --git a/Include/API/lib3mf_accessright.hpp b/Include/API/lib3mf_accessright.hpp new file mode 100644 index 000000000..a1e8fe6b1 --- /dev/null +++ b/Include/API/lib3mf_accessright.hpp @@ -0,0 +1,74 @@ +/*++ + +Copyright (C) 2019 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: This is the class declaration of CAccessRight + +*/ + + +#ifndef __LIB3MF_DECRYPTRIGHT +#define __LIB3MF_DECRYPTRIGHT + +#include "lib3mf_interfaces.hpp" +#include "lib3mf_base.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +namespace Lib3MF { + namespace Impl { + + + /************************************************************************************************************************* + Class declaration of CAccessRight + **************************************************************************************************************************/ + + class CAccessRight : public virtual IAccessRight, public virtual CBase { + private: + NMR::PKeyStoreAccessRight m_pAccessRight; + public: + CAccessRight(NMR::PKeyStoreAccessRight ar); + + // Inherited via IAccessRight + virtual IConsumer * GetConsumer() override; + + virtual Lib3MF::eWrappingAlgorithm GetWrappingAlgorithm(); + + virtual Lib3MF::eMgfAlgorithm GetMgfAlgorithm(); + + virtual Lib3MF::eDigestMethod GetDigestMethod(); + + // Other access methods + NMR::PKeyStoreAccessRight accessRight() const; + + + }; + } +} +#endif diff --git a/Include/API/lib3mf_attachment.hpp b/Include/API/lib3mf_attachment.hpp index 03fd67283..9cb759b8f 100644 --- a/Include/API/lib3mf_attachment.hpp +++ b/Include/API/lib3mf_attachment.hpp @@ -79,6 +79,8 @@ class CAttachment : public virtual IAttachment, public virtual CBase { void SetPath (const std::string & sPath); + IPackagePart * PackagePart(); + std::string GetRelationShipType (); void SetRelationShipType (const std::string & sPath); diff --git a/Include/API/lib3mf_beamlattice.hpp b/Include/API/lib3mf_beamlattice.hpp index ff69be3f2..3dd2742f2 100644 --- a/Include/API/lib3mf_beamlattice.hpp +++ b/Include/API/lib3mf_beamlattice.hpp @@ -84,13 +84,17 @@ class CBeamLattice : public virtual IBeamLattice, public virtual CBase { void SetMinLength (const Lib3MF_double dMinLength); - void GetClipping (eBeamLatticeClipMode & eClipMode, Lib3MF_uint32 & nResourceID); + void GetClipping (eBeamLatticeClipMode & eClipMode, Lib3MF_uint32 & nUniqueResourceID); - void SetClipping (const eBeamLatticeClipMode eClipMode, const Lib3MF_uint32 nResourceID); + void SetClipping (const eBeamLatticeClipMode eClipMode, const Lib3MF_uint32 nUniqueResourceID); - bool GetRepresentation(Lib3MF_uint32 & nResourceID); + bool GetRepresentation(Lib3MF_uint32 & nUniqueResourceID); - void SetRepresentation(const Lib3MF_uint32 nResourceID); + void SetRepresentation(const Lib3MF_uint32 nUniqueResourceID); + + void GetBallOptions (eBeamLatticeBallMode & eBallMode, Lib3MF_double & dBallRadius); + + void SetBallOptions (const eBeamLatticeBallMode eBallMode, const Lib3MF_double dBallRadius); Lib3MF_uint32 GetBeamCount (); @@ -102,7 +106,19 @@ class CBeamLattice : public virtual IBeamLattice, public virtual CBase { void SetBeams (const Lib3MF_uint64 nBeamInfoBufferSize, const sLib3MFBeam * pBeamInfoBuffer); - void GetBeams (Lib3MF_uint64 nBeamInfoBufferSize, Lib3MF_uint64* pBeamInfoNeededCount, sLib3MFBeam * pBeamInfoBuffer); + void GetBeams (Lib3MF_uint64 nBeamInfoBufferSize, Lib3MF_uint64 * pBeamInfoNeededCount, sLib3MFBeam * pBeamInfoBuffer); + + Lib3MF_uint32 GetBallCount (); + + sLib3MFBall GetBall (const Lib3MF_uint32 nIndex); + + Lib3MF_uint32 AddBall (const sLib3MFBall BallInfo); + + void SetBall (const Lib3MF_uint32 nIndex, const sLib3MFBall BallInfo); + + void SetBalls (const Lib3MF_uint64 nBallInfoBufferSize, const sLib3MFBall * pBallInfoBuffer); + + void GetBalls (Lib3MF_uint64 nBeamInfoBufferSize, Lib3MF_uint64 * pBallInfoNeededCount, sLib3MFBall * pBallInfoBuffer); Lib3MF_uint32 GetBeamSetCount (); diff --git a/Include/API/lib3mf_beamset.hpp b/Include/API/lib3mf_beamset.hpp index cb6dba5ff..21cf4c774 100644 --- a/Include/API/lib3mf_beamset.hpp +++ b/Include/API/lib3mf_beamset.hpp @@ -91,7 +91,13 @@ class CBeamSet : public virtual IBeamSet, public virtual CBase { virtual void SetReferences(const Lib3MF_uint64 nReferencesBufferSize, const Lib3MF_uint32 * pReferencesBuffer); - virtual void GetReferences(Lib3MF_uint64 nReferencesBufferSize, Lib3MF_uint64* pReferencesNeededCount, Lib3MF_uint32 * pReferencesBuffer); + virtual void GetReferences(Lib3MF_uint64 nReferencesBufferSize, Lib3MF_uint64 * pReferencesNeededCount, Lib3MF_uint32 * pReferencesBuffer); + + virtual Lib3MF_uint32 GetBallReferenceCount(); + + virtual void SetBallReferences(const Lib3MF_uint64 nBallReferencesBufferSize, const Lib3MF_uint32 * pBallReferencesBuffer); + + virtual void GetBallReferences(Lib3MF_uint64 nBallReferencesBufferSize, Lib3MF_uint64 * pBallReferencesNeededCount, Lib3MF_uint32 * pBallReferencesBuffer); }; diff --git a/Include/API/lib3mf_consumer.hpp b/Include/API/lib3mf_consumer.hpp new file mode 100644 index 000000000..b6afcc037 --- /dev/null +++ b/Include/API/lib3mf_consumer.hpp @@ -0,0 +1,66 @@ +/*++ + +Copyright (C) 2019 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: This is the class declaration of CConsumer + +*/ + + +#ifndef __LIB3MF_CONSUMER +#define __LIB3MF_CONSUMER + +#include "lib3mf_interfaces.hpp" +#include "lib3mf_base.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +#include "Model/Classes/NMR_KeyStoreConsumer.h" +// Include custom headers here. +namespace Lib3MF { + namespace Impl { + + /************************************************************************************************************************* + Class declaration of CConsumer + **************************************************************************************************************************/ + + class CConsumer : public virtual IConsumer, public virtual CBase { + private: + NMR::PKeyStoreConsumer m_Consumer; + public: + inline NMR::PKeyStoreConsumer consumer() const { + return m_Consumer; + } + CConsumer(NMR::PKeyStoreConsumer const & consumer); + // Inherited via IConsumer + std::string GetConsumerID() override; + std::string GetKeyID() override; + std::string GetKeyValue() override; + }; + } +} +#endif diff --git a/Include/API/lib3mf_contentencryptionparams.hpp b/Include/API/lib3mf_contentencryptionparams.hpp new file mode 100644 index 000000000..f64454512 --- /dev/null +++ b/Include/API/lib3mf_contentencryptionparams.hpp @@ -0,0 +1,74 @@ +/*++ + +Copyright (C) 2019 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: This is the class declaration of CContentEncryptionParams + +*/ + + +#ifndef __LIB3MF_CIPHERDATA +#define __LIB3MF_CIPHERDATA + +#include "lib3mf_interfaces.hpp" +#include "lib3mf_base.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + + +#include "Model/Classes/NMR_KeyStoreCEKParams.h" +// Include custom headers here. +namespace Lib3MF { + namespace Impl { + + /************************************************************************************************************************* + Class declaration of CContentEncryptionParams + **************************************************************************************************************************/ + + class CContentEncryptionParams : public virtual IContentEncryptionParams, public virtual CBase { + private: + NMR::PCKeyStoreContentEncryptionParams m_pParams; + public: + CContentEncryptionParams(NMR::PCKeyStoreContentEncryptionParams const & p); + // Inherited via IContentEncryptionParams + Lib3MF_uint64 GetDescriptor(); + Lib3MF::eEncryptionAlgorithm GetEncryptionAlgorithm(); + void GetKey(Lib3MF_uint64 nByteDataBufferSize, Lib3MF_uint64 *pByteDataNeededCount, Lib3MF_uint8 *pByteDataBuffer); + void GetInitializationVector(Lib3MF_uint64 nByteDataBufferSize, Lib3MF_uint64 *pByteDataNeededCount, Lib3MF_uint8 *pByteDataBuffer); + void GetAuthenticationTag(Lib3MF_uint64 nByteDataBufferSize, Lib3MF_uint64 *pByteDataNeededCount, Lib3MF_uint8 *pByteDataBuffer); + void SetAuthenticationTag(Lib3MF_uint64 const nByteDataBufferSize, const Lib3MF_uint8 *pByteDataBuffer); + void GetAdditionalAuthenticationData(Lib3MF_uint64 nByteDataBufferSize, Lib3MF_uint64 *pByteDataNeededCount, Lib3MF_uint8 *pByteDataBuffer); + void SetAdditionalAuthenticationData(Lib3MF_uint64 const nByteDataBufferSize, const Lib3MF_uint8 *pByteDataBuffer); + std::string GetKeyUUID(); + + inline NMR::PKeyStoreCEKParams params() const { + return m_pParams; + } + }; + } +} +#endif diff --git a/Include/API/lib3mf_keystore.hpp b/Include/API/lib3mf_keystore.hpp new file mode 100644 index 000000000..cfc4bb2b6 --- /dev/null +++ b/Include/API/lib3mf_keystore.hpp @@ -0,0 +1,119 @@ +/*++ + +Copyright (C) 2019 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: This is the class declaration of CKeyStore + +*/ + + +#ifndef __LIB3MF_KEYSTORE +#define __LIB3MF_KEYSTORE + +#include "lib3mf_interfaces.hpp" +#include "lib3mf_base.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_Model.h" +namespace Lib3MF { + namespace Impl { + + + /************************************************************************************************************************* + Class declaration of CKeyStore + **************************************************************************************************************************/ + + class CKeyStore : public virtual IKeyStore, public virtual CBase { + private: + + /** + * Put private members here. + */ + NMR::PKeyStore m_pKeyStore; + NMR::PModel m_pModel; + protected: + + /** + * Put protected members here. + */ + + public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + CKeyStore(NMR::PModel const & pModel); + + /** + * Public member functions to implement. + */ + + + // Inherited via IKeyStore + IConsumer * AddConsumer(const std::string & sConsumerID, const std::string & sKeyID, const std::string & sKeyValue) override; + + Lib3MF_uint64 GetConsumerCount() override; + + IConsumer * GetConsumer(const Lib3MF_uint64 nConsumerIndex) override; + + IConsumer * FindConsumer(const std::string & sConsumerID) override; + + virtual void RemoveConsumer(IConsumer * pConsumerInstance) override; + + std::string GetUUID(bool & bHasUUID) override; + + void SetUUID(const std::string & sUUID) override; + + virtual Lib3MF_uint64 GetResourceDataGroupCount() override; + + virtual IResourceDataGroup * GetResourceDataGroup(const Lib3MF_uint64 nResourceDataIndex) override; + + virtual IResourceDataGroup * AddResourceDataGroup() override; + + virtual void RemoveResourceDataGroup(IResourceDataGroup * pTheResourceDataGroup) override; + + virtual Lib3MF::Impl::IResourceDataGroup * FindResourceDataGroup(Lib3MF::Impl::IPackagePart *pPartPath); + + virtual IResourceData * AddResourceData(IResourceDataGroup* pResourceDataGroup, IPackagePart* pPartPath, const Lib3MF::eEncryptionAlgorithm eAlgorithm, const Lib3MF::eCompression eCompression, const Lib3MF_uint64 nAdditionalAuthenticationDataBufferSize, const Lib3MF_uint8 * pAdditionalAuthenticationDataBuffer); + + virtual void RemoveResourceData(Lib3MF::Impl::IResourceData *pResourceData); + + virtual Lib3MF_uint64 GetResourceDataCount(); + + virtual Lib3MF::Impl::IResourceData * GetResourceData(const Lib3MF_uint64 nResourceDataIndex); + + virtual IResourceData * FindResourceData(IPackagePart * pResourcePath) override; + + }; + + } // namespace Impl +} // namespace Lib3MF + +#endif // __LIB3MF_KEYSTORE \ No newline at end of file diff --git a/Include/API/lib3mf_meshobject.hpp b/Include/API/lib3mf_meshobject.hpp index 9b461d3f4..edc714c5c 100644 --- a/Include/API/lib3mf_meshobject.hpp +++ b/Include/API/lib3mf_meshobject.hpp @@ -113,9 +113,9 @@ class CMeshObject : public virtual IMeshObject, public virtual CObject { virtual IBeamLattice * BeamLattice(); - void SetObjectLevelProperty(const Lib3MF_uint32 nResourceID, const Lib3MF_uint32 nPropertyID); + void SetObjectLevelProperty(const Lib3MF_uint32 nUniqueResourceID, const Lib3MF_uint32 nPropertyID); - bool GetObjectLevelProperty(Lib3MF_uint32 & nResourceID, Lib3MF_uint32 & nPropertyID); + bool GetObjectLevelProperty(Lib3MF_uint32 & nUniqueResourceID, Lib3MF_uint32 & nPropertyID); void SetTriangleProperties(const Lib3MF_uint32 nIndex, const sLib3MFTriangleProperties Properties); diff --git a/Include/API/lib3mf_model.hpp b/Include/API/lib3mf_model.hpp index 2e915b86c..5e63c7412 100644 --- a/Include/API/lib3mf_model.hpp +++ b/Include/API/lib3mf_model.hpp @@ -43,7 +43,7 @@ Abstract: This is the class declaration of CModel // Include custom headers here. #include "Model/Classes/NMR_Model.h" - +#include "Model/Classes/NMR_KeyStore.h" namespace Lib3MF { namespace Impl { @@ -77,116 +77,123 @@ class CModel : public virtual IModel, public virtual CBase { * Public member functions to implement. */ - void SetUnit (const eLib3MFModelUnit eUnit); + IPackagePart * RootModelPart() override; + + IPackagePart * FindOrCreatePackagePart(const std::string & sAbsolutePath) override; + + void SetUnit (const eLib3MFModelUnit eUnit) override; + + eLib3MFModelUnit GetUnit() override; - eLib3MFModelUnit GetUnit (); + std::string GetLanguage() override; - std::string GetLanguage (); + void SetLanguage(const std::string & sLanguage) override; - void SetLanguage (const std::string & sLanguage); + IWriter * QueryWriter(const std::string & sWriterClass) override; - IWriter * QueryWriter (const std::string & sWriterClass); + IReader * QueryReader(const std::string & sReaderClass) override; - IReader * QueryReader (const std::string & sReaderClass); + ITexture2D * GetTexture2DByID(const Lib3MF_uint32 nUniqueResourceID) override; - ITexture2D * GetTexture2DByID (const Lib3MF_uint32 nResourceID); + eLib3MFPropertyType GetPropertyTypeByID(const Lib3MF_uint32 nUniqueResourceID) override; - eLib3MFPropertyType GetPropertyTypeByID(const Lib3MF_uint32 nResourceID); + IBaseMaterialGroup * GetBaseMaterialGroupByID(const Lib3MF_uint32 nUniqueResourceID) override; - IBaseMaterialGroup * GetBaseMaterialGroupByID (const Lib3MF_uint32 nResourceID); + IMeshObject * GetMeshObjectByID(const Lib3MF_uint32 nUniqueResourceID) override; - IMeshObject * GetMeshObjectByID (const Lib3MF_uint32 nResourceID); + IComponentsObject * GetComponentsObjectByID(const Lib3MF_uint32 nUniqueResourceID) override; - IComponentsObject * GetComponentsObjectByID (const Lib3MF_uint32 nResourceID); + IColorGroup * GetColorGroupByID(const Lib3MF_uint32 nUniqueResourceID) override; - IColorGroup * GetColorGroupByID(const Lib3MF_uint32 nResourceID); + ITexture2DGroup * GetTexture2DGroupByID(const Lib3MF_uint32 nUniqueResourceID) override; - ITexture2DGroup * GetTexture2DGroupByID(const Lib3MF_uint32 nResourceID); + ICompositeMaterials * GetCompositeMaterialsByID(const Lib3MF_uint32 nUniqueResourceID) override; - ICompositeMaterials * GetCompositeMaterialsByID(const Lib3MF_uint32 nResourceID); + IMultiPropertyGroup * GetMultiPropertyGroupByID(const Lib3MF_uint32 nUniqueResourceID) override; - IMultiPropertyGroup * GetMultiPropertyGroupByID(const Lib3MF_uint32 nResourceID); + ISliceStack * GetSliceStackByID(const Lib3MF_uint32 nUniqueResourceID) override; - ISliceStack * GetSliceStackByID(const Lib3MF_uint32 nResourceID); + std::string GetBuildUUID (bool & bHasUUID) override; - std::string GetBuildUUID (bool & bHasUUID); + void SetBuildUUID (const std::string & sUUID) override; - void SetBuildUUID (const std::string & sUUID); + IBuildItemIterator * GetBuildItems() override; - IBuildItemIterator * GetBuildItems (); + IResourceIterator * GetResources() override; - IResourceIterator * GetResources (); + IObjectIterator * GetObjects() override; - IObjectIterator * GetObjects (); + IMeshObjectIterator * GetMeshObjects() override; - IMeshObjectIterator * GetMeshObjects (); + IComponentsObjectIterator * GetComponentsObjects() override; - IComponentsObjectIterator * GetComponentsObjects (); + ITexture2DIterator * GetTexture2Ds() override; - ITexture2DIterator * GetTexture2Ds (); + IBaseMaterialGroupIterator * GetBaseMaterialGroups() override; - IBaseMaterialGroupIterator * GetBaseMaterialGroups (); + IColorGroupIterator * GetColorGroups() override; - IColorGroupIterator * GetColorGroups(); + ITexture2DGroupIterator * GetTexture2DGroups() override; - ITexture2DGroupIterator * GetTexture2DGroups(); + ICompositeMaterialsIterator * GetCompositeMaterials() override; - ICompositeMaterialsIterator * GetCompositeMaterials(); + IMultiPropertyGroupIterator * GetMultiPropertyGroups() override; - IMultiPropertyGroupIterator * GetMultiPropertyGroups(); + ISliceStackIterator * GetSliceStacks() override; - ISliceStackIterator * GetSliceStacks(); + IModel * MergeToModel() override; - IModel * MergeToModel (); + IMeshObject * AddMeshObject() override; - IMeshObject * AddMeshObject (); + IComponentsObject * AddComponentsObject() override; - IComponentsObject * AddComponentsObject (); + ISliceStack * AddSliceStack(const Lib3MF_double dZBottom) override; - ISliceStack * AddSliceStack(const Lib3MF_double dZBottom); + ITexture2D * AddTexture2DFromAttachment(IAttachment* pTextureAttachment) override; - ITexture2D * AddTexture2DFromAttachment (IAttachment* pTextureAttachment); + IBaseMaterialGroup * AddBaseMaterialGroup() override; - IBaseMaterialGroup * AddBaseMaterialGroup (); + IColorGroup * AddColorGroup() override; - IColorGroup * AddColorGroup(); + ITexture2DGroup * AddTexture2DGroup(ITexture2D* pTexture2DInstance) override; - ITexture2DGroup * AddTexture2DGroup(ITexture2D* pTexture2DInstance); + ICompositeMaterials * AddCompositeMaterials(IBaseMaterialGroup* pBaseMaterialGroupInstance) override; - ICompositeMaterials * AddCompositeMaterials(IBaseMaterialGroup* pBaseMaterialGroupInstance); + IMultiPropertyGroup * AddMultiPropertyGroup() override; - IMultiPropertyGroup * AddMultiPropertyGroup(); + IBuildItem * AddBuildItem(IObject* pObject, const sLib3MFTransform Transform) override; - IBuildItem * AddBuildItem (IObject* pObject, const sLib3MFTransform Transform); + void RemoveBuildItem(IBuildItem* pBuildItemInstance) override; - void RemoveBuildItem (IBuildItem* pBuildItemInstance); + IMetaDataGroup * GetMetaDataGroup() override; - IMetaDataGroup * GetMetaDataGroup (); + IAttachment * AddAttachment(const std::string & sURI, const std::string & sRelationShipType) override; - IAttachment * AddAttachment (const std::string & sURI, const std::string & sRelationShipType); + void RemoveAttachment(IAttachment* pAttachmentInstance) override; - void RemoveAttachment(IAttachment* pAttachmentInstance); + IAttachment * GetAttachment(const Lib3MF_uint32 nIndex) override; - IAttachment * GetAttachment (const Lib3MF_uint32 nIndex); + IAttachment * FindAttachment(const std::string & sURI) override; - IAttachment * FindAttachment (const std::string & sURI); + Lib3MF_uint32 GetAttachmentCount() override; - Lib3MF_uint32 GetAttachmentCount (); + bool HasPackageThumbnailAttachment() override; - bool HasPackageThumbnailAttachment (); + IAttachment * CreatePackageThumbnailAttachment() override; - IAttachment * CreatePackageThumbnailAttachment (); + IAttachment * GetPackageThumbnailAttachment() override; - IAttachment * GetPackageThumbnailAttachment (); + void RemovePackageThumbnailAttachment() override; - void RemovePackageThumbnailAttachment (); + void AddCustomContentType(const std::string & sExtension, const std::string & sContentType) override; - void AddCustomContentType (const std::string & sExtension, const std::string & sContentType); + void RemoveCustomContentType(const std::string & sExtension) override; - void RemoveCustomContentType (const std::string & sExtension); + Lib3MF::sBox GetOutbox() override; - Lib3MF::sBox GetOutbox(); + IKeyStore * GetKeyStore(); + void SetRandomNumberCallback(const Lib3MF::RandomNumberCallback pTheCallback, const Lib3MF_pvoid pUserData); }; } diff --git a/Include/API/lib3mf_packagepart.hpp b/Include/API/lib3mf_packagepart.hpp new file mode 100644 index 000000000..ccf9b2d9d --- /dev/null +++ b/Include/API/lib3mf_packagepart.hpp @@ -0,0 +1,92 @@ +/*++ + +Copyright (C) 2019 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: This is the class declaration of CPackagePart + +*/ + + +#ifndef __LIB3MF_MODELPART +#define __LIB3MF_MODELPART + +#include "lib3mf_interfaces.hpp" + +// Parent classes +#include "lib3mf_base.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +// Include custom headers here. +#include "Model/Classes/NMR_PackageResourceID.h" + +namespace Lib3MF { +namespace Impl { + + +/************************************************************************************************************************* + Class declaration of CPackagePart +**************************************************************************************************************************/ + +class CPackagePart : public virtual IPackagePart, public virtual CBase { +private: + + /** + * Put private members here. + */ + NMR::PPackageModelPath m_pPath; + +protected: + + /** + * Put protected members here. + */ + +public: + + /** + * Put additional public members here. They will not be visible in the external API. + */ + CPackagePart(NMR::PPackageModelPath pPath); + + /** + * Public member functions to implement. + */ + + std::string GetPath() override; + + void SetPath(const std::string & sPath) override; + +}; + +} // namespace Impl +} // namespace Lib3MF + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#endif // __LIB3MF_MODELPART diff --git a/Include/API/lib3mf_reader.hpp b/Include/API/lib3mf_reader.hpp index 14efd78a5..50a4c78a8 100644 --- a/Include/API/lib3mf_reader.hpp +++ b/Include/API/lib3mf_reader.hpp @@ -99,6 +99,10 @@ class CReader : public virtual IReader, public virtual CBase { Lib3MF_uint32 GetWarningCount (); + void AddKeyWrappingCallback(const std::string &sConsumerID, const Lib3MF::KeyWrappingCallback pTheCallback, const Lib3MF_pvoid pUserData); + + void SetContentEncryptionCallback(const Lib3MF::ContentEncryptionCallback pTheCallback, const Lib3MF_pvoid pUserData); + }; } diff --git a/Include/API/lib3mf_resource.hpp b/Include/API/lib3mf_resource.hpp index ec85bbb87..a24bf7f2e 100644 --- a/Include/API/lib3mf_resource.hpp +++ b/Include/API/lib3mf_resource.hpp @@ -75,10 +75,17 @@ class CResource : public virtual IResource, public virtual CBase { * Public member functions to implement. */ - Lib3MF_uint32 GetResourceID (); + Lib3MF_uint32 GetResourceID() override; + + Lib3MF_uint32 GetUniqueResourceID() override; virtual IObject * AsObject(); + IPackagePart * PackagePart() override; + + void SetPackagePart(IPackagePart* pPackagePath) override; + + Lib3MF_uint32 GetModelResourceID() override; }; } diff --git a/Include/API/lib3mf_resourcedata.hpp b/Include/API/lib3mf_resourcedata.hpp new file mode 100644 index 000000000..cae2902d5 --- /dev/null +++ b/Include/API/lib3mf_resourcedata.hpp @@ -0,0 +1,74 @@ +/*++ + +Copyright (C) 2019 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: This is the class declaration of CResourceData + +*/ + + +#ifndef __LIB3MF_RESOURCEDATA +#define __LIB3MF_RESOURCEDATA + +#include "lib3mf_interfaces.hpp" +#include "lib3mf_base.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +#include "Model/Classes/NMR_KeyStoreResourceData.h" +// Include custom headers here. +namespace Lib3MF { + namespace Impl { + + + /************************************************************************************************************************* + Class declaration of CResourceData + **************************************************************************************************************************/ + + class CResourceData : public virtual IResourceData, public virtual CBase { + private: + NMR::PKeyStoreResourceData m_pResourceData; + public: + CResourceData(NMR::PKeyStoreResourceData resourceData); + + + // Inherited via IResourceData + IPackagePart * GetPath() override; + + Lib3MF::eEncryptionAlgorithm GetEncryptionAlgorithm() override; + + Lib3MF::eCompression GetCompression() override; + + void GetAdditionalAuthenticationData(Lib3MF_uint64 nByteDataBufferSize, Lib3MF_uint64 * pByteDataNeededCount, Lib3MF_uint8 * pByteDataBuffer) override; + + inline NMR::PKeyStoreResourceData resourceData() const { + return m_pResourceData; + } + }; + } +} +#endif diff --git a/Include/API/lib3mf_resourcedatagroup.hpp b/Include/API/lib3mf_resourcedatagroup.hpp new file mode 100644 index 000000000..cc88bcc44 --- /dev/null +++ b/Include/API/lib3mf_resourcedatagroup.hpp @@ -0,0 +1,74 @@ +/*++ + +Copyright (C) 2019 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: This is the class declaration of CResourceDataGroup + +*/ + + +#ifndef __LIB3MF_RESOURCEDATAGROUP +#define __LIB3MF_RESOURCEDATAGROUP + + +#include "lib3mf_interfaces.hpp" +#include "lib3mf_base.hpp" +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4250) +#endif + +#include "Model/Classes/NMR_KeyStoreResourceDataGroup.h" +#include "Model/Classes/NMR_KeyStore.h" + +namespace Lib3MF { + namespace Impl { + + /************************************************************************************************************************* + Class declaration of CResourceData + **************************************************************************************************************************/ + + class CResourceDataGroup : public virtual IResourceDataGroup, public virtual CBase { + NMR::PKeyStoreResourceDataGroup m_pDataGroup; + public: + CResourceDataGroup(NMR::PKeyStoreResourceDataGroup const & dg); + + // Inherited via IResourceDataGroup + virtual IAccessRight * AddAccessRight(IConsumer * pConsumer, const Lib3MF::eWrappingAlgorithm eWrappingAlgorithm, const Lib3MF::eMgfAlgorithm eMgfAlgorithm, const Lib3MF::eDigestMethod eDigestMethod) override; + virtual IAccessRight * FindAccessRightByConsumer(IConsumer * pConsumerInstance) override; + virtual void RemoveAccessRight(IConsumer * pConsumerInstance) override; + virtual std::string GetKeyUUID() override; + + + inline NMR::PKeyStoreResourceDataGroup resourceDataGroup() const { + return m_pDataGroup; + } + + }; + } +} + + +#endif // !__LIB3MF_RESOURCEDATAGROUP diff --git a/Include/API/lib3mf_utils.hpp b/Include/API/lib3mf_utils.hpp index 4f60cc546..235df5d2e 100644 --- a/Include/API/lib3mf_utils.hpp +++ b/Include/API/lib3mf_utils.hpp @@ -36,6 +36,7 @@ Abstract: This file contains utilties used in the API of lib3mf // Include custom headers here. #include "Common/Math/NMR_Matrix.h" +#include "Common/NMR_SecureContentTypes.h" namespace Lib3MF { @@ -43,6 +44,17 @@ NMR::NMATRIX3 TransformToMatrix(const sLib3MFTransform Transform); sLib3MFTransform MatrixToTransform(const NMR::NMATRIX3 matrix); +eLib3MFEncryptionAlgorithm translateEncryptionAlgorithm(const NMR::eKeyStoreEncryptAlgorithm algorithm); + +NMR::eKeyStoreEncryptAlgorithm translateEncryptionAlgorithm(const eLib3MFEncryptionAlgorithm algorithm); + +eLib3MFWrappingAlgorithm translateWrappingAlgorithm(const NMR::eKeyStoreWrapAlgorithm algorithm); + +NMR::eKeyStoreWrapAlgorithm translateWrappingAlgorithm(const eLib3MFWrappingAlgorithm algorithm); + +eLib3MFCompression translateCompression(bool compression); +bool translateCompression(const eLib3MFCompression compression); + } #endif // __LIB3MF_UTILS diff --git a/Include/API/lib3mf_writer.hpp b/Include/API/lib3mf_writer.hpp index de96f0e02..6cf997f55 100644 --- a/Include/API/lib3mf_writer.hpp +++ b/Include/API/lib3mf_writer.hpp @@ -45,6 +45,11 @@ Abstract: This is the class declaration of CWriter #include "Model/Writer/NMR_ModelWriter_3MF_Native.h" #include "Model/Writer/NMR_ModelWriter_STL.h" +namespace NMR { + class CExportStreamMemory; + using PExportStreamMemory = std::shared_ptr; +} + namespace Lib3MF { namespace Impl { @@ -60,6 +65,7 @@ class CWriter : public virtual IWriter, public virtual CBase { */ NMR::PModelWriter m_pWriter; + NMR::PExportStreamMemory momentBuffer; protected: /** @@ -91,6 +97,19 @@ class CWriter : public virtual IWriter, public virtual CBase { Lib3MF_uint32 GetDecimalPrecision() override; void SetDecimalPrecision(const Lib3MF_uint32 nDecimalPrecision) override; + + void AddKeyWrappingCallback(const std::string & sConsumerID, const Lib3MF::KeyWrappingCallback pTheCallback, const Lib3MF_pvoid pUserData); + + void SetContentEncryptionCallback(const Lib3MF::ContentEncryptionCallback pTheCallback, const Lib3MF_pvoid pUserData); + + void SetStrictModeActive(const bool bStrictModeActive); + + bool GetStrictModeActive(); + + std::string GetWarning(const Lib3MF_uint32 nIndex, Lib3MF_uint32 & nErrorCode); + + Lib3MF_uint32 GetWarningCount(); + }; } diff --git a/Include/Common/Mesh/NMR_BeamLattice.h b/Include/Common/Mesh/NMR_BeamLattice.h index 7e5b0c795..b78d63928 100644 --- a/Include/Common/Mesh/NMR_BeamLattice.h +++ b/Include/Common/Mesh/NMR_BeamLattice.h @@ -38,6 +38,8 @@ NMR_MeshBeamLattice.h defines the class CMeshBeamLattice. #include "Common/NMR_Types.h" #include "Model/Classes/NMR_ModelTypes.h" +#include + namespace NMR { class CBeamLattice { @@ -45,13 +47,19 @@ namespace NMR { friend class CMesh; MESHNODES &m_Nodes; // reference to the nodes of the parent mesh + std::unordered_set m_OccupiedNodes; // datastructure used to ensure that balls are only placed at nodes with beams MESHBEAMS m_Beams; std::vector m_pBeamSets; + MESHBALLS m_Balls; nfDouble m_dMinLength; + eModelBeamLatticeBallMode m_eBallMode; + nfDouble m_dDefaultBallRadius; public: CBeamLattice(_In_ MESHNODES &nodes); + void clearBeams(); + void clearBalls(); void clear(); }; diff --git a/Include/Common/Mesh/NMR_Mesh.h b/Include/Common/Mesh/NMR_Mesh.h index 70c626c8b..628f43df0 100644 --- a/Include/Common/Mesh/NMR_Mesh.h +++ b/Include/Common/Mesh/NMR_Mesh.h @@ -74,17 +74,23 @@ namespace NMR { _Ret_notnull_ MESHFACE * addFace(_In_ nfInt32 nNodeIndex1, _In_ nfInt32 nNodeIndex2, _In_ nfInt32 nNodeIndex3); _Ret_notnull_ MESHBEAM * addBeam(_In_ MESHNODE * pNode1, _In_ MESHNODE * pNode2, _In_ nfDouble dRadius1, _In_ nfDouble dRadius2, _In_ nfInt32 eCapMode1, _In_ nfInt32 eCapMode2); + _Ret_notnull_ MESHBALL * addBall(_In_ MESHNODE * pNode, _In_ nfDouble dRadius); _Ret_notnull_ PBEAMSET addBeamSet(); nfUint32 getNodeCount(); nfUint32 getFaceCount(); nfUint32 getBeamCount(); + nfUint32 getBallCount(); nfUint32 getBeamSetCount(); + nfUint32 getOccupiedNodeCount(); + nfBool isNodeOccupied(_In_ nfUint32 nIdx); _Ret_notnull_ MESHNODE * getNode(_In_ nfUint32 nIdx); _Ret_notnull_ MESHFACE * getFace(_In_ nfUint32 nIdx); _Ret_notnull_ MESHBEAM * getBeam(_In_ nfUint32 nIdx); + _Ret_notnull_ MESHBALL * getBall(_In_ nfUint32 nIdx); _Ret_notnull_ PBEAMSET getBeamSet(_In_ nfUint32 nIdx); + _Ret_notnull_ MESHNODE * getOccupiedNode(_In_ nfUint32 nIdx); void setBeamLatticeMinLength(nfDouble dMinLength); nfDouble getBeamLatticeMinLength(); @@ -92,20 +98,28 @@ namespace NMR { // TODO: make these return sensible values void setDefaultBeamRadius(nfDouble dRadius); nfDouble getDefaultBeamRadius(); + void setDefaultBallRadius(nfDouble dBallRadius); + nfDouble getDefaultBallRadius(); void setBeamLatticeAccuracy(nfDouble dAccuracy); nfBool getBeamLatticeAccuracy(nfDouble& dAccuracy); - void setBeamLatticeCapMode(eModelBeamLatticeCapMode dRadius); + void setBeamLatticeBallMode(eModelBeamLatticeBallMode eBallMode); + eModelBeamLatticeBallMode getBeamLatticeBallMode(); + void setBeamLatticeCapMode(eModelBeamLatticeCapMode eCapMode); eModelBeamLatticeCapMode getBeamLatticeCapMode(); nfBool checkSanity(); void clear(); void clearBeamLattice(); + void clearBeamLatticeBeams(); + void clearBeamLatticeBalls(); + void scanOccupiedNodes(); + void validateBeamLatticeBalls(); _Ret_maybenull_ CMeshInformationHandler * getMeshInformationHandler(); _Ret_notnull_ CMeshInformationHandler * createMeshInformationHandler(); void clearMeshInformationHandler(); - void patchMeshInformationResources(_In_ std::map &oldToNewMapping); + void patchMeshInformationResources(_In_ std::map &oldToNewMapping); void extendOutbox(_Out_ NOUTBOX3& vOutBox, _In_ const NMATRIX3 mAccumulatedMatrix); }; diff --git a/Include/Common/Mesh/NMR_MeshTypes.h b/Include/Common/Mesh/NMR_MeshTypes.h index 1d707abc8..5dbe04378 100644 --- a/Include/Common/Mesh/NMR_MeshTypes.h +++ b/Include/Common/Mesh/NMR_MeshTypes.h @@ -46,6 +46,7 @@ In addition, some constants are defined here. #define NMR_MESH_MAXEDGECOUNT 2147483647 #define NMR_MESH_MAXFACECOUNT 2147483647 #define NMR_MESH_MAXBEAMCOUNT 2147483647 +#define NMR_MESH_MAXBALLCOUNT 2147483647 #define NMR_MESH_MAXCOORDINATE 1000000000.0f @@ -53,6 +54,7 @@ In addition, some constants are defined here. #define NMR_MESH_EDGEBLOCKCOUNT 256 #define NMR_MESH_FACEBLOCKCOUNT 256 #define NMR_MESH_BEAMBLOCKCOUNT 256 +#define NMR_MESH_BALLBLOCKCOUNT 256 #define NMR_MESH_NODEEDGELINKBLOCKCOUNT 256 namespace NMR { @@ -71,6 +73,7 @@ namespace NMR { typedef struct BEAMSET { std::vector m_Refs; + std::vector m_BallRefs; std::string m_sName; // "" for no name std::string m_sIdentifier; // "" for no identifier BEAMSET() { @@ -91,6 +94,15 @@ namespace NMR { } MESHBEAM; typedef CPagedVector MESHBEAMS; + typedef struct MESHBALL { + nfInt32 m_index; + nfInt32 m_nodeindex; + nfDouble m_radius; + MESHBALL() { + }; + } MESHBALL; + typedef CPagedVector MESHBALLS; + typedef struct { nfInt32 m_index; NVEC2 m_position; diff --git a/Include/Common/MeshInformation/NMR_MeshInformationTypes.h b/Include/Common/MeshInformation/NMR_MeshInformationTypes.h index 02f73b3f5..c61513a55 100644 --- a/Include/Common/MeshInformation/NMR_MeshInformationTypes.h +++ b/Include/Common/MeshInformation/NMR_MeshInformationTypes.h @@ -51,7 +51,7 @@ namespace NMR { #pragma pack (1) typedef struct { - nfUint32 m_nResourceID; + nfUint32 m_nUniqueResourceID; nfUint32 m_nPropertyIDs[3]; } MESHINFORMATION_PROPERTIES; diff --git a/Include/Common/MeshInformation/NMR_MeshInformation_Properties.h b/Include/Common/MeshInformation/NMR_MeshInformation_Properties.h index 6d0d20823..ce8a62e80 100644 --- a/Include/Common/MeshInformation/NMR_MeshInformation_Properties.h +++ b/Include/Common/MeshInformation/NMR_MeshInformation_Properties.h @@ -42,16 +42,16 @@ namespace NMR { class CMeshInformation_PropertyIndexMapping { private: - std::map, nfUint32> m_IDMap; + std::map, nfUint32> m_IDMap; public: CMeshInformation_PropertyIndexMapping(); - nfUint32 mapPropertyIDToIndex(nfUint32 nResourceID, ModelPropertyID nPropertyID); + nfUint32 mapPropertyIDToIndex(UniqueResourceID nUniqueResourceID, ModelPropertyID nPropertyID); - nfUint32 getDefaultResourceID (); - nfUint32 getDefaultResourceIndex (); + UniqueResourceID getDefaultResourceID(); + nfUint32 getDefaultResourceIndex(); - nfUint32 registerPropertyID(nfUint32 nResourceID, ModelPropertyID nPropertyID, nfUint32 nResourceIndex); + nfUint32 registerPropertyID(UniqueResourceID nUniqueResourceID, ModelPropertyID nPropertyID, nfUint32 nResourceIndex); }; diff --git a/Include/Common/NMR_ErrorConst.h b/Include/Common/NMR_ErrorConst.h index 620679a67..598880d93 100644 --- a/Include/Common/NMR_ErrorConst.h +++ b/Include/Common/NMR_ErrorConst.h @@ -290,6 +290,15 @@ NMR_ErrorConst.h defines all error code constants. // XML prefix is already registered. #define NMR_ERROR_XMLPREFIXALREADYREGISTERED 0x104F +// Failed to initialize a zlib buffer +#define NMR_ERROR_COULDNOTINITINFLATE 0x1050 + +// Failed to decompress part +#define NMR_ERROR_COULDNOTINFLATE 0x1051 + +// Failed to initialize a zlib buffer +#define NMR_ERROR_COULDNOTINITDEFLATE 0x1052 + /*------------------------------------------------------------------- Core framework error codes (0x2XXX) -------------------------------------------------------------------*/ @@ -423,7 +432,7 @@ Core framework error codes (0x2XXX) // Part is too large #define NMR_ERROR_PARTTOOLARGE 0x202B -// Texture path is already existing +// Texture getPath is already existing #define NMR_ERROR_DUPLICATETEXTUREPATH 0x202C // Texture width is already existing @@ -477,6 +486,8 @@ Core framework error codes (0x2XXX) // Too many beams #define NMR_ERROR_TOOMANYBEAMS 0x203D +// Too many balls +#define NMR_ERROR_TOOMANYBALLS 0x203E // Invalid slice polygon index #define NMR_ERROR_INVALIDSLICEPOLYGON 0x2040 @@ -911,7 +922,7 @@ Model error codes (0x8XXX) // a slice stack resource is invalid #define NMR_ERROR_INVALIDSLICESTACK 0x809D -// Duplicate path +// Duplicate getPath #define NMR_ERROR_DUPLICATEPATH 0x809E // Duplicate UUID @@ -1103,6 +1114,114 @@ Model error codes (0x8XXX) // Version 093 of the core-specification is not fully supported #define NMR_ERROR_VERSION093_NOT_SUPPORTED 0x80E7 +// Attachment Model Mismatch +#define NMR_ERROR_ATTACHMENTMODELMISMATCH 0x80E8 + +// Duplicate PackagePath +#define NMR_ERROR_DUPLICATEPACKAGEPATH 0x80E9 + +// Serialization of this Model requires the production extension +#define NMR_ERROR_PRODUCTIONEXTENSION_REQUIRED 0x80EA + +// Referenced model resource must not be in a different model +#define NMR_ERROR_MODELRESOURCE_IN_DIFFERENT_MODEL 0x80EB + +// Path attribute is not absolute +#define NMR_ERROR_PATH_NOT_ABSOLUTE 0x80EC + +// Encrypted stream header signature mismatch +#define NMR_ERROR_COULDNOTREADENCRYPTEDSTREAM 0x80ED + +// Header version mismatch +#define NMR_ERROR_ENCRYPTEDCONTENTVERSIONUNSUPPORTED 0x80EE + +// Could not get OPC KeyStore Stream +#define NMR_ERROR_KEYSTOREOPCCOULDNOTGETSTREAM 0x80F0 + +// Duplicate KeyStore Consumer id attribute on xml +#define NMR_ERROR_KEYSTOREDUPLICATECONSUMERID 0x80F1 + +// Duplicate KeyStore Consumer keyId attribute on xml +#define NMR_ERROR_KEYSTOREDUPLICATECONSUMERKEYID 0x80F2 + +// Missing KeyStore Consumer id +#define NMR_ERROR_KEYSTOREMISSINGCONSUMERID 0x80F3 + +// Duplicate KeyStore ResourceData path +#define NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATAPATH 0x80F4 + +// Duplicate KeyStore DecryptRight consumerindex +#define NMR_ERROR_KEYSTOREDUPLICATECONSUMERINDEX 0x80F5 + +// Invalid KeyStore Consumer Index +#define NMR_ERROR_KEYSTOREINVALIDCONSUMERINDEX 0x80F6 + +// Invalid KeyStore encryption algorithm +#define NMR_ERROR_KEYSTOREINVALIDALGORITHM 0x80F7 + +// Invalid KeyStore compression +#define NMR_ERROR_KEYSTOREINVALIDCOMPRESSION 0x80F8 + +// Invlaid KeyStore CipherValue +#define NMR_ERROR_KEYSTOREINVALIDCIPHERVALUE 0x80F9 + +//Missing decrypt right +#define NMR_ERROR_KEYSTOREMISSINGCIPHERDATA 0x80FA + +// Duplicate KeyStore consumer +#define NMR_ERROR_KEYSTOREDUPLICATECONSUMER 0x80FB + +// Duplicate KeyStore ResourceData object +#define NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATA 0x80FC + +// Duplicate KeyStore DecryptRight object +#define NMR_ERROR_KEYSTOREDUPLICATEACCESSRIGHT 0x80FD + +// Invalid KEK Param +#define NMR_ERROR_KEYSTOREMISSINGCEKPARAMS 0x80FE + +// Invalid key uuid param +#define NMR_ERROR_KEYSTOREINVALIDKEYUUID 0x80FF + +// Unsupported algorithm +#define NMR_ERROR_KEYSTOREUNSUPPORTEDALGORITHM 0x8100 + +// Dupliaced KeySore ResourceDataGroup +#define NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATAGROUP 0x8101 + +// Invalid KeyStore Mask Generation Function +#define NMR_ERROR_KEYSTOREINVALIDMGF 0x8102 + +// Invalid KeyStore Digest Method +#define NMR_ERROR_KEYSTOREINVALIDDIGEST 0x8103 + +// Invalid Keystore kekparams configuration +#define NMR_ERROR_KEYSTOREINCONSISTENTKEKPARAMS 0x8104 + +// No Consumer Index +#define NMR_ERROR_KEYSTOREMISSINGCONSUMERINDEX 0x8105 + +// No kekparams +#define NMR_ERROR_KEYSTOREMISSINGKEKPARAMS 0x8106 + +// No keyuuid +#define NMR_ERROR_KEYSTOREMISSINGKEYUUID 0x8107 + +// Too many elements in a keystore xml tree +#define NMR_ERROR_KEYSTORETOOMANYELEMENTS 0x8108 + +// No path defined on resourcedata +#define NMR_ERROR_KEYSTOREMISSINGPATH 0x8109 + +// No algorithm defined +#define NMR_ERROR_KEYSTOREMISSINGALGORTHM 0x810A + +// A beamset identifier is not unique +#define NMR_ERROR_BEAMSET_IDENTIFIER_NOT_UNIQUE 0x810B + + + + /*------------------------------------------------------------------- XML Parser Error Constants (0x9XXX) @@ -1183,6 +1302,8 @@ XML Parser Error Constants (0x9XXX) // A matindices attribute is duplicated #define NMR_ERROR_DUPLICATE_MATINDICES_ATTRIBUTE 0x9019 +// + /*------------------------------------------------------------------- Library errors (0xAXXX) @@ -1206,4 +1327,14 @@ Library errors (0xAXXX) // Invalid Texture type #define NMR_ERROR_INVALIDTEXTURETYPE 0xA006 +// Key Encryption Descriptor not found +#define NMR_ERROR_KEKDESCRIPTORNOTFOUND 0xA00A + +// Content encryption descritor not found +#define NMR_ERROR_DEKDESCRIPTORNOTFOUND 0xA00B + +// Using cryptographically weak random number generator +#define NMR_ERROR_RNGCALLBACKNOTCRYPTOSTRONG 0XA00C + + #endif // __NMR_ERRORCONST diff --git a/Include/Model/Reader/NMR_ModelReaderWarnings.h b/Include/Common/NMR_ModelWarnings.h similarity index 59% rename from Include/Model/Reader/NMR_ModelReaderWarnings.h rename to Include/Common/NMR_ModelWarnings.h index c1a0e9967..3a376f81a 100644 --- a/Include/Model/Reader/NMR_ModelReaderWarnings.h +++ b/Include/Common/NMR_ModelWarnings.h @@ -43,57 +43,49 @@ a relaxed import policy on the file format. #define NMR_MAXWARNINGCOUNT 1000000000 -#define MODELREADERWARNING_INVALIDMODELUNIT "invalid model unit" -#define MODELREADERWARNING_INVALIDMETADATA "invalid model metadata" -#define MODELREADERWARNING_DUPLICATEMETADATA "duplicate model metadata" -#define MODELREADERWARNING_INVALIDMODELOBJECTTYPE "invalid model object tpye" -#define MODELREADERWARNING_REQUIREDEXTENSIONNOTSUPPORTED "A required extension is not supported" -#define MODELREADERWARNING_BEAMLATTICECLIPPINGRESOURCENOTDEFINED "The resource defined as clippingmesh has not yet been defined in the model" -#define MODELREADERWARNING_BEAMLATTICEREPRESENTATIONRESOURCENOTDEFINED "The resource defined as representationmesh has not yet been defined in the model" - namespace NMR { - typedef enum _eModelReaderWarningLevel { + typedef enum _eModelWarningLevel { mrwFatal, mrwInvalidMandatoryValue, mrwMissingMandatoryValue, mrwInvalidOptionalValue - } eModelReaderWarningLevel; + } eModelWarningLevel; - class CModelReaderWarning { + class CModelWarning { private: std::string m_sMessage; - eModelReaderWarningLevel m_WarningLevel; + eModelWarningLevel m_WarningLevel; nfError m_nErrorCode; public: - CModelReaderWarning() = delete; - CModelReaderWarning(std::string sMessage, eModelReaderWarningLevel WarningLevel, nfError nErrorCode); + CModelWarning() = delete; + CModelWarning(std::string sMessage, eModelWarningLevel WarningLevel, nfError nErrorCode); std::string getMessage(); - eModelReaderWarningLevel getWarningLevel(); + eModelWarningLevel getWarningLevel(); nfError getErrorCode(); }; - typedef std::shared_ptr PModelReaderWarning; + typedef std::shared_ptr PModelReaderWarning; - class CModelReaderWarnings { + class CModelWarnings { private: std::vector m_Warnings; - eModelReaderWarningLevel m_CriticalWarningLevel; + eModelWarningLevel m_CriticalWarningLevel; public: - CModelReaderWarnings(); + CModelWarnings(); - eModelReaderWarningLevel getCriticalWarningLevel (); - void setCriticalWarningLevel(_In_ eModelReaderWarningLevel WarningLevel); + eModelWarningLevel getCriticalWarningLevel (); + void setCriticalWarningLevel(_In_ eModelWarningLevel WarningLevel); - void addWarning(_In_ std::string sMessage, _In_ nfError nErrorCode, _In_ eModelReaderWarningLevel WarningLevel); - void addException(const _In_ CNMRException & Exception, _In_ eModelReaderWarningLevel WarningLevel); + void addWarning(_In_ nfError nErrorCode, _In_ eModelWarningLevel WarningLevel); + void addException(const _In_ CNMRException & Exception, _In_ eModelWarningLevel WarningLevel); nfUint32 getWarningCount(); PModelReaderWarning getWarning(_In_ nfUint32 nIndex); }; - typedef std::shared_ptr PModelReaderWarnings; + typedef std::shared_ptr PModelWarnings; } diff --git a/Include/Common/NMR_SecureContentTypes.h b/Include/Common/NMR_SecureContentTypes.h new file mode 100644 index 000000000..2e19f2ca7 --- /dev/null +++ b/Include/Common/NMR_SecureContentTypes.h @@ -0,0 +1,118 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +--*/ + + +#ifndef NMR_SECURECONTENTTYPES +#define NMR_SECURECONTENTTYPES + +#define KEYSTORE_TYPES_MODULUSBUFFERSIZE 257 +#define KEYSTORE_TYPES_EXPONENTBUFFERSIZE 5 +#define KEYSTORE_TYPES_IVSIZE 12 +#define KEYSTORE_TYPES_TAGSIZE 16 + +#include "Common/NMR_Types.h" +#include "Common/NMR_Local.h" + +#include +#include +namespace NMR { + + enum eKeyStoreWrapAlgorithm { + RSA_OAEP = 0, // http://www.w3.org/2009/xmlenc11#rsa-oaep, http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p + }; + + enum eKeyStoreMaskGenerationFunction { + MGF1_SHA1 = 160, // http://www.w3.org/2009/xmlenc11#mgf1sha1 + MGF1_SHA224 = 224, // http://www.w3.org/2009/xmlenc11#mgf1sha224 + MGF1_SHA256 = 256, // http://www.w3.org/2009/xmlenc11#mgf1sha256 + MGF1_SHA384 = 384, // http://www.w3.org/2009/xmlenc11#mgf1sha384 + MGF1_SHA512 = 512 // http://www.w3.org/2009/xmlenc11#mgf1sha512 + }; + + enum eKeyStoreMessageDigest { + SHA1 = 160, // http://www.w3.org/2000/09/xmldsig#sha1 + SHA256 = 256, // http://www.w3.org/2001/04/xmlenc#sha256 + SHA384 = 384, // http://www.w3.org/2001/04/xmlenc#sha384 + SHA512 = 512, // http://www.w3.org/2001/04/xmlenc#sha512 + }; + + enum eKeyStoreEncryptAlgorithm { + AES256_GCM = 1 // http://www.w3.org/2009/xmlenc11#aes256-gcm + }; + + class CKeyStoreContentEncryptionParams; + using PKeyStoreContentEncryptionParams = std::shared_ptr; + + struct ContentEncryptionContext { + void * m_pUserData; + PKeyStoreContentEncryptionParams m_sParams; + }; + using ContentEncryptionCbType = std::function; + + struct ContentEncryptionDescriptor { + ContentEncryptionCbType m_fnCrypt; + ContentEncryptionContext m_sDekDecryptData; + }; + + class CKeyStoreAccessRight; + using PKeyStoreAccessRight = std::shared_ptr; + + struct KeyWrappingContext { + void * m_pUserData; + PKeyStoreAccessRight m_pAccessRight; + }; + + using KeyWrappingCbType = std::function const &, std::vector &, KeyWrappingContext &)>; + + struct KeyWrappingDescriptor { + KeyWrappingCbType m_fnWrap; + KeyWrappingContext m_sKekDecryptData; + }; + + using CryptoRandCbType = std::function; + + struct CryptoRandGenDescriptor { + CryptoRandCbType m_fnRNG; + void * m_pUserData; + }; + + constexpr nfUint64 fnGetAlgorithmInitVectorSize(eKeyStoreEncryptAlgorithm ea) { + return 12; + } + + constexpr nfUint64 fnGetAlgorithmKeySize(eKeyStoreEncryptAlgorithm ea) { + return 32; + } + + constexpr nfUint64 fnGetAlgorithmAuthTagSize(eKeyStoreEncryptAlgorithm ea) { + return 16; + } +} + +#endif // !NMR_SECURECONTENTTYPES diff --git a/Include/Common/NMR_SecureContext.h b/Include/Common/NMR_SecureContext.h new file mode 100644 index 000000000..90dcde2a0 --- /dev/null +++ b/Include/Common/NMR_SecureContext.h @@ -0,0 +1,34 @@ + + + +#ifndef NMR_SECURECONTEXT +#define NMR_SECURECONTEXT + +#include +#include +#include "Common/NMR_SecureContentTypes.h" + +namespace NMR { + + using ClientConsumerMap = std::map; + class CSecureContext { + private: + ClientConsumerMap m_ConsumerMap; + ContentEncryptionDescriptor m_sDekDescriptor; + bool m_bHasDek = false; + public: + bool hasDekCtx() const; + ContentEncryptionDescriptor getDekCtx() const; + void setDekCtx(ContentEncryptionDescriptor const & descriptor); + + ClientConsumerMap::const_iterator kekCtxBegin() const; + ClientConsumerMap::const_iterator kekCtxEnd() const; + void addKekCtx(std::string const & consumerId, KeyWrappingDescriptor const & descriptor); + KeyWrappingDescriptor getKekCtx(std::string const & consumerId) const; + bool emptyKekCtx() const; + }; + + +} + +#endif // !NMR_SECURECONTEXT diff --git a/Include/Common/NMR_StringUtils.h b/Include/Common/NMR_StringUtils.h index 2df89da13..99eb31644 100644 --- a/Include/Common/NMR_StringUtils.h +++ b/Include/Common/NMR_StringUtils.h @@ -142,6 +142,9 @@ namespace NMR { } return vctValues; } + + void decomposeKeyIntoNamespaceAndName(const std::string &sKey, std::string &sNameSpace, std::string &sName); + std::string composeNamespaceAndNameIntoKey(const std::string &sNameSpace, const std::string &sName); } #endif // __NMR_STRINGUTILS diff --git a/Include/Common/OPC/NMR_IOpcPackageReader.h b/Include/Common/OPC/NMR_IOpcPackageReader.h new file mode 100644 index 000000000..873d24911 --- /dev/null +++ b/Include/Common/OPC/NMR_IOpcPackageReader.h @@ -0,0 +1,24 @@ +#ifndef NMR_IOPCPACKAGEREADER +#define NMR_IOPCPACKAGEREADER + +#include +#include +#include "Common/NMR_Types.h" +#include "Common/NMR_Local.h" + +namespace NMR { + class COpcPackageRelationship; + class COpcPackagePart; + using POpcPackagePart = std::shared_ptr; + + class IOpcPackageReader { + public: + virtual _Ret_maybenull_ COpcPackageRelationship * findRootRelation(_In_ std::string sRelationType, _In_ nfBool bMustBeUnique) = 0; + virtual POpcPackagePart createPart(_In_ std::string sPath) = 0; + virtual nfUint64 getPartSize(_In_ std::string sPath) = 0; + virtual void close() {} + }; + + using PIOpcPackageReader = std::shared_ptr; +} +#endif // !NMR_IOPCPACKAGEREADER diff --git a/Include/Common/OPC/NMR_IOpcPackageWriter.h b/Include/Common/OPC/NMR_IOpcPackageWriter.h new file mode 100644 index 000000000..838707a8e --- /dev/null +++ b/Include/Common/OPC/NMR_IOpcPackageWriter.h @@ -0,0 +1,29 @@ +#ifndef NMR_IOPCPACKAGEWRITER +#define NMR_IOPCPACKAGEWRITER + +#include +#include +#include +#include "Common/NMR_Types.h" +#include "Common/NMR_Local.h" + +namespace NMR { + class COpcPackageRelationship; + using POpcPackageRelationship = std::shared_ptr; + class COpcPackagePart; + using POpcPackagePart = std::shared_ptr; + + class IOpcPackageWriter { + public: + virtual POpcPackagePart addPart(_In_ std::string sPath) = 0; + virtual void addContentType(_In_ std::string sExtension, _In_ std::string sContentType) = 0; + virtual void addContentType(_In_ POpcPackagePart pOpcPackagePart, _In_ std::string sContentType) = 0; + virtual POpcPackageRelationship addRootRelationship(_In_ std::string sType, _In_ COpcPackagePart * pTargetPart) = 0; + virtual POpcPackageRelationship addPartRelationship(_In_ POpcPackagePart pOpcPackagePart, _In_ std::string sType, _In_ COpcPackagePart * pTargetPart) = 0; + virtual std::list addWriterSpecificRelationships(_In_ POpcPackagePart pOpcPackagePart, _In_ COpcPackagePart* pTargetPart) = 0; + virtual void close() {} + }; + + using PIOpcPackageWriter = std::shared_ptr; +} +#endif // !NMR_IOPCPACKAGEWRITER diff --git a/Include/Common/OPC/NMR_OpcPackagePart.h b/Include/Common/OPC/NMR_OpcPackagePart.h index 91661dfb2..3c6ca8d9c 100644 --- a/Include/Common/OPC/NMR_OpcPackagePart.h +++ b/Include/Common/OPC/NMR_OpcPackagePart.h @@ -56,6 +56,8 @@ namespace NMR { public: COpcPackagePart(_In_ std::string sURI, _In_ PExportStream pExportStream); COpcPackagePart(_In_ std::string sURI, _In_ PImportStream pImportStream); + COpcPackagePart(_In_ COpcPackagePart const & cp, _In_ PExportStream pExportStream); + COpcPackagePart(_In_ COpcPackagePart const & cp, _In_ PImportStream pImportStream); std::string getURI (); PExportStream getExportStream (); diff --git a/Include/Common/OPC/NMR_OpcPackageReader.h b/Include/Common/OPC/NMR_OpcPackageReader.h index 04c3e8949..bdc4f6568 100644 --- a/Include/Common/OPC/NMR_OpcPackageReader.h +++ b/Include/Common/OPC/NMR_OpcPackageReader.h @@ -33,12 +33,13 @@ NMR_OpcPackageReader.h defines an OPC Package reader in a portable way. #ifndef __NMR_OPCPACKAGEREADER #define __NMR_OPCPACKAGEREADER +#include "Common/OPC/NMR_IOpcPackageReader.h" #include "Common/Platform/NMR_ImportStream.h" #include "Common/OPC/NMR_OpcPackagePart.h" #include "Common/OPC/NMR_OpcPackageTypes.h" #include "Common/OPC/NMR_OpcPackageRelationship.h" #include "Common/3MF_ProgressMonitor.h" -#include "Model/Reader/NMR_ModelReaderWarnings.h" +#include "Common/NMR_ModelWarnings.h" #include "Libraries/libzip/zip.h" #include #include @@ -47,9 +48,9 @@ NMR_OpcPackageReader.h defines an OPC Package reader in a portable way. namespace NMR { - class COpcPackageReader { + class COpcPackageReader: public IOpcPackageReader { protected: - PModelReaderWarnings m_pWarnings; + PModelWarnings m_pWarnings; PProgressMonitor m_pProgressMonitor; // ZIP Handling Variables @@ -74,12 +75,12 @@ namespace NMR { void readRootRelationships(); public: - COpcPackageReader(_In_ PImportStream pImportStream, _In_ PModelReaderWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor); + COpcPackageReader(_In_ PImportStream pImportStream, _In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor); ~COpcPackageReader(); - _Ret_maybenull_ COpcPackageRelationship * findRootRelation(_In_ std::string sRelationType, _In_ nfBool bMustBeUnique); - POpcPackagePart createPart(_In_ std::string sPath); - nfUint64 GetPartSize(_In_ std::string sPath); + _Ret_maybenull_ COpcPackageRelationship * findRootRelation(_In_ std::string sRelationType, _In_ nfBool bMustBeUnique) override; + POpcPackagePart createPart(_In_ std::string sPath) override; + nfUint64 getPartSize(_In_ std::string sPath) override; }; typedef std::shared_ptr POpcPackageReader; diff --git a/Include/Common/OPC/NMR_OpcPackageWriter.h b/Include/Common/OPC/NMR_OpcPackageWriter.h index d2037c276..5bbf3bfc5 100644 --- a/Include/Common/OPC/NMR_OpcPackageWriter.h +++ b/Include/Common/OPC/NMR_OpcPackageWriter.h @@ -36,6 +36,7 @@ NMR_OpcPackageWriter.h defines an OPC Package writer in a portable way. #include "Common/Platform/NMR_ExportStream.h" #include "Common/Platform/NMR_ExportStream_ZIP.h" #include "Common/Platform/NMR_PortableZIPWriter.h" +#include "Common/OPC/NMR_IOpcPackageWriter.h" #include "Common/OPC/NMR_OpcPackagePart.h" #include "Common/OPC/NMR_OpcPackageTypes.h" #include "Common/OPC/NMR_OpcPackageRelationship.h" @@ -44,27 +45,34 @@ NMR_OpcPackageWriter.h defines an OPC Package writer in a portable way. namespace NMR { - class COpcPackageWriter { + class COpcPackageWriter: public IOpcPackageWriter { protected: PExportStream m_pExportStream; std::list m_Parts; PPortableZIPWriter m_pZIPWriter; + nfInt32 m_nRelationIDCounter; - std::map m_ContentTypes; + // Extension -> ContentType + std::map m_DefaultContentTypes; + // PartName -> ContentType + std::map m_OverrideContentTypes; std::list m_RootRelationships; void finishPackage(); void writeContentTypes(); void writeRootRelationships(); + std::string generateRelationShipID(); public: COpcPackageWriter(_In_ PExportStream pExportStream); ~COpcPackageWriter(); - POpcPackagePart addPart(_In_ std::string sPath); - - void addContentType(_In_ std::string sExtension, _In_ std::string sContentType); - POpcPackageRelationship addRootRelationship(_In_ std::string sID, _In_ std::string sType, _In_ COpcPackagePart * pTargetPart); + POpcPackagePart addPart(_In_ std::string sPath) override; + void addContentType(_In_ std::string sExtension, _In_ std::string sContentType) override; + void addContentType(_In_ POpcPackagePart pOpcPackagePart, _In_ std::string sContentType) override; + POpcPackageRelationship addRootRelationship(_In_ std::string sType, _In_ COpcPackagePart * pTargetPart) override; + POpcPackageRelationship addPartRelationship(_In_ POpcPackagePart pOpcPackagePart, _In_ std::string sType, _In_ COpcPackagePart * pTargetPart) override; + std::list addWriterSpecificRelationships(_In_ POpcPackagePart pOpcPackagePart, _In_ COpcPackagePart* pTargetPart) override; }; typedef std::shared_ptr POpcPackageWriter; diff --git a/Include/Common/Platform/NMR_EncryptionHeader.h b/Include/Common/Platform/NMR_EncryptionHeader.h new file mode 100644 index 000000000..0242aeed2 --- /dev/null +++ b/Include/Common/Platform/NMR_EncryptionHeader.h @@ -0,0 +1,44 @@ +#ifndef NMR_ENCRYPTIONHEADER +#define NMR_ENCRYPTIONHEADER + +#include +#include +#include "Common/NMR_Types.h" +#include "Common/NMR_Local.h" + +namespace NMR { + class CImportStream; + using PImportStream = std::shared_ptr; + class CExportStream; + using PExportStream = std::shared_ptr; + + union uEncryptedFileHeader { + nfByte bytes[12]; + struct sHeaderStructure { + union uMagic { + nfByte bytes[5]; + } Signature; + nfByte majorVersion; + nfByte minorVersion; + nfByte unused; + union uLength { + nfByte bytes[4]; + nfUint32 length; + } Length; + } Header; + }; + + class CEncryptionHeader { + std::vector m_rgAdditionalData; + nfUint64 m_nfHeaderSize; + public: + CEncryptionHeader(std::vector const & additionalData = std::vector()); + size_t readFrom(PImportStream from); + size_t writeTo(PExportStream to); + + std::vector const & additionalData() const; + nfUint64 headerSize() const; + }; +} + +#endif // !NMR_ENCRYPTIONHEADER diff --git a/Include/Common/Platform/NMR_ExportStream.h b/Include/Common/Platform/NMR_ExportStream.h index 401f561af..15108a716 100644 --- a/Include/Common/Platform/NMR_ExportStream.h +++ b/Include/Common/Platform/NMR_ExportStream.h @@ -52,6 +52,7 @@ namespace NMR { virtual nfBool seekFromEnd(_In_ nfUint64 bytes, _In_ nfBool bHasToSucceed) = 0; virtual nfUint64 getPosition () = 0; virtual nfUint64 writeBuffer(_In_ const void * pBuffer, _In_ nfUint64 cbTotalBytesToWrite) = 0; + virtual void close(); void copyFrom(_In_ CImportStream * pImportStream, _In_ nfUint64 cbCount, _In_ nfUint32 cbBufferSize); }; diff --git a/Include/Common/Platform/NMR_ExportStream_Compressed.h b/Include/Common/Platform/NMR_ExportStream_Compressed.h new file mode 100644 index 000000000..453bfcda3 --- /dev/null +++ b/Include/Common/Platform/NMR_ExportStream_Compressed.h @@ -0,0 +1,69 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ExportStream_Compressed.h defines a stream to write compressed files + +--*/ + +#ifndef __NMR_EXPORTSTREAM_COMPRESSED +#define __NMR_EXPORTSTREAM_COMPRESSED + +#include "Common/NMR_Types.h" +#include "Common/Platform/NMR_ExportStream.h" +#include "Common/Platform/NMR_PortableZIPWriter.h" +#include "Libraries/zlib/zlib.h" + +#define EXPORTSTREAM_WRITE_BUFFER_CHUNKSIZE 1024 + +namespace NMR { + + class CExportStream_Compressed: public CExportStream { + private: + z_stream m_strm; + PExportStream m_pUncompressedStream; + nfByte out[EXPORTSTREAM_WRITE_BUFFER_CHUNKSIZE]; + + nfInt32 compress(nfInt32 flush); + public: + CExportStream_Compressed() = delete; + CExportStream_Compressed(PExportStream pUncompressedStream); + ~CExportStream_Compressed(); + + virtual nfBool seekPosition(_In_ nfUint64 position, _In_ nfBool bHasToSucceed); + virtual nfBool seekForward(_In_ nfUint64 bytes, _In_ nfBool bHasToSucceed); + virtual nfBool seekFromEnd(_In_ nfUint64 bytes, _In_ nfBool bHasToSucceed); + virtual nfUint64 getPosition(); + virtual nfUint64 writeBuffer(_In_ const void * pBuffer, _In_ nfUint64 cbTotalBytesToWrite); + virtual void close(); + }; + + typedef std::shared_ptr PExportStream_Compressed; + +} + +#endif // __NMR_EXPORTSTREAM_COMPRESSED diff --git a/Include/Common/Platform/NMR_ExportStream_Encrypted.h b/Include/Common/Platform/NMR_ExportStream_Encrypted.h new file mode 100644 index 000000000..c6dc61ee5 --- /dev/null +++ b/Include/Common/Platform/NMR_ExportStream_Encrypted.h @@ -0,0 +1,68 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ImportStream_Encrypted.h defines the CImportStream_Encrypted Class. +This is a stream class for importing encrypted resources from the underlying stream and handing them +to the proper callbacks that will decrypt the content before returning back to the consumer. + +--*/ + +#ifndef NMR_EXPORTSTREAM_ENCRYPTED +#define NMR_EXPORTSTREAM_ENCRYPTED + +#include "Common/NMR_Types.h" +#include "Common/NMR_SecureContentTypes.h" +#include "Common/Platform/NMR_ExportStream.h" +#include "Common/Platform/NMR_EncryptionHeader.h" + +namespace NMR { + + + + class CExportStream_Encrypted : public CExportStream { + PExportStream m_pEncryptedStream; + ContentEncryptionDescriptor m_pDecryptContext; + CEncryptionHeader m_header; + public: + CExportStream_Encrypted(PExportStream pEncryptedStream, ContentEncryptionDescriptor context); + + + // Inherited via CExportStream + virtual nfBool seekPosition(nfUint64 position, nfBool bHasToSucceed) override; + virtual nfBool seekForward(nfUint64 bytes, nfBool bHasToSucceed) override; + virtual nfBool seekFromEnd(nfUint64 bytes, nfBool bHasToSucceed) override; + virtual nfUint64 getPosition() override; + virtual nfUint64 writeBuffer(const void * pBuffer, nfUint64 cbTotalBytesToWrite) override; + + }; +} + + +#endif // !NMR_EXPORTSTREAM_ENCRYPTED + + diff --git a/Include/Common/Platform/NMR_ImportStream_Compressed.h b/Include/Common/Platform/NMR_ImportStream_Compressed.h new file mode 100644 index 000000000..7e535c07a --- /dev/null +++ b/Include/Common/Platform/NMR_ImportStream_Compressed.h @@ -0,0 +1,67 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ImportStream_Compressed.h defines the CImportStream_Compressed Class. +This is a stream class for importing from a compressed object. + +--*/ + +#ifndef __NMR_IMPORTSTREAM_COMPRESSED +#define __NMR_IMPORTSTREAM_COMPRESSED + +#include "Common/Platform/NMR_ImportStream.h" +#include "Libraries/zlib/zlib.h" + +#define IMPORTSTREAM_READ_BUFFER_CHUNKSIZE 1024 +#define IMPORTSTREAM_COMPRESSED_CHUNKSIZE 1024 + +namespace NMR { + + class CImportStream_Compressed : public CImportStream { + private: + PImportStream m_pCompressedStream; + z_stream m_strm; + std::vector m_decompressedBuffer; + nfByte in[IMPORTSTREAM_COMPRESSED_CHUNKSIZE]; + public: + CImportStream_Compressed(PImportStream pCompressedStream); + ~CImportStream_Compressed(); + + virtual nfBool seekPosition(_In_ nfUint64 position, _In_ nfBool bHasToSucceed); + virtual nfBool seekForward(_In_ nfUint64 bytes, _In_ nfBool bHasToSucceed); + virtual nfBool seekFromEnd(_In_ nfUint64 bytes, _In_ nfBool bHasToSucceed); + virtual nfUint64 readBuffer(nfByte * pBuffer, nfUint64 cbTotalBytesToRead, nfBool bNeedsToReadAll); + virtual nfUint64 retrieveSize(); + virtual void writeToFile(_In_ const nfWChar * pwszFileName); + virtual PImportStream copyToMemory(); + virtual nfUint64 getPosition(); + }; + +} + +#endif // __NMR_IMPORTSTREAM_COMPRESSED diff --git a/Include/Common/Platform/NMR_ImportStream_Encrypted.h b/Include/Common/Platform/NMR_ImportStream_Encrypted.h new file mode 100644 index 000000000..07c37f35f --- /dev/null +++ b/Include/Common/Platform/NMR_ImportStream_Encrypted.h @@ -0,0 +1,69 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ImportStream_Encrypted.h defines the CImportStream_Encrypted Class. +This is a stream class for importing encrypted resources from the underlying stream and handing them +to the proper callbacks that will decrypt the content before returning back to the consumer. + +--*/ + +#ifndef NMR_IMPORTSTREAM_ENCRYPTED +#define NMR_IMPORTSTREAM_ENCRYPTED + +#include "Common/NMR_Types.h" +#include "Common/NMR_SecureContentTypes.h" +#include "Common/Platform/NMR_ImportStream.h" +#include "Common/Platform/NMR_EncryptionHeader.h" + +#include + +namespace NMR { + + class CImportStream_Encrypted : public CImportStream { + PImportStream m_pEncryptedStream; + ContentEncryptionDescriptor m_pDecryptContext; + CEncryptionHeader m_header; + public: + CImportStream_Encrypted(PImportStream pEncryptedStream, ContentEncryptionDescriptor context); + + // Inherited via CImportStream + virtual nfBool seekPosition(nfUint64 position, nfBool bHasToSucceed) override; + virtual nfBool seekForward(nfUint64 bytes, nfBool bHasToSucceed) override; + virtual nfBool seekFromEnd(nfUint64 bytes, nfBool bHasToSucceed) override; + virtual nfUint64 readBuffer(nfByte * pBuffer, nfUint64 cbTotalBytesToRead, nfBool bNeedsToReadAll) override; + virtual nfUint64 retrieveSize() override; + virtual void writeToFile(const nfWChar * pwszFileName) override; + virtual PImportStream copyToMemory() override; + virtual nfUint64 getPosition() override; + }; +} + + +#endif // !NMR_IMPORTSTREAM_ENCRYPTED + + diff --git a/Include/Common/Platform/NMR_XmlWriter_Native.h b/Include/Common/Platform/NMR_XmlWriter_Native.h index 914009172..95284f307 100644 --- a/Include/Common/Platform/NMR_XmlWriter_Native.h +++ b/Include/Common/Platform/NMR_XmlWriter_Native.h @@ -37,6 +37,7 @@ NMR_XmlWriter_Native.h implements an XML Writer Class without dependencies. #include #include #include +#include #define NATIVEXMLSPACINGBUFFERSIZE 256 #define NATIVEXMLSPACING 9 diff --git a/Include/Libraries/cpp-base64/base64.h b/Include/Libraries/cpp-base64/base64.h new file mode 100644 index 000000000..e8442ea0c --- /dev/null +++ b/Include/Libraries/cpp-base64/base64.h @@ -0,0 +1,15 @@ +// +// base64 encoding and decoding with C++. +// Version: 1.01.00 +// + +#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A +#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A + +#include +#include + +std::string base64_encode(std::vector const & buffer); +std::vector base64_decode(std::string const& s); + +#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */ diff --git a/Include/Libraries/zlib/gzguts.h b/Include/Libraries/zlib/gzguts.h index d87659d03..28ba0b6a6 100644 --- a/Include/Libraries/zlib/gzguts.h +++ b/Include/Libraries/zlib/gzguts.h @@ -167,7 +167,7 @@ typedef struct { /* used for both reading and writing */ int mode; /* see gzip modes above */ int fd; /* file descriptor */ - char *path; /* path or fd for error messages */ + char *path; /* getPath or fd for error messages */ unsigned size; /* buffer size, zero if not allocated yet */ unsigned want; /* requested buffer size, default is GZBUFSIZE */ unsigned char *in; /* input buffer */ diff --git a/Include/Libraries/zlib/zlib.h b/Include/Libraries/zlib/zlib.h index 1028d89c5..06dc24a40 100644 --- a/Include/Libraries/zlib/zlib.h +++ b/Include/Libraries/zlib/zlib.h @@ -1224,7 +1224,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ /* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +ZEXTERN gzFile ZEXPORT gzopen OF((const char *getPath, const char *mode)); Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level ("wb9") or diff --git a/Include/Model/Classes/NMR_KeyStore.h b/Include/Model/Classes/NMR_KeyStore.h new file mode 100644 index 000000000..68049f96e --- /dev/null +++ b/Include/Model/Classes/NMR_KeyStore.h @@ -0,0 +1,107 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStore.h defines the KeyStore Class. A keystore is an in memory representation of the 3MF file keystore. + +--*/ + +#ifndef __NMR_KEYSTORE +#define __NMR_KEYSTORE + +#include +#include +#include +#include +#include "Common/NMR_Types.h" +#include "Common/NMR_SecureContentTypes.h" +#include "Common/NMR_UUID.h" + +namespace NMR { + class CKeyStoreConsumer; + using PKeyStoreConsumer = std::shared_ptr; + class CKeyStoreResourceDataGroup; + using PKeyStoreResourceDataGroup = std::shared_ptr; + class CKeyStoreResourceData; + using PKeyStoreResourceData = std::shared_ptr; + class CKeyStoreAccessRight; + using PKeyStoreAccessRight = std::shared_ptr; + + class CPackageModelPath; + using PPackageModelPath = std::shared_ptr; + + class CKeyStore { + private: + PUUID m_UUID; + + std::vector m_Consumers; + std::map m_ConsumerRefs; + + std::vector m_ResourceDataGroups; + std::map m_ResourceDataGroupsRefs; + + std::vector m_ResourceDatas; + std::map m_ResourceDataRefs; + + std::mutex mtx; + public: + CKeyStore(); + ~CKeyStore(); + PUUID getUUID(); + void setUUID(PUUID uuid); + void addConsumer(PKeyStoreConsumer const &consumer); + nfUint64 getConsumerCount() const; + PKeyStoreConsumer getConsumer(nfUint64 index) const; + PKeyStoreConsumer findConsumerById(std::string id); + void removeConsumer(NMR::PKeyStoreConsumer consumer); + + nfUint64 getResourceDataGroupCount() const; + PKeyStoreResourceDataGroup getResourceDataGroup(nfUint64 index) const; + void addResourceDataGroup(PKeyStoreResourceDataGroup const &dataGroup); + PKeyStoreResourceDataGroup findResourceDataGroupByResourceDataPath(PPackageModelPath const & rdPath); + void removeResourceDataGroup(PKeyStoreResourceDataGroup rdg); + + nfUint64 addResourceData(PKeyStoreResourceData const & rd); + void removeResourceData(NMR::PKeyStoreResourceData const & rd); + nfUint64 getResourceDataCount(); + PKeyStoreResourceData getResourceData(nfUint64 index) const; + PKeyStoreResourceData findResourceData(PPackageModelPath const & path); + + std::vector getResourceDataByGroup(PKeyStoreResourceDataGroup const & rdg) const; + + PKeyStoreResourceDataGroup findResourceDataGroupByResourceDataPath(std::string const & rdPath); + PKeyStoreResourceData findResourceData(std::string const & path); + + bool empty() const; + protected: + void clearAll(); + }; + + typedef std::shared_ptr PKeyStore; +} + +#endif diff --git a/Include/Model/Classes/NMR_KeyStoreAccessRight.h b/Include/Model/Classes/NMR_KeyStoreAccessRight.h new file mode 100644 index 000000000..d6edf2a6d --- /dev/null +++ b/Include/Model/Classes/NMR_KeyStoreAccessRight.h @@ -0,0 +1,61 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStoreAccessRight.h defines the KeyStoreAccessRight Class. A accessright is an in memory representation of the 3MF keystore resource data accessright. + +--*/ + +#ifndef __NMR_KEYSTOREACCESSRIGHT +#define __NMR_KEYSTOREACCESSRIGHT + +#include +#include +#include "Common/NMR_Types.h" +#include "Model/Classes/NMR_KeyStoreConsumer.h" +namespace NMR { + class CKeyStoreAccessRight { + private: + PKeyStoreConsumer m_pConsumer; + eKeyStoreWrapAlgorithm m_eAlgorithm; + eKeyStoreMaskGenerationFunction m_eMgf; + eKeyStoreMessageDigest m_eDigest; + std::vector m_rgCipherValue; + public: + CKeyStoreAccessRight(PKeyStoreConsumer const & consumer, eKeyStoreWrapAlgorithm const algorithm, eKeyStoreMaskGenerationFunction const mgf, eKeyStoreMessageDigest const digest, std::vector const & cipherValue); + PKeyStoreConsumer getConsumer() const; + eKeyStoreWrapAlgorithm getAlgorithm() const; + eKeyStoreMaskGenerationFunction getMgf() const; + eKeyStoreMessageDigest getDigest() const; + std::vector const & getCipherValue() const; + void setCipherValue(std::vector const & cv); + nfBool isNew() const; + }; + + typedef std::shared_ptr PKeyStoreAccessRight; +} +#endif diff --git a/Include/Model/Classes/NMR_KeyStoreCEKParams.h b/Include/Model/Classes/NMR_KeyStoreCEKParams.h new file mode 100644 index 000000000..becdeb0fb --- /dev/null +++ b/Include/Model/Classes/NMR_KeyStoreCEKParams.h @@ -0,0 +1,86 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStoreDecryptRight.h defines the KeyStoreDecryptRight Class. A decryptright is an in memory representation of the 3MF keystore resource data decrypright. + +--*/ + +#ifndef __NMR_KEYSTORECEKPARAMS +#define __NMR_KEYSTORECEKPARAMS + +#include +#include +#include +#include "Common/NMR_Types.h" +#include "Model/Classes/NMR_KeyStoreConsumer.h" +namespace NMR { + + class CKeyStoreCEKParams { + protected: + eKeyStoreEncryptAlgorithm m_eAlgorithm; + nfBool m_bCompression; + std::vector m_rgIv, m_rgTag, m_rgAad; + nfUint64 m_nDescriptor; + public: + CKeyStoreCEKParams(nfBool const & compression, + eKeyStoreEncryptAlgorithm const & encryptionAlgorithm, + std::vector const & iv, + std::vector const & tag, + std::vector const & aad, + nfUint64 descriptor); + + eKeyStoreEncryptAlgorithm getEncryptionAlgorithm() const; + nfBool isCompressed() const; + std::vector const & getInitVector() const; + std::vector const & getAuthTag() const; + std::vector const & getAddAuthData() const; + nfUint64 getDescriptor() const; + + void setAuthTag(std::vector const & buf); + void setAddAuthData(std::vector const & buf); + }; + + typedef std::shared_ptr PKeyStoreCEKParams; + + class CKeyStoreContentEncryptionParams: public CKeyStoreCEKParams { + std::vector m_rgKey; + public: + CKeyStoreContentEncryptionParams(nfBool const & compression, + eKeyStoreEncryptAlgorithm const & encryptionAlgorithm, + std::vector const & key, + std::vector const & iv, + std::vector const & tag, + std::vector const & aad, + nfUint64 descriptor); + + std::vector const & getKey() const; + }; + + typedef std::shared_ptr PCKeyStoreContentEncryptionParams; +} +#endif \ No newline at end of file diff --git a/Include/Model/Classes/NMR_KeyStoreConsumer.h b/Include/Model/Classes/NMR_KeyStoreConsumer.h new file mode 100644 index 000000000..577e7e8d6 --- /dev/null +++ b/Include/Model/Classes/NMR_KeyStoreConsumer.h @@ -0,0 +1,64 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStoreConsumer.h defines the KeyStore Consumer Class. A consumer is an in memory representation of the 3MF file KeyStore Consumer. + +--*/ + +#ifndef __NMR_KEYSTORECONSUMER +#define __NMR_KEYSTORECONSUMER + +#include +#include +#include +#include +#include "Common/NMR_Types.h" +#include "Common/NMR_SecureContentTypes.h" + +namespace NMR { + class CKeyStoreConsumer { + std::string m_sConsumerID; + std::string m_sKeyID; + std::string m_sKeyValue; + public: + CKeyStoreConsumer(std::string const & consumerID, std::string const & keyID, std::string keyValue); + + std::string getConsumerID() const; + + std::string getKeyID() const; + void setKeyID(std::string const & keyID); + nfBool hasKeyID() const; + + std::string getKeyValue() const; + void setKeyValue(std::string const & keyValue); + nfBool hasKeyValue() const; + }; + + typedef std::shared_ptr PKeyStoreConsumer; +} +#endif \ No newline at end of file diff --git a/Include/Model/Classes/NMR_KeyStoreFactory.h b/Include/Model/Classes/NMR_KeyStoreFactory.h new file mode 100644 index 000000000..b9979ff27 --- /dev/null +++ b/Include/Model/Classes/NMR_KeyStoreFactory.h @@ -0,0 +1,84 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStoreFactory.h defines the CKeyStoreFactory Class. It is responsible for creating logic of keystore entities. + +--*/ + +#ifndef __NMR_KEYSTOREFACTORY +#define __NMR_KEYSTOREFACTORY + +#include +#include +#include + +#include +#include "Common/NMR_SecureContentTypes.h" + + +namespace NMR { + + class CModel; + using PModel = std::shared_ptr; + class CKeyStore; + using PKeyStore = std::shared_ptr; + class CKeyStoreConsumer; + using PKeyStoreConsumer = std::shared_ptr; + class CKeyStoreResourceDataGroup; + using PKeyStoreResourceDataGroup = std::shared_ptr; + class CKeyStoreAccessRight; + using PKeyStoreAccessRight = std::shared_ptr; + class CKeyStoreResourceData; + using PKeyStoreResourceData = std::shared_ptr; + class CKeyStoreContentEncryptionParams; + using PKeyStoreContentEncryptionParams = std::shared_ptr; + class CKeyStoreCEKParams; + using PKeyStoreCEKParams = std::shared_ptr; + + class CUUID; + using PUUID = std::shared_ptr; + + class CPackageModelPath; + using PPackageModelPath = std::shared_ptr; + + class CKeyStoreFactory { + public: + static PKeyStore makeKeyStore(); + static PKeyStoreResourceDataGroup makeResourceDataGroup(PUUID const & keyUUID = nullptr, std::vector const & key = std::vector()); + static PKeyStoreConsumer makeConsumer(std::string const & consumerID, std::string const & keyId = std::string(), std::string const & keyValue = std::string()); + static PKeyStoreAccessRight makeAccessRight(PKeyStoreConsumer const & consumer, eKeyStoreWrapAlgorithm const algorithm, eKeyStoreMaskGenerationFunction const mask, eKeyStoreMessageDigest const digest, std::vector const & cipherValue = std::vector()); + static PKeyStoreResourceData makeResourceData(PKeyStoreResourceDataGroup const & rdg, PPackageModelPath const & path, PKeyStoreCEKParams params = nullptr); + static PKeyStoreContentEncryptionParams makeContentEncryptionParams(PKeyStoreResourceData rd, PKeyStoreResourceDataGroup rdg); + static PKeyStoreCEKParams makeCEKParams(nfBool compressed, eKeyStoreEncryptAlgorithm algorithm, std::vector const & aad, std::vector const & iv = std::vector(), std::vector const & tag = std::vector()); + }; +} + + +#endif // !__NMR_KEYSTOREFACTORY + + diff --git a/Include/Model/Classes/NMR_KeyStoreResourceData.h b/Include/Model/Classes/NMR_KeyStoreResourceData.h new file mode 100644 index 000000000..b4a481caf --- /dev/null +++ b/Include/Model/Classes/NMR_KeyStoreResourceData.h @@ -0,0 +1,76 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStoreResourceData.h defines the KeyStoreResourceData Class. A ResourceData is an in memory representation of the 3MF keystore resourcedata element. + +--*/ + +#ifndef __NMR_KEYSTORERESOURCEDATA +#define __NMR_KEYSTORERESOURCEDATA + +#include +#include +#include +#include "Common/NMR_Types.h" +#include "Common/NMR_SecureContentTypes.h" +#include "Model/Classes/NMR_PackageResourceID.h" +#include "Model/Classes/NMR_KeyStoreCEKParams.h" +namespace NMR { + + class CKeyStoreResourceDataGroup; + using PKeyStoreResourceDataGroup = std::shared_ptr; + + class CKeyStoreResourceData: public CKeyStoreCEKParams { + PKeyStoreResourceDataGroup m_pGroup; + PPackageModelPath m_pPath; + static nfUint64 s_nfHandleCount; + public: + CKeyStoreResourceData( + PKeyStoreResourceDataGroup const & rdg, + PPackageModelPath const & path, + bool compression, + eKeyStoreEncryptAlgorithm alg, + std::vector const & iv, + std::vector const & tag, + std::vector const & aad); + + inline PPackageModelPath packagePath() const { + return m_pPath; + } + + inline PKeyStoreResourceDataGroup const & getGroup() const { + return m_pGroup; + } + + void setInitVector(std::vector const &newIV); + void setAuthTag(std::vector const & newTag); + }; + typedef std::shared_ptr PKeyStoreResourceData; +} + +#endif diff --git a/Include/Model/Classes/NMR_KeyStoreResourceDataGroup.h b/Include/Model/Classes/NMR_KeyStoreResourceDataGroup.h new file mode 100644 index 000000000..90b535871 --- /dev/null +++ b/Include/Model/Classes/NMR_KeyStoreResourceDataGroup.h @@ -0,0 +1,77 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStoreResourceData.h defines the KeyStoreResourceData Class. A ResourceData is an in memory representation of the 3MF keystore resourcedata element. + +--*/ + +#ifndef __NMR_KEYSTORERESOURCEDATAGROUP +#define __NMR_KEYSTORERESOURCEDATAGROUP + +#include +#include +#include +#include + +#include "Common/NMR_Types.h" +#include "Common/NMR_SecureContentTypes.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_PackageResourceID.h" +#include "Common/NMR_UUID.h" + +namespace NMR { + + class CKeyStoreResourceDataGroup { + PUUID m_sKeyUUID; + std::vector m_AccessRights; + std::map m_ConsumerAccesstRight; + std::vector m_rgKey; + std::mutex mtx; + public: + CKeyStoreResourceDataGroup(PUUID const& keyUUID, std::vector const & key); + + PUUID getKeyUUID() const; + nfUint64 addAccessRight(PKeyStoreAccessRight const & ar); + void removeAccessRight(std::string const & consumerId); + nfUint64 getAccessRightCount(); + PKeyStoreAccessRight getAccessRight(nfUint64 index) const; + PKeyStoreAccessRight findAccessRightByConsumerID(std::string const & consumerId) const; + + std::vector const & getKey() const; + void setKey(std::vector const & key); + + inline nfBool isOpen() const { + return !m_rgKey.empty(); + } + }; + typedef std::shared_ptr PKeyStoreResourceDataGroup; +} + +#endif diff --git a/Include/Model/Classes/NMR_Model.h b/Include/Model/Classes/NMR_Model.h index d0f094e6c..ebb114608 100644 --- a/Include/Model/Classes/NMR_Model.h +++ b/Include/Model/Classes/NMR_Model.h @@ -48,6 +48,8 @@ NMR_Model.h defines the Model Class. A model is an in memory representation of t #include "Common/NMR_UUID.h" +#include "Common/NMR_SecureContentTypes.h" + namespace NMR { class CModelBuildItem; @@ -89,17 +91,22 @@ namespace NMR { class CModelSliceStack; typedef std::shared_ptr PModelSliceStack; - typedef std::map UniqueResourceIDMapping; + class CKeyStore; + typedef std::shared_ptr PKeyStore; + + typedef std::map UniqueResourceIDMapping; + // The Model class implements the unification of all model-file in a 3MF package + // It should be understood as a "MultiModel" class CModel { private: - std::string m_sCurPath; - std::string m_sRootPath; + PPackageModelPath m_pCurPath; + PPackageModelPath m_pPath; std::unordered_map usedUUIDs; // datastructure used to ensure that UUIDs within one model (package) are unique - // Object Resources of the model - std::map m_ResourceMap; + // map of all UniqueResourceIDs to actual object resources of the model + std::map m_ResourceMap; CResourceHandler m_resourceHandler; private: std::vector m_Resources; @@ -141,6 +148,11 @@ namespace NMR { std::vector m_CompositeMaterialsLookup; std::vector m_MultiPropertyGroupLookup; + // The KeyStore reference + PKeyStore m_pKeyStore; + + CryptoRandGenDescriptor m_sRandDescriptor; + // Add Resource to resource lookup tables void addResourceToLookupTable(_In_ PModelResource pResource); @@ -148,12 +160,17 @@ namespace NMR { CModel(); ~CModel(); - const std::string curPath(); - void setCurPath(const std::string sPath); + const std::string currentPath(); + PPackageModelPath currentModelPath(); + void setCurrentPath(const std::string sPath); + PPackageModelPath rootModelPath(); const std::string rootPath(); void setRootPath(const std::string sPath); + PPackageModelPath findOrCreateModelPath(std::string sPath); + std::vector retrieveAllModelPaths(); + // Merge all build items into one mesh void mergeToMesh(_In_ CMesh * pMesh); @@ -169,11 +186,11 @@ namespace NMR { // General Resource Handling PModelResource findResource(_In_ std::string path, ModelResourceID nID); - PModelResource findResource(_In_ PackageResourceID nID); + PModelResource findResource(_In_ UniqueResourceID nID); PModelResource findResource(_In_ PPackageResourceID pID); PPackageResourceID findPackageResourceID(_In_ std::string path, ModelResourceID nID); - PPackageResourceID findPackageResourceID(_In_ PackageResourceID nID); + PPackageResourceID findPackageResourceID(_In_ UniqueResourceID nID); nfUint32 getResourceCount(); PModelResource getResource(_In_ nfUint32 nIndex); @@ -207,53 +224,56 @@ namespace NMR { PModelAttachment getPackageThumbnail(); // Retrieve a unique Resource ID - PackageResourceID generateResourceID(); // unique per model + UniqueResourceID generateResourceID(); // unique per model + void updateUniqueResourceID(UniqueResourceID nOldID, UniqueResourceID nNewID); + PPackageResourceID generatePackageResourceID(_In_ std::string path, ModelResourceID nID); // unique per package + void removePackageResourceID(PPackageResourceID pID); // Convenience functions for objects - _Ret_maybenull_ CModelObject * findObject(_In_ PackageResourceID nResourceID); + _Ret_maybenull_ CModelObject * findObject(_In_ UniqueResourceID nResourceID); nfUint32 getObjectCount(); PModelResource getObjectResource(_In_ nfUint32 nIndex); nfInt32 compareObjectsByResourceID(CModelResource* pObjectResourceA, CModelResource* pObjectResourceB); CModelObject * getObject(_In_ nfUint32 nIndex); // Convenience functions for base materials - _Ret_maybenull_ PModelBaseMaterialResource findBaseMaterial(_In_ PackageResourceID nResourceID); + _Ret_maybenull_ PModelBaseMaterialResource findBaseMaterial(_In_ PPackageResourceID pID); nfUint32 getBaseMaterialCount(); PModelResource getBaseMaterialResource(_In_ nfUint32 nIndex); CModelBaseMaterialResource * getBaseMaterial(_In_ nfUint32 nIndex); void mergeBaseMaterials(_In_ CModel * pSourceModel, _In_ UniqueResourceIDMapping &oldToNewMapping); // Convenience functions for color groups - _Ret_maybenull_ PModelColorGroupResource findColorGroup(_In_ PackageResourceID nResourceID); + _Ret_maybenull_ PModelColorGroupResource findColorGroup(_In_ UniqueResourceID nResourceID); nfUint32 getColorGroupCount(); PModelResource getColorGroupResource(_In_ nfUint32 nIndex); CModelColorGroupResource * getColorGroup(_In_ nfUint32 nIndex); void mergeColorGroups(_In_ CModel * pSourceModel, _In_ UniqueResourceIDMapping &oldToNewMapping); // Convenience functions for texture2d groups - _Ret_maybenull_ PModelTexture2DGroupResource findTexture2DGroup(_In_ PackageResourceID nResourceID); + _Ret_maybenull_ PModelTexture2DGroupResource findTexture2DGroup(_In_ UniqueResourceID nResourceID); nfUint32 getTexture2DGroupCount(); PModelResource getTexture2DGroupResource(_In_ nfUint32 nIndex); CModelTexture2DGroupResource * getTexture2DGroup(_In_ nfUint32 nIndex); void mergeTexture2DGroups(_In_ CModel * pSourceModel, _In_ UniqueResourceIDMapping &oldToNewMapping); // Convenience functions for composite materials - _Ret_maybenull_ PModelCompositeMaterialsResource findCompositeMaterials(_In_ PackageResourceID nResourceID); + _Ret_maybenull_ PModelCompositeMaterialsResource findCompositeMaterials(_In_ UniqueResourceID nResourceID); nfUint32 getCompositeMaterialsCount(); PModelResource getCompositeMaterialsResource(_In_ nfUint32 nIndex); CModelCompositeMaterialsResource * getCompositeMaterials(_In_ nfUint32 nIndex); void mergeCompositeMaterials(_In_ CModel * pSourceModel, _In_ UniqueResourceIDMapping &oldToNewMapping); // Convenience functions for multi property groups - _Ret_maybenull_ PModelMultiPropertyGroupResource findMultiPropertyGroup(_In_ PackageResourceID nResourceID); + _Ret_maybenull_ PModelMultiPropertyGroupResource findMultiPropertyGroup(_In_ UniqueResourceID nResourceID); nfUint32 getMultiPropertyGroupCount(); PModelResource getMultiPropertyGroupResource(_In_ nfUint32 nIndex); CModelMultiPropertyGroupResource * getMultiPropertyGroup(_In_ nfUint32 nIndex); void mergeMultiPropertyGroups(_In_ CModel * pSourceModel, _In_ UniqueResourceIDMapping &oldToNewMapping); // Convenience functions for 2D Textures - _Ret_maybenull_ PModelTexture2DResource findTexture2D(_In_ PackageResourceID nResourceID); + _Ret_maybenull_ PModelTexture2DResource findTexture2D(_In_ UniqueResourceID nResourceID); nfUint32 getTexture2DCount(); PModelResource getTexture2DResource(_In_ nfUint32 nIndex); CModelTexture2DResource * getTexture2D(_In_ nfUint32 nIndex); @@ -297,6 +317,16 @@ namespace NMR { // Sorts objects by correct dependency std::list getSortedObjectList (); + + + // Gets the KeyStore + PKeyStore getKeyStore(); + void setKeyStore(PKeyStore keyStore); + + void setCryptoRandCallback(CryptoRandGenDescriptor const & randDescriptor); + nfBool hasCryptoRandCallbak() const; + nfUint64 generateRandomBytes(nfByte *, nfUint64); + }; typedef std::shared_ptr PModel; diff --git a/Include/Model/Classes/NMR_ModelBuildItem.h b/Include/Model/Classes/NMR_ModelBuildItem.h index cf59f985a..79e8e4eba 100644 --- a/Include/Model/Classes/NMR_ModelBuildItem.h +++ b/Include/Model/Classes/NMR_ModelBuildItem.h @@ -73,9 +73,6 @@ namespace NMR { nfBool hasTransform(); std::string getTransformString(); - // Associated object getter/setter - PackageResourceID getObjectID(); - // Item reference getter/setter std::string getPartNumber(); void setPartNumber(_In_ std::string sPartNumber); diff --git a/Include/Model/Classes/NMR_ModelComponent.h b/Include/Model/Classes/NMR_ModelComponent.h index 87f154738..b0c7c839f 100644 --- a/Include/Model/Classes/NMR_ModelComponent.h +++ b/Include/Model/Classes/NMR_ModelComponent.h @@ -47,7 +47,6 @@ namespace NMR { NMATRIX3 m_mTransform; PUUID m_UUID; - std::wstring m_sPath; public: CModelComponent() = delete; CModelComponent(_In_ CModelObject * pObject); @@ -60,7 +59,6 @@ namespace NMR { NMATRIX3 getTransform (); void setTransform(_In_ const NMATRIX3 mTransform); - PackageResourceID getObjectID(); nfBool hasTransform(); std::string getTransformString(); diff --git a/Include/Model/Classes/NMR_ModelConstants.h b/Include/Model/Classes/NMR_ModelConstants.h index eb466f4a0..21191891b 100644 --- a/Include/Model/Classes/NMR_ModelConstants.h +++ b/Include/Model/Classes/NMR_ModelConstants.h @@ -39,6 +39,7 @@ These are given by the 3MF Standard #define PACKAGE_TEXTURE_CONTENT_TYPE "application/vnd.ms-package.3dmanufacturing-3dmodeltexture" #define PACKAGE_PRINT_TICKET_CONTENT_TYPE "application/vnd.ms-printing.printticket+xml" #define PACKAGE_CORE_PROPERTIES_CONTENT_TYPE "application/vnd.openxmlformats-package.core-properties+xml" +#define PACKAGE_KEYSTORE_CONTENT_TYPE "application/vnd.ms-package.3dmanufacturing-keystore+xml" #define PACKAGE_GIF_CONTENT_TYPE "image/gif" #define PACKAGE_JPG_CONTENT_TYPE "image/jpeg" #define PACKAGE_PNG_CONTENT_TYPE "image/png" @@ -56,6 +57,8 @@ These are given by the 3MF Standard #define PACKAGE_CORE_PROPERTIES_URI "/Metadata/CoreProperties.prop" #define PACKAGE_THUMBNAIL_URI_BASE "/Metadata" +#define PACKAGE_3D_KEYSTORE_URI "/Secure/keystore.xml" + #define NMR_MAXHANDLE 0xfffffffe #define PACKAGE_XMLNS_093 "http://schemas.microsoft.com/3dmanufacturing/2013/01" @@ -66,6 +69,9 @@ These are given by the 3MF Standard #define PACKAGE_TEXTURE_RELATIONSHIP_TYPE "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture" #define PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" #define PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail" +#define PACKAGE_MUST_PRESERVE_RELATIONSHIP_TYPE "http://schemas.openxmlformats.org/package/2006/relationships/mustpreserve" +#define PACKAGE_KEYSTORE_RELATIONSHIP_TYPE "http://schemas.microsoft.com/3dmanufacturing/2019/04/keystore" +#define PACKAGE_ENCRYPTED_FILE_RELATIONSHIP "http://schemas.openxmlformats.org/package/2006/relationships/encryptedfile" #define XML_3MF_NAMESPACE_XML "http://www.w3.org/XML/1998/namespace" #define XML_3MF_NAMESPACE_XMLNS "http://www.w3.org/2000/xmlns/" @@ -75,11 +81,15 @@ These are given by the 3MF Standard #define XML_3MF_NAMESPACE_PRODUCTIONSPEC "http://schemas.microsoft.com/3dmanufacturing/production/2015/06" #define XML_3MF_NAMESPACE_BEAMLATTICESPEC "http://schemas.microsoft.com/3dmanufacturing/beamlattice/2017/02" #define XML_3MF_NAMESPACE_SLICESPEC "http://schemas.microsoft.com/3dmanufacturing/slice/2015/07" +#define XML_3MF_NAMESPACE_SECURECONTENTSPEC "http://schemas.microsoft.com/3dmanufacturing/securecontent/2019/04" +#define XML_3MF_NAMESPACE_DIGITALSIGNATURESPEC "http://www.w3.org/2000/09/xmldsig#" +#define XML_3MF_NAMESPACE_CIPHERVALUESPEC "http://www.w3.org/2001/04/xmlenc#" #define XML_3MF_NAMESPACEPREFIX_MATERIAL "m" #define XML_3MF_NAMESPACEPREFIX_PRODUCTION "p" #define XML_3MF_NAMESPACEPREFIX_BEAMLATTICE "b" #define XML_3MF_NAMESPACEPREFIX_SLICE "s" +#define XML_3MF_NAMESPACEPREFIX_SECURECONTENT "sc" #define XML_3MF_ATTRIBUTE_XMLNS "xmlns" #define XML_3MF_ATTRIBUTE_PREFIX_XML "xml" @@ -128,9 +138,12 @@ These are given by the 3MF Standard #define XML_3MF_ELEMENT_BEAMLATTICE "beamlattice" #define XML_3MF_ELEMENT_BEAMS "beams" #define XML_3MF_ELEMENT_BEAM "beam" +#define XML_3MF_ELEMENT_BALLS "balls" +#define XML_3MF_ELEMENT_BALL "ball" #define XML_3MF_ELEMENT_BEAMSETS "beamsets" #define XML_3MF_ELEMENT_BEAMSET "beamset" #define XML_3MF_ELEMENT_REF "ref" +#define XML_3MF_ELEMENT_BALLREF "ballref" // Triangle element. #define XML_3MF_ELEMENT_TRIANGLE "triangle" @@ -161,6 +174,10 @@ These are given by the 3MF Standard #define XML_3MF_ATTRIBUTE_BEAMLATTICE_CAPMODE "cap" #define XML_3MF_ATTRIBUTE_BEAMLATTICE_CAP1 "cap1" #define XML_3MF_ATTRIBUTE_BEAMLATTICE_CAP2 "cap2" +#define XML_3MF_ATTRIBUTE_BEAMLATTICE_BALLMODE "ballmode" +#define XML_3MF_ATTRIBUTE_BEAMLATTICE_BALLRADIUS "ballradius" +#define XML_3MF_ATTRIBUTE_BEAMLATTICE_BALL_VINDEX "vindex" +#define XML_3MF_ATTRIBUTE_BEAMLATTICE_BALL_R "r" #define XML_3MF_ATTRIBUTE_BEAMLATTICE_INDEX "index" #define XML_3MF_ATTRIBUTE_BEAMLATTICETAG_TAG "tag" // deprecated (has been used in draft version of the specification): @@ -299,7 +316,6 @@ These are given by the 3MF Standard #define XML_3MF_ATTRIBUTE_COLOR_ID "id" #define XML_3MF_ATTRIBUTE_COLOR_VALUE "value" - // Base Material element. #define XML_3MF_ELEMENT_BASEMATERIALS "basematerials" #define XML_3MF_ELEMENT_BASE "base" @@ -336,6 +352,59 @@ These are given by the 3MF Standard // depricated (from a draft version of the spec): #define XML_3MF_BEAMLATTICE_CAPMODE_ROUND "round" +#define XML_3MF_BEAMLATTICE_BALLMODE_NONE "none" +#define XML_3MF_BEAMLATTICE_BALLMODE_MIXED "mixed" +#define XML_3MF_BEAMLATTICE_BALLMODE_ALL "all" + +// KeyStore element. +#define XML_3MF_ELEMENT_KEYSTORE "keystore" +#define XML_3MF_ELEMENT_CONSUMER "consumer" +#define XML_3MF_ELEMENT_RESOURCEDATA "resourcedata" +#define XML_3MF_ELEMENT_RESOURCEDATAGROUP "resourcedatagroup" +#define XML_3MF_ELEMENT_KEYVALUE "keyvalue" +#define XML_3MF_ELEMENT_CIPHERDATA "cipherdata" +#define XML_3MF_ELEMENT_CIPHERVALUE "CipherValue" +#define XML_3MF_ELEMENT_KEKPARAMS "kekparams" +#define XML_3MF_ELEMENT_CEKPARAMS "cekparams" +#define XML_3MF_ELEMENT_ACCESSRIGHT "accessright" +#define XML_3MF_SECURE_CONTENT_UUID "UUID" +#define XML_3MF_SECURE_CONTENT_CONSUMER_ID "consumerid" +#define XML_3MF_SECURE_CONTENT_KEY_ID "keyid" +#define XML_3MF_SECURE_CONTENT_KEY_UUID "keyuuid" +#define XML_3MF_SECURE_CONTENT_PATH "path" +#define XML_3MF_SECURE_CONTENT_ENCRYPTION_ALGORITHM "encryptionalgorithm" +#define XML_3MF_SECURE_CONTENT_COMPRESSION "compression" +#define XML_3MF_SECURE_CONTENT_COMPRESSION_DEFLATE "deflate" +#define XML_3MF_SECURE_CONTENT_COMPRESSION_NONE "none" +#define XML_3MF_SECURE_CONTENT_CONSUMER_INDEX "consumerindex" +#define XML_3MF_SECURE_CONTENT_ALGORITHM "Algorithm" +#define XML_3MF_SECURE_CONTENT_WRAPPINGALGORITHM "wrappingalgorithm" +#define XML_3MF_SECURE_CONTENT_MGFALGORITHM "mgfalgorithm" +#define XML_3MF_SECURE_CONTENT_DIGESTMETHOD "digestmethod" +#define XML_3MF_SECURE_CONTENT_IV "iv" +#define XML_3MF_SECURE_CONTENT_TAG "tag" +#define XML_3MF_SECURE_CONTENT_AAD "aad" +#define XML_3MF_SECURE_CONTENT_KEY_UUID "keyuuid" + +#define XML_3MF_SECURE_CONTENT_ENCRYPTION_AES256 "http://www.w3.org/2009/xmlenc11#aes256-gcm" +#define XML_3MF_SECURE_CONTENT_KEYWRAPPING_RSA "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" +#define XML_3MF_SECURE_CONTENT_KEYWRAPPING_RSASHORT "http://www.w3.org/2009/xmlenc11#rsa-oaep" + +#define XML_3MF_SECURE_CONTENT_MGF1_SHA1 "http://www.w3.org/2009/xmlenc11#mgf1sha1" +#define XML_3MF_SECURE_CONTENT_MGF1_SHA224 "http://www.w3.org/2009/xmlenc11#mgf1sha224" +#define XML_3MF_SECURE_CONTENT_MGF1_SHA256 "http://www.w3.org/2009/xmlenc11#mgf1sha256" +#define XML_3MF_SECURE_CONTENT_MGF1_SHA384 "http://www.w3.org/2009/xmlenc11#mgf1sha384" +#define XML_3MF_SECURE_CONTENT_MGF1_SHA512 "http://www.w3.org/2009/xmlenc11#mgf1sha512" + +#define XML_3MF_SECURE_CONTENT_MD_SHA1 "http://www.w3.org/2000/09/xmldsig#sha1" +#define XML_3MF_SECURE_CONTENT_MD_SHA256 "http://www.w3.org/2001/04/xmlenc#sha256" +#define XML_3MF_SECURE_CONTENT_MD_SHA384 "http://www.w3.org/2001/04/xmlenc#sha384" +#define XML_3MF_SECURE_CONTENT_MD_SHA512 "http://www.w3.org/2001/04/xmlenc#sha512" + +#define XML_3MF_SECURE_CONTENT_MAXELEMENTCOUNT 2147483647 + +#define XML_3MF_NAMESPACEPREFIX_DS "ds" +#define XML_3MF_NAMESPACEPREFIX_XENC "xenc" #define XML_3MF_PRODUCTION_PATH "path" #define XML_3MF_PRODUCTION_UUID "UUID" @@ -350,7 +419,9 @@ These are given by the 3MF Standard #define XML_3MF_MAXBUILDITEMCOUNT 2147483647 #define XML_3MF_MAXRESOURCECOUNT 2147483647 #define XML_3MF_MAXIMUMBEAMRADIUSVALUE 1000000000.0f +#define XML_3MF_MAXIMUMBALLRADIUSVALUE 1000000000.0f #define XML_3MF_MAXIMUMSKINTHICKNESSVALUE 1000000000.0f #define XML_3MF_MAXBEAMCOUNT 2147483647 +#define XML_3MF_MAXBALLCOUNT 2147483647 #endif // __NMR_MODELCONSTANTS diff --git a/Include/Model/Classes/NMR_ModelContext.h b/Include/Model/Classes/NMR_ModelContext.h new file mode 100644 index 000000000..4e584c50c --- /dev/null +++ b/Include/Model/Classes/NMR_ModelContext.h @@ -0,0 +1,94 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +--*/ + +#ifndef NMR_MODELCONTEXT +#define NMR_MODELCONTEXT + +#include + +#include "Common/NMR_Types.h" +#include "Common/NMR_Local.h" +#include "Common/3MF_ProgressTypes.h" + +namespace NMR { + + class CModel; + class CKeyStore; + class CSecureContext; + class CProgressMonitor; + class CModelWarnings; + + using PModel = std::shared_ptr; + using PKeyStore = std::shared_ptr; + using PSecureContext = std::shared_ptr; + using PProgressMonitor = std::shared_ptr; + using PModelWarnings = std::shared_ptr; + + class CModelContext { + private: + PModel m_pModel; + PSecureContext m_pSecureContext; + PProgressMonitor m_pProgressMonitor; + PModelWarnings m_pWarnings; + PKeyStore m_pKeystore; + + protected: + + + public: + CModelContext() = delete; + CModelContext(_In_ PModel pModel); + virtual ~CModelContext() = default; + + inline PModel const & model() const{ + return m_pModel; + } + inline PProgressMonitor const & monitor() const{ + return m_pProgressMonitor; + } + + inline PModelWarnings const & warnings() const{ + return m_pWarnings; + } + + inline PKeyStore const & keyStore() const{ + return m_pKeystore; + } + + inline PSecureContext const & secureContext() const{ + return m_pSecureContext; + } + + nfBool isComplete() const; + + void SetProgressCallback(Lib3MFProgressCallback callback, void* userData); + }; +} +#endif // !NMR_MODELCONTEXT + diff --git a/Include/Model/Classes/NMR_ModelMeshBeamLatticeAttributes.h b/Include/Model/Classes/NMR_ModelMeshBeamLatticeAttributes.h index aec33282a..afdd18cb6 100644 --- a/Include/Model/Classes/NMR_ModelMeshBeamLatticeAttributes.h +++ b/Include/Model/Classes/NMR_ModelMeshBeamLatticeAttributes.h @@ -46,9 +46,10 @@ namespace NMR { public: eModelBeamLatticeClipMode m_eClipMode; nfBool m_bHasClippingMeshID; - PPackageResourceID m_nClippingMeshID; + PPackageResourceID m_pClippingMeshUniqueID; nfBool m_bHasRepresentationMeshID; - PPackageResourceID m_nRepresentationID; + PPackageResourceID m_pRepresentationUniqueID; + eModelBeamLatticeBallMode m_eBallMode; CModelMeshBeamLatticeAttributes(); virtual ~CModelMeshBeamLatticeAttributes(); diff --git a/Include/Model/Classes/NMR_ModelMetaData.h b/Include/Model/Classes/NMR_ModelMetaData.h index 0dcb7ace8..4f529662e 100644 --- a/Include/Model/Classes/NMR_ModelMetaData.h +++ b/Include/Model/Classes/NMR_ModelMetaData.h @@ -35,7 +35,7 @@ metadata, and can be attached to any 3MF model node. #ifndef __NMR_MODELMETADATA #define __NMR_MODELMETADATA -#include "Common/NMR_Types.h" +#include "Common/NMR_Types.h" #include "Common/Platform/NMR_SAL.h" #include #include @@ -69,9 +69,7 @@ namespace NMR { std::string getKey(); - static void decomposeKeyIntoNamespaceAndName(const std::string &sKey, std::string &sNameSpace, std::string &sName); static bool isValidNamespaceAndName(std::string sNameSpace, std::string sName); - static std::string calculateKey(const std::string &sNameSpace, const std::string &sName); }; typedef std::shared_ptr PModelMetaData; diff --git a/Include/Model/Classes/NMR_ModelResource.h b/Include/Model/Classes/NMR_ModelResource.h index b734e09ad..95eef8ebf 100644 --- a/Include/Model/Classes/NMR_ModelResource.h +++ b/Include/Model/Classes/NMR_ModelResource.h @@ -47,7 +47,7 @@ namespace NMR { class CModelResource { private: CModel * m_pModel; - PPackageResourceID m_sResourceID; + PPackageResourceID m_pPackageResourceID; protected: std::vector m_ResourceIndexMap; @@ -60,7 +60,8 @@ namespace NMR { CModelResource(_In_ const ModelResourceID sResourceID, _In_ CModel * pModel); virtual ~CModelResource(); - virtual PPackageResourceID getResourceID(); + virtual PPackageResourceID getPackageResourceID(); + void setPackageResourceID(PPackageResourceID pID); bool mapResourceIndexToPropertyID (_In_ ModelResourceIndex nPropertyIndex, _Out_ ModelPropertyID & nPropertyID); void clearResourceIndexMap(); diff --git a/Include/Model/Classes/NMR_ModelSliceStack.h b/Include/Model/Classes/NMR_ModelSliceStack.h index 18061b103..6ea3d1a48 100644 --- a/Include/Model/Classes/NMR_ModelSliceStack.h +++ b/Include/Model/Classes/NMR_ModelSliceStack.h @@ -47,7 +47,6 @@ namespace NMR { class CModelSliceStack : public CModelResource { private: nfDouble m_dZBottom; - std::string m_sOwnPath; std::vector m_pSliceRefs; std::vector m_pSlices; diff --git a/Include/Model/Classes/NMR_ModelTexture2D.h b/Include/Model/Classes/NMR_ModelTexture2D.h index 6bb863ae4..1cae97bd0 100644 --- a/Include/Model/Classes/NMR_ModelTexture2D.h +++ b/Include/Model/Classes/NMR_ModelTexture2D.h @@ -101,7 +101,7 @@ namespace NMR { void setFilter(_In_ eModelTextureFilter eFilter); // copy all parameters from source - void copyFrom(_In_ CModelTexture2DResource * pSourceTexture); + void copyFrom(_In_ CModelTexture2DResource * pSourceTexture, _In_ nfBool bCopyAttachment); static eModelTextureTileStyle tileStyleFromString(_In_ std::string sValue); static std::string tileStyleToString(_In_ eModelTextureTileStyle eTileStyle); diff --git a/Include/Model/Classes/NMR_ModelTypes.h b/Include/Model/Classes/NMR_ModelTypes.h index a8b64121e..a63ea066d 100644 --- a/Include/Model/Classes/NMR_ModelTypes.h +++ b/Include/Model/Classes/NMR_ModelTypes.h @@ -71,6 +71,13 @@ namespace NMR { MODELBEAMLATTICECAPMODE_HEMISPHERE = 1, MODELBEAMLATTICECAPMODE_BUTT = 2 }; + + enum eModelBeamLatticeBallMode { + MODELBEAMLATTICEBALLMODE_NONE = 0, + MODELBEAMLATTICEBALLMODE_MIXED = 1, + MODELBEAMLATTICEBALLMODE_ALL = 2 + }; + typedef struct MODELMESHBEAM { DWORD m_nIndices[2]; DOUBLE m_dRadius[2]; // the radius of end 0 or 1 of this beam @@ -81,6 +88,13 @@ namespace NMR { } } MODELMESHBEAM; + typedef struct MODELMESHBALL { + DWORD m_nIndex; + DOUBLE m_dRadius; // the radius of this ball + MODELMESHBALL() { + } + } MODELMESHBALL; + typedef struct { FLOAT m_fFields[3][4]; } MODELTRANSFORM; @@ -111,7 +125,7 @@ namespace NMR { typedef DWORD ModelPropertyID; typedef DWORD ModelResourceID; - typedef DWORD PackageResourceID; + typedef DWORD UniqueResourceID; typedef DWORD ModelResourceIndex; enum eModelUnit { @@ -174,7 +188,7 @@ namespace NMR { } MODELCOMPOSITECONSTITUENT; typedef struct { - ModelResourceID m_nResourceID; + UniqueResourceID m_nUniqueResourceID; eModelBlendMethod m_nMethod; } MODELMULTIPROPERTYLAYER; diff --git a/Include/Model/Classes/NMR_PackageResourceID.h b/Include/Model/Classes/NMR_PackageResourceID.h index 80e61b94b..78dfe4260 100644 --- a/Include/Model/Classes/NMR_PackageResourceID.h +++ b/Include/Model/Classes/NMR_PackageResourceID.h @@ -26,7 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Abstract: -NMR_PackageResourceID.h defines the PackageResourceID Class. +NMR_PackageResourceID.h defines the UniqueResourceID Class. --*/ @@ -43,35 +43,78 @@ NMR_PackageResourceID.h defines the PackageResourceID Class. namespace NMR { - class CPackageResourceID { + class CResourceHandler; + + + class CPackageModelPath { private: - std::string m_path; - ModelResourceID m_id; // combination of those two must be unique + CResourceHandler* m_pResourceHandler; + std::string m_sPath; - PackageResourceID m_uniqueID; // the unique Identifier + public: + CPackageModelPath(CResourceHandler* pResourceHandler, std::string sPath); friend class CResourceHandler; - void setPathAndId(std::string p, ModelResourceID id); - void setUniqueID(PackageResourceID id); + std::string getPath(); + void setPath(std::string sPath); + }; + typedef std::shared_ptr PPackageModelPath; + + + class CPackageResourceID { + private: + CResourceHandler* m_pResourceHandler; + // combination of those two must be unique + PPackageModelPath m_pModelPath; + ModelResourceID m_id; + + // the unique Identifier that MUST not be persistent into a .3mf-file. + // it is only valid thoughout the lifetime of a NMR::CModel + UniqueResourceID m_uniqueID; + + void setUniqueID(UniqueResourceID id); + public: - void get(std::string& p); - void get(ModelResourceID& id); - PackageResourceID getUniqueID(); + CPackageResourceID(CResourceHandler* pResourceHandler, PPackageModelPath pModelPath, ModelResourceID nID); + + friend class CResourceHandler; + + std::string getPath(); + PPackageModelPath getPackageModelPath(); + ModelResourceID getModelResourceID(); + UniqueResourceID getUniqueID(); + + static void setModelPath(std::shared_ptr pPackageResourceID, PPackageModelPath pPath); + CResourceHandler * getResourceHandler(); }; typedef std::shared_ptr PPackageResourceID; + + using UniqueIDPackageIdMap = std::unordered_map; + using UniqueIdPackageIdPair = std::pair; + class CResourceHandler { private: + // getPath-strings to ModelPaths + std::unordered_map m_PathToModelPath; + // unique IDs to CPackageResourceID - std::unordered_map m_resourceIDs; - std::map, PPackageResourceID> m_IdAndPathToResourceIDs; + UniqueIDPackageIdMap m_resourceIDs; + std::map, PPackageResourceID> m_IdAndPathToPackageResourceIDs; public: - PPackageResourceID getNewResourceID(std::string path, ModelResourceID id); // this is supposed to be the only way to generate a CPackageResourceID - PPackageResourceID findResourceID(PackageResourceID id); - PPackageResourceID findResourceID(std::string path, ModelResourceID id); + PPackageResourceID makePackageResourceID(std::string path, ModelResourceID id); // this is supposed to be the only way to generate a CPackageResourceID + + PPackageResourceID findResourceIDByUniqueID(UniqueResourceID id); + PPackageResourceID findResourceIDByPair(std::string path, ModelResourceID id); + + PPackageModelPath findPackageModelPath(std::string sPath); + PPackageModelPath makePackageModelPath(std::string sPath); + + void updateModelPath(PPackageResourceID pPackageResourceID, PPackageModelPath pNewPath); + std::vector retrieveAllModelPaths(); - void FlattenIDs(); + void removePackageResourceID(PPackageResourceID pPackageResourceID); void clear(); }; diff --git a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ball.h b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ball.h new file mode 100644 index 000000000..ec2b9f1b6 --- /dev/null +++ b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ball.h @@ -0,0 +1,67 @@ +/*++ + +Copyright (C) 2020 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: +NMR_ModelReaderNode_BeamLattice1702_Ball.h covers the official 3MF beamlattice extension. + +--*/ + +#ifndef __NMR_MODELREADERNODE_BEAMLATTICE1702_BALL +#define __NMR_MODELREADERNODE_BEAMLATTICE1702_BALL + +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_ModelComponent.h" +#include "Model/Classes/NMR_ModelComponentsObject.h" +#include "Model/Classes/NMR_ModelObject.h" + +namespace NMR { + eModelBeamLatticeBallMode stringToBallMode(const nfChar * ballModeStr); + + class CModelReaderNode_BeamLattice1702_Ball : public CModelReaderNode { + private: + nfInt32 m_nIndex; + nfBool m_bHasRadius; + nfDouble m_dRadius; + nfBool m_bHasTag; + nfInt32 m_nTag; + protected: + virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); + virtual void OnNSAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue, _In_z_ const nfChar * pNameSpace); + public: + CModelReaderNode_BeamLattice1702_Ball() = delete; + CModelReaderNode_BeamLattice1702_Ball(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + + void retrieveIndex(_Out_ nfInt32 & nIndex, nfInt32 nNodeCount); + void retrieveRadius(_Out_ nfBool & bHasRadius, _Out_ nfDouble & dRadius); + void retrieveTag(_Out_ nfBool & bHasTag, _Out_ nfInt32 & tag); + }; + + typedef std::shared_ptr PModelReaderNode_BeamLattice1702_Ball; +} + +#endif // __NMR_MODELREADERNODE_BEAMLATTICE1702_BALL \ No newline at end of file diff --git a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BallRef.h b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BallRef.h new file mode 100644 index 000000000..fab2b2c81 --- /dev/null +++ b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BallRef.h @@ -0,0 +1,59 @@ +/*++ + +Copyright (C) 2020 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: +NMR_ModelReaderNode_BeamLattice1702_BallRef.h covers the official 3MF beamlattice extension. + +--*/ + +#ifndef __NMR_MODELREADERNODE_BEAMLATTICE1702_BALLREF +#define __NMR_MODELREADERNODE_BEAMLATTICE1702_BALLREF + +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_ModelComponent.h" +#include "Model/Classes/NMR_ModelComponentsObject.h" +#include "Model/Classes/NMR_ModelObject.h" + +namespace NMR { + + class CModelReaderNode_BeamLattice1702_BallRef : public CModelReaderNode { + private: + nfInt32 m_nIndex; + protected: + virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); + public: + CModelReaderNode_BeamLattice1702_BallRef() = delete; + CModelReaderNode_BeamLattice1702_BallRef(_In_ PModelWarnings pWarnings); + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + void retrieveIndex(_Out_ nfInt32 & nIndex); + }; + + typedef std::shared_ptr PModelReaderNode_BeamLattice1702_BallRef; + +} + +#endif // __NMR_MODELREADERNODE_BEAMLATTICE1702_BALLREF diff --git a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Balls.h b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Balls.h new file mode 100644 index 000000000..6ccc6645f --- /dev/null +++ b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Balls.h @@ -0,0 +1,61 @@ +/*++ + +Copyright (C) 2020 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_BeamLattice1702_Balls.h covers the official 3MF beamlattice extension. + +--*/ + +#ifndef __NMR_MODELREADERNODE_BEAMLATTICE1702_BALLS +#define __NMR_MODELREADERNODE_BEAMLATTICE1702_BALLS + +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_ModelComponent.h" +#include "Model/Classes/NMR_ModelObject.h" + +namespace NMR { + + class CModelReaderNode_BeamLattice1702_Balls : public CModelReaderNode { + protected: + CMesh* m_pMesh; + CModel* m_pModel; + + nfDouble m_dDefaultBallRadius; + + virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); + virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); + public: + CModelReaderNode_BeamLattice1702_Balls() = delete; + CModelReaderNode_BeamLattice1702_Balls(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ nfDouble defaultBallRadius, _In_ PModelWarnings pWarnings); + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + }; + + typedef std::shared_ptr PModelReaderNode_BeamLattice1702_Balls; +} + +#endif // __NMR_MODELREADERNODE_BEAMLATTICE1702_BALLS \ No newline at end of file diff --git a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beam.h b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beam.h index b5650e0a0..35aa1813a 100644 --- a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beam.h +++ b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beam.h @@ -60,7 +60,7 @@ namespace NMR { virtual void OnNSAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue, _In_z_ const nfChar * pNameSpace); public: CModelReaderNode_BeamLattice1702_Beam() = delete; - CModelReaderNode_BeamLattice1702_Beam(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode_BeamLattice1702_Beam(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamLattice.h b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamLattice.h index f4a5ae6e4..f909ed3d9 100644 --- a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamLattice.h +++ b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamLattice.h @@ -45,7 +45,6 @@ namespace NMR { private: CModel * m_pModel; CMesh * m_pMesh; - PModelReaderWarnings m_pWarnings; eModelBeamLatticeClipMode m_eClipMode; nfBool m_bHasClippingMeshID; @@ -54,16 +53,18 @@ namespace NMR { ModelResourceID m_nRepresentationMeshID; nfDouble m_dDefaultRadius; eModelBeamLatticeCapMode m_eDefaultCapMode; + nfDouble m_dDefaultBallRadius; protected: virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); virtual void OnNSAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue, _In_z_ const nfChar * pNameSpace); virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode_BeamLattice1702_BeamLattice() = delete; - CModelReaderNode_BeamLattice1702_BeamLattice(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode_BeamLattice1702_BeamLattice(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelWarnings pWarnings); void retrieveClippingInfo(_Out_ eModelBeamLatticeClipMode &eClipMode, _Out_ nfBool & bHasClippingMode, _Out_ ModelResourceID & nClippingMeshID); void retrieveRepresentationInfo(_Out_ nfBool & bHasRepresentation, _Out_ ModelResourceID & nRepresentationMeshID); + void validateBallOptions(_In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSet.h b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSet.h index df56cce93..14cd3f99a 100644 --- a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSet.h +++ b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSet.h @@ -37,18 +37,22 @@ NMR_ModelReaderNode_BeamLattice1702_BeamSet.h covers the official 3MF beamlattic #include "Model/Classes/NMR_ModelComponentsObject.h" #include "Model/Classes/NMR_ModelObject.h" +#include + namespace NMR { class CModelReaderNode_BeamLattice1702_BeamSet : public CModelReaderNode { private: BEAMSET * m_pBeamSet; + + std::unordered_set * m_pUniqueIdentifiers; protected: virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); virtual void OnNSAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue, _In_z_ const nfChar * pNameSpace); virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode_BeamLattice1702_BeamSet() = delete; - CModelReaderNode_BeamLattice1702_BeamSet(_In_ BEAMSET * pBeamSet, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode_BeamLattice1702_BeamSet(_In_ BEAMSET * pBeamSet, _In_ std::unordered_set * pUniqueIdentifiers, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSets.h b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSets.h index d81917a84..3257753ec 100644 --- a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSets.h +++ b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSets.h @@ -37,9 +37,13 @@ NMR_ModelReaderNode_BeamLattice1702_BeamSets.h covers the official 3MF beamlatti #include "Model/Classes/NMR_ModelComponent.h" #include "Model/Classes/NMR_ModelObject.h" +#include + namespace NMR { class CModelReaderNode_BeamLattice1702_BeamSets : public CModelReaderNode { + private: + std::unordered_set m_uniqueIdentifiers; // Data structure used to ensure beamsets have unique identifiers protected: CMesh * m_pMesh; @@ -47,7 +51,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode_BeamLattice1702_BeamSets() = delete; - CModelReaderNode_BeamLattice1702_BeamSets(_In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode_BeamLattice1702_BeamSets(_In_ CMesh * pMesh, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beams.h b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beams.h index b36b074b4..b379491f2 100644 --- a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beams.h +++ b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beams.h @@ -53,7 +53,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode_BeamLattice1702_Beams() = delete; - CModelReaderNode_BeamLattice1702_Beams(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ nfDouble defaultRadius, _In_ eModelBeamLatticeCapMode defaultCapMode, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode_BeamLattice1702_Beams(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ nfDouble defaultRadius, _In_ eModelBeamLatticeCapMode defaultCapMode, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ref.h b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ref.h index 9a58fd108..936bd2e7d 100644 --- a/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ref.h +++ b/Include/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ref.h @@ -46,7 +46,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode_BeamLattice1702_Ref() = delete; - CModelReaderNode_BeamLattice1702_Ref(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode_BeamLattice1702_Ref(_In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); void retrieveIndex(_Out_ nfInt32 & nIndex); diff --git a/Include/Model/Reader/NMR_KeyStoreOpcPackageReader.h b/Include/Model/Reader/NMR_KeyStoreOpcPackageReader.h new file mode 100644 index 000000000..41f7d3491 --- /dev/null +++ b/Include/Model/Reader/NMR_KeyStoreOpcPackageReader.h @@ -0,0 +1,76 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStoreOpcPackageReader.h defines an OPC Package reader in a portable way. + +--*/ + +#ifndef NMR_KEYSTOREOPCPACKAGEREADER +#define NMR_KEYSTOREOPCPACKAGEREADER + +#include +#include +#include + +#include "Common/NMR_SecureContentTypes.h" +#include "Common/OPC/NMR_IOpcPackageReader.h" +#include "Common/Platform/NMR_ImportStream.h" +#include "Common/3MF_ProgressMonitor.h" +#include "Common/NMR_ModelWarnings.h" + +namespace NMR { + + class CModelContext; + + + class CKeyStoreOpcPackageReader: public IOpcPackageReader { + private: + CModelContext const & m_pContext; + PIOpcPackageReader m_pPackageReader; + std::map m_encryptedParts; + protected: + NMR::PImportStream findKeyStoreStream(); + void parseKeyStore(NMR::PImportStream keyStoreStream); + void openAllResourceDataGroups(); + void checkAuthenticatedTags(); + public: + CKeyStoreOpcPackageReader(_In_ PImportStream pImportStream, _In_ CModelContext const & context); + + // Inherited via IOpcPackageReader + virtual COpcPackageRelationship * findRootRelation(std::string sRelationType, nfBool bMustBeUnique) override; + virtual POpcPackagePart createPart(std::string sPath) override; + virtual nfUint64 getPartSize(std::string sPath) override; + + void close() override; + }; + + using PKeyStoreOpcPackageReader = std::shared_ptr; + +} + +#endif // !NMR_KEYSTOREOPCPACKAGEREADER diff --git a/Include/Model/Reader/NMR_ModelReader.h b/Include/Model/Reader/NMR_ModelReader.h index 11f22213d..5f0b95ba1 100644 --- a/Include/Model/Reader/NMR_ModelReader.h +++ b/Include/Model/Reader/NMR_ModelReader.h @@ -34,24 +34,21 @@ A model reader reads in a model file and generates an in-memory representation o #ifndef __NMR_MODELREADER #define __NMR_MODELREADER -#include "Model/Classes/NMR_Model.h" -#include "Model/Reader/NMR_ModelReaderWarnings.h" +#include "Model/Classes/NMR_ModelContext.h" +#include "Common/NMR_ModelWarnings.h" #include "Common/MeshImport/NMR_MeshImporter.h" -#include "Common/3MF_ProgressMonitor.h" #include +#include namespace NMR { - class CModelReader { + class CModelReader : public CModelContext { protected: - PModel m_pModel; PImportStream m_pPrintTicketStream; std::string m_sPrintTicketContentType; std::set m_RelationsToRead; - PModelReaderWarnings m_pWarnings; - PProgressMonitor m_pProgressMonitor; void readFromMeshImporter(_In_ CMeshImporter * pImporter); public: @@ -61,12 +58,9 @@ namespace NMR { virtual void readStream(_In_ PImportStream pStream) = 0; PImportStream retrievePrintTicket(_Out_ std::string & sContentType); - PModelReaderWarnings getWarnings (); void addRelationToRead(_In_ std::string sRelationShipType); void removeRelationToRead(_In_ std::string sRelationShipType); - - void SetProgressCallback(Lib3MFProgressCallback callback, void* userData); }; typedef std::shared_ptr PModelReader; diff --git a/Include/Model/Reader/NMR_ModelReaderNode.h b/Include/Model/Reader/NMR_ModelReaderNode.h index 30937ab29..9e634eab4 100644 --- a/Include/Model/Reader/NMR_ModelReaderNode.h +++ b/Include/Model/Reader/NMR_ModelReaderNode.h @@ -35,7 +35,7 @@ A model reader node is an abstract base class for all XML nodes of a 3MF Model S #define __NMR_MODELREADERNODE #include "Model/Classes/NMR_Model.h" -#include "Model/Reader/NMR_ModelReaderWarnings.h" +#include "Common/NMR_ModelWarnings.h" #include "Common/Platform/NMR_XmlReader.h" #include "Common/3MF_ProgressMonitor.h" @@ -50,7 +50,7 @@ namespace NMR { protected: PProgressMonitor m_pProgressMonitor; - PModelReaderWarnings m_pWarnings; + PModelWarnings m_pWarnings; void parseName(_In_ CXmlReader * pXMLReader); void parseAttributes(_In_ CXmlReader * pXMLReader); @@ -64,11 +64,11 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode() = delete; - CModelReaderNode(_In_ PModelReaderWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor = nullptr); + CModelReaderNode(_In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor = nullptr); virtual ~CModelReaderNode() = default; std::string getName(); - PModelReaderWarnings getWarnings(); + PModelWarnings getWarnings() const; virtual void parseXML(_In_ CXmlReader * pXMLReader) = 0; }; diff --git a/Include/Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h b/Include/Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h new file mode 100644 index 000000000..6b076bd8b --- /dev/null +++ b/Include/Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h @@ -0,0 +1,66 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreBase.h defines the base class for all Model Reader Node classes that are related to . + +--*/ + +#ifndef __NMR_MODELREADERNODE_KEYSTOREBASE +#define __NMR_MODELREADERNODE_KEYSTOREBASE + +#include "Common/NMR_Local.h" +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_Model.h" +#include "Model/Classes/NMR_KeyStore.h" +#include +namespace NMR { + + class CModelReaderNode_KeyStoreBase : public CModelReaderNode { + protected: + CKeyStore * const m_pKeyStore; + CModel * const m_pModel; + + public: + CModelReaderNode_KeyStoreBase() = delete; + CModelReaderNode_KeyStoreBase(_In_ CModel * const pModel, _In_ CKeyStore * const pKeyStore, _In_ PModelWarnings pWarnings); + + inline CKeyStore * const keystore() const { + return m_pKeyStore; + } + + inline CModel * const model() const { + return m_pModel; + } + + template std::shared_ptr extractCopy() const { + return std::make_shared(model(), keystore(), getWarnings()); + } + }; +} + +#endif // __NMR_MODELREADERNODE_KEYSTOREBASE diff --git a/Include/Model/Reader/NMR_ModelReaderNode_Model.h b/Include/Model/Reader/NMR_ModelReaderNode_ModelBase.h similarity index 82% rename from Include/Model/Reader/NMR_ModelReaderNode_Model.h rename to Include/Model/Reader/NMR_ModelReaderNode_ModelBase.h index d238fd3ca..8b23493cf 100644 --- a/Include/Model/Reader/NMR_ModelReaderNode_Model.h +++ b/Include/Model/Reader/NMR_ModelReaderNode_ModelBase.h @@ -26,19 +26,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Abstract: -NMR_ModelReaderNode_Model.h defines the Model Reader Model Node Class. +NMR_ModelReaderNode_ModelBase.h defines the Model Reader Model Node Class. A model reader model node is a parser for the root node of an XML Model Stream. --*/ -#ifndef __NMR_MODELREADERNODE_MODEL -#define __NMR_MODELREADERNODE_MODEL +#ifndef __NMR_MODELREADERNODE_MODELBASE +#define __NMR_MODELREADERNODE_MODELBASE #include "Model/Reader/NMR_ModelReaderNode.h" namespace NMR { - class CModelReaderNode_Model : public CModelReaderNode { + class CModelReaderNode_ModelBase : public CModelReaderNode { protected: CModel * m_pModel; std::string m_sRequiredExtensions; @@ -62,8 +62,8 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); virtual void OnNSAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue, _In_z_ const nfChar * pNameSpace); public: - CModelReaderNode_Model() = delete; - CModelReaderNode_Model(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings, const std::string sPath, _In_ PProgressMonitor pProgressMonitor); + CModelReaderNode_ModelBase() = delete; + CModelReaderNode_ModelBase(_In_ CModel *pModel, _In_ PModelWarnings pWarnings, const std::string sPath, _In_ PProgressMonitor pProgressMonitor); virtual void parseXML(_In_ CXmlReader * pXMLReader); @@ -76,8 +76,8 @@ namespace NMR { void setIgnoreMetaData(bool bIgnoreMetaData); }; - typedef std::shared_ptr PModelReaderNode_Model; + typedef std::shared_ptr PModelReaderNode_ModelBase; } -#endif // __NMR_MODELREADERNODE_MODEL +#endif // __NMR_MODELREADERNODE_MODELBASE diff --git a/Include/Model/Reader/NMR_ModelReaderNode_StringValue.h b/Include/Model/Reader/NMR_ModelReaderNode_StringValue.h new file mode 100644 index 000000000..2a2e515c1 --- /dev/null +++ b/Include/Model/Reader/NMR_ModelReaderNode_StringValue.h @@ -0,0 +1,59 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreKeyValue.h defines the Model Reader Node class that is related to . + +--*/ + +#ifndef __NMR_MODELREADERNODE_KEYSTOREKEYVALUE +#define __NMR_MODELREADERNODE_KEYSTOREKEYVALUE + +#include "Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h" +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Common/NMR_Local.h" +namespace NMR { + + class CModelReaderNode_StringValue: public CModelReaderNode { + private: + std::string m_sKeyValue; + protected: + void OnText(_In_z_ const nfChar * pText, _In_ CXmlReader * pXMLReader); + public: + CModelReaderNode_StringValue() = delete; + using CModelReaderNode::CModelReaderNode; + + std::string const & getValue() const; + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + }; + + typedef std::shared_ptr PModelReaderNode_StringValue; +} + +#endif // __NMR_MODELREADERNODE_KEYSTOREKEYVALUE diff --git a/Include/Model/Reader/NMR_ModelReader_3MF.h b/Include/Model/Reader/NMR_ModelReader_3MF.h index c4e7bf0a4..dc799de9f 100644 --- a/Include/Model/Reader/NMR_ModelReader_3MF.h +++ b/Include/Model/Reader/NMR_ModelReader_3MF.h @@ -35,6 +35,7 @@ NMR_ModelReader_3MF.h defines the Model Reader Class for #define __NMR_MODELREADER_3MF #include "Model/Reader/NMR_ModelReader.h" +#include "Common/NMR_SecureContentTypes.h" #include #include diff --git a/Include/Model/Reader/NMR_ModelReader_3MF_Native.h b/Include/Model/Reader/NMR_ModelReader_3MF_Native.h index 34947a6e2..c7c26fa63 100644 --- a/Include/Model/Reader/NMR_ModelReader_3MF_Native.h +++ b/Include/Model/Reader/NMR_ModelReader_3MF_Native.h @@ -39,15 +39,15 @@ It uses libzip and irrxml to parse the OPC package. #include "Model/Reader/NMR_ModelReader.h" #include "Model/Classes/NMR_Model.h" #include "Common/Platform/NMR_XmlReader.h" -#include "Common/OPC/NMR_OpcPackageReader.h" - +#include "Model/Reader/NMR_KeyStoreOpcPackageReader.h" +#include "Common/OPC/NMR_OpcPackagePart.h" #include namespace NMR { class CModelReader_3MF_Native : public CModelReader_3MF { private: - POpcPackageReader m_pPackageReader; + PKeyStoreOpcPackageReader m_pPackageReader; protected: void extractCustomDataFromRelationships(_In_ std::string& sTargetPartURIDir, _In_ COpcPackagePart * pModelPart); diff --git a/Include/Model/Reader/NMR_ModelReader_InstructionElement.h b/Include/Model/Reader/NMR_ModelReader_InstructionElement.h index f25f54b7c..38b5491f3 100644 --- a/Include/Model/Reader/NMR_ModelReader_InstructionElement.h +++ b/Include/Model/Reader/NMR_ModelReader_InstructionElement.h @@ -45,7 +45,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReader_InstructionElement() = delete; - CModelReader_InstructionElement(_In_ PModelReaderWarnings pWarnings); + CModelReader_InstructionElement(_In_ PModelWarnings pWarnings); virtual void parseName(_In_ CXmlReader * pXMLReader); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStore.h b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStore.h new file mode 100644 index 000000000..27303a29f --- /dev/null +++ b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStore.h @@ -0,0 +1,58 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStore.h defines the Model Reader Node class that is related to . + +--*/ + +#ifndef __NMR_MODELREADERNODE_KEYSTORE +#define __NMR_MODELREADERNODE_KEYSTORE + +#include "Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h" +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_KeyStore.h" + +namespace NMR { + + class CModelReaderNode_KeyStore: public CModelReaderNode_KeyStoreBase { + private: + PUUID m_UUID; + protected: + virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); + virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); + public: + CModelReaderNode_KeyStore() = delete; + using CModelReaderNode_KeyStoreBase::CModelReaderNode_KeyStoreBase; + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + }; + + typedef std::shared_ptr PModelReaderNode_KeyStore; +} + +#endif // __NMR_MODELREADERNODE_KEYSTORE diff --git a/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreAccessRight.h b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreAccessRight.h new file mode 100644 index 000000000..79b88e2b3 --- /dev/null +++ b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreAccessRight.h @@ -0,0 +1,67 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreDecryptRight.h defines the Model Reader Node class that is related to . + +--*/ + +#ifndef __NMR_MODELREADERNODE_KEYSTOACCESSRIGHT +#define __NMR_MODELREADERNODE_KEYSTOACCESSRIGHT + +#include "Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h" +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreKEKParams.h" + +namespace NMR { + + class CModelReaderNode_KeyStoreAccessRight : public CModelReaderNode_KeyStoreBase { + private: + nfBool m_bHasParams = false; + nfBool m_bHasConsumerIndex = false; + nfBool m_bHasCipherData = false; + nfUint64 m_nConsumerIndex = 0; + KEKPARAMS m_sParams; + std::vector m_rgCipherValue; + protected: + virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); + virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); + public: + CModelReaderNode_KeyStoreAccessRight() = delete; + using CModelReaderNode_KeyStoreBase::CModelReaderNode_KeyStoreBase; + + PKeyStoreAccessRight getAccessRight(); + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + }; + + typedef std::shared_ptr PModelReaderNode_KeyStoreAccessRight; +} + +#endif // __NMR_MODELREADERNODE_KEYSTOACCESSRIGHT diff --git a/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.h b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.h new file mode 100644 index 000000000..e11d05c08 --- /dev/null +++ b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.h @@ -0,0 +1,68 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreCipherValue.h defines the Model Reader Node class that is related to . + +--*/ + +#ifndef __NMR_MODELREADERNODE_KEYSTORECEKPARAMS +#define __NMR_MODELREADERNODE_KEYSTORECEKPARAMS + +#include "Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h" +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +#include "Model/Classes/NMR_KeyStoreCEKParams.h" + +namespace NMR { + + class CModelReaderNode_KeyStoreCEKParams: public CModelReaderNode_KeyStoreBase { + private: + nfBool m_bCompressed = false; + eKeyStoreEncryptAlgorithm m_eAlgorithm = eKeyStoreEncryptAlgorithm::AES256_GCM; + std::vector m_iv; + std::vector m_tag; + std::vector m_aad; + nfBool m_bHasAlgorithm = false; + protected: + virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); + virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); + + public: + CModelReaderNode_KeyStoreCEKParams() = delete; + using CModelReaderNode_KeyStoreBase::CModelReaderNode_KeyStoreBase; + + PKeyStoreCEKParams getCEKParams(); + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + }; + typedef std::shared_ptr PModelReaderNode_KeyStoreCEKParams; + +} + +#endif // __NMR_MODELREADERNODE_KEYSTORECEKPARAMS diff --git a/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.h b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.h new file mode 100644 index 000000000..fecaf7d68 --- /dev/null +++ b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.h @@ -0,0 +1,60 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreCipherValue.h defines the Model Reader Node class that is related to . + +--*/ + +#ifndef __NMR_MODELREADERNODE_KEYSTORECIPHERVALUE +#define __NMR_MODELREADERNODE_KEYSTORECIPHERVALUE + +#include "Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h" +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" + +namespace NMR { + + class CModelReaderNode_KeyStoreCipherValue: public CModelReaderNode_KeyStoreBase { + private: + std::vector m_sCipherValue; + protected: + virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); + public: + CModelReaderNode_KeyStoreCipherValue() = delete; + using CModelReaderNode_KeyStoreBase::CModelReaderNode_KeyStoreBase; + + std::vector const & getCipherValue() const; + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + }; + + typedef std::shared_ptr PModelReaderNode_KeyStoreCipherValue; +} + +#endif // __NMR_MODELREADERNODE_KEYSTORECIPHERVALUE diff --git a/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreConsumer.h b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreConsumer.h new file mode 100644 index 000000000..312b819fc --- /dev/null +++ b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreConsumer.h @@ -0,0 +1,60 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreConsumer.h defines the Model Reader Node class that is related to . + +--*/ + +#ifndef __NMR_MODELREADERNODE_KEYSTORECONSUMER +#define __NMR_MODELREADERNODE_KEYSTORECONSUMER + +#include "Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h" +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_KeyStore.h" + +namespace NMR { + + class CModelReaderNode_KeyStoreConsumer: public CModelReaderNode_KeyStoreBase { + private: + std::string m_sConsumerID; + std::string m_sKeyID; + std::string m_sKeyValue; + protected: + virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); + virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); + public: + CModelReaderNode_KeyStoreConsumer() = delete; + using CModelReaderNode_KeyStoreBase::CModelReaderNode_KeyStoreBase; + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + }; + + typedef std::shared_ptr PModelReaderNode_KeyStoreConsumer; +} + +#endif // __NMR_MODELREADERNODE_KEYSTORECONSUMER diff --git a/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreKEKParams.h b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreKEKParams.h new file mode 100644 index 000000000..c256e3941 --- /dev/null +++ b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreKEKParams.h @@ -0,0 +1,74 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreCipherValue.h defines the Model Reader Node class that is related to . + +--*/ + +#ifndef __NMR_MODELREADERNODE_KEYSTOREKEKPARAMS +#define __NMR_MODELREADERNODE_KEYSTOREKEKPARAMS + +#include "Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h" +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Common/NMR_SecureContentTypes.h" + +namespace NMR { + + namespace ParserUtils { + eKeyStoreWrapAlgorithm parseWrapAlgorithm(std::string const & value, bool & hasMgf1); + eKeyStoreMaskGenerationFunction parseMgf(std::string const & value); + eKeyStoreMessageDigest parseMessageDigest(std::string const & value); + } + + struct KEKPARAMS { + eKeyStoreWrapAlgorithm m_eAlgorithm; + eKeyStoreMaskGenerationFunction m_eMgf; + eKeyStoreMessageDigest m_eDigest; + }; + + class CModelReaderNode_KeyStoreKEKParams: public CModelReaderNode_KeyStoreBase { + private: + KEKPARAMS m_sKekParams = { eKeyStoreWrapAlgorithm::RSA_OAEP, eKeyStoreMaskGenerationFunction::MGF1_SHA1, eKeyStoreMessageDigest::SHA1 }; + nfBool m_bAlgHasMgf = false; + nfBool m_bHasAlgorithm = false; + protected: + virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); + public: + CModelReaderNode_KeyStoreKEKParams() = delete; + using CModelReaderNode_KeyStoreBase::CModelReaderNode_KeyStoreBase; + + KEKPARAMS getKekParams(); + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + }; + + typedef std::shared_ptr PModelReaderNode_KeyStoreKEKParams; +} + +#endif // __NMR_MODELREADERNODE_KEYSTOREKEKPARAMS diff --git a/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceData.h b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceData.h new file mode 100644 index 000000000..4160a376f --- /dev/null +++ b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceData.h @@ -0,0 +1,65 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreResourceData.h defines the Model Reader Node class that is related to . + +--*/ + +#ifndef __NMR_MODELREADERNODE_KEYSTORERESOURCEDATA +#define __NMR_MODELREADERNODE_KEYSTORERESOURCEDATA + +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreCEKParams.h" +#include "Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h" +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_KeyStoreResourceDataGroup.h" + + + +namespace NMR { + + class CModelReaderNode_KeyStoreResourceData : public CModelReaderNode_KeyStoreBase { + private: + std::string m_sPath; + PKeyStoreCEKParams m_pCekParams; + protected: + virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); + virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); + public: + CModelReaderNode_KeyStoreResourceData() = delete; + using CModelReaderNode_KeyStoreBase::CModelReaderNode_KeyStoreBase; + + PKeyStoreResourceData getResourceData(PKeyStoreResourceDataGroup const & rdg); + virtual void parseXML(_In_ CXmlReader * pXMLReader); + }; + + typedef std::shared_ptr PModelReaderNode_KeyStoreResourceData; +} + +#endif // __NMR_MODELREADERNODE_KEYSTORERESOURCEDATA diff --git a/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceDataGroup.h b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceDataGroup.h new file mode 100644 index 000000000..f0060c30e --- /dev/null +++ b/Include/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceDataGroup.h @@ -0,0 +1,65 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreResourceData.h defines the Model Reader Node class that is related to . + +--*/ + +#ifndef __NMR_MODELREADERNODE_KEYSTORERESOURCEDATAGROUP +#define __NMR_MODELREADERNODE_KEYSTORERESOURCEDATAGROUP + +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreAccessRight.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceData.h" +#include "Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h" +#include "Model/Reader/NMR_ModelReaderNode.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreResourceDataGroup.h" + + +namespace NMR { + + class CModelReaderNode_KeyStoreResourceDataGroup : public CModelReaderNode_KeyStoreBase { + private: + PKeyStoreResourceDataGroup m_pGroup; + nfBool m_bHasUuid = false; + protected: + virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); + virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); + public: + CModelReaderNode_KeyStoreResourceDataGroup() = delete; + using CModelReaderNode_KeyStoreBase::CModelReaderNode_KeyStoreBase; + + virtual void parseXML(_In_ CXmlReader * pXMLReader); + }; + + typedef std::shared_ptr PModelReaderNode_KeyStoreResourceDataGroup; +} + +#endif // __NMR_MODELREADERNODE_KEYSTORERESOURCEDATAGROUP diff --git a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Polygon.h b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Polygon.h index e23c1527e..fba08ab06 100644 --- a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Polygon.h +++ b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Polygon.h @@ -51,7 +51,7 @@ namespace NMR { public: CModelReaderNode_Slices1507_Polygon() = delete; - CModelReaderNode_Slices1507_Polygon(_In_ CSlice *pSlice, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode_Slices1507_Polygon(_In_ CSlice *pSlice, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Segment.h b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Segment.h index 99aadc579..8540bbc70 100644 --- a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Segment.h +++ b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Segment.h @@ -52,7 +52,7 @@ namespace NMR { public: CModelReaderNode_Slices1507_Segment() = delete; - CModelReaderNode_Slices1507_Segment(_In_ CSlice *pSlice, nfUint32 nPolygonIndex, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode_Slices1507_Segment(_In_ CSlice *pSlice, nfUint32 nPolygonIndex, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Slice.h b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Slice.h index e10953e55..7999124a9 100644 --- a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Slice.h +++ b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Slice.h @@ -54,7 +54,7 @@ namespace NMR { public: CModelReaderNode_Slices1507_Slice() = delete; - CModelReaderNode_Slices1507_Slice(_In_ CModelSliceStack *pSliceStack, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode_Slices1507_Slice(_In_ CModelSliceStack *pSliceStack, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRef.h b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRef.h index 9543d103b..c7667151e 100644 --- a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRef.h +++ b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRef.h @@ -51,7 +51,7 @@ namespace NMR { public: CModelReaderNode_Slice1507_SliceRef() = delete; - CModelReaderNode_Slice1507_SliceRef(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode_Slice1507_SliceRef(_In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefModel.h b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefModel.h index bf020500c..2a7a73bce 100644 --- a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefModel.h +++ b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefModel.h @@ -33,7 +33,7 @@ NMR_ModelReaderNode_slice1507.h covers the private 3MF slice extension. #ifndef __NMR_MODELREADERNODE_SLICE1507_SLICEREFMODEL #define __NMR_MODELREADERNODE_SLICE1507_SLICEREFMODEL -#include "Model/Reader/NMR_ModelReaderNode_Model.h" +#include "Model/Reader/NMR_ModelReaderNode_ModelBase.h" #include "Model/Classes/NMR_ModelComponent.h" #include "Model/Classes/NMR_ModelComponentsObject.h" #include "Model/Classes/NMR_ModelObject.h" @@ -41,7 +41,7 @@ NMR_ModelReaderNode_slice1507.h covers the private 3MF slice extension. namespace NMR { - class CModelReader_Slice1507_SliceRefModel : public CModelReaderNode_Model { + class CModelReader_Slice1507_SliceRefModel : public CModelReaderNode_ModelBase { private: std::string m_sSliceRefPath; @@ -50,7 +50,7 @@ namespace NMR { public: CModelReader_Slice1507_SliceRefModel() = delete; - CModelReader_Slice1507_SliceRefModel(_In_ CModel *pModel, _In_ PModelReaderWarnings pWarnings, _In_z_ const std::string sSliceRefPath); + CModelReader_Slice1507_SliceRefModel(_In_ CModel *pModel, _In_ PModelWarnings pWarnings, _In_z_ const std::string sSliceRefPath); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefResources.h b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefResources.h index 095487211..beee4c9e9 100644 --- a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefResources.h +++ b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefResources.h @@ -50,7 +50,7 @@ namespace NMR { public: CModelReader_Slice1507_SliceRefResources() = delete; - CModelReader_Slice1507_SliceRefResources(_In_ CModel *pModel, _In_ PModelReaderWarnings pWarnings, _In_z_ const std::string sSliceRefPath); + CModelReader_Slice1507_SliceRefResources(_In_ CModel *pModel, _In_ PModelWarnings pWarnings, _In_z_ const std::string sSliceRefPath); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceStack.h b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceStack.h index 05dd43450..e60aac7ad 100644 --- a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceStack.h +++ b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceStack.h @@ -55,7 +55,7 @@ namespace NMR { public: CModelReaderNode_Slice1507_SliceStack() = delete; - CModelReaderNode_Slice1507_SliceStack(_In_ CModel *pModel, _In_ PModelReaderWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor, _In_ const std::string sSlicePath); + CModelReaderNode_Slice1507_SliceStack(_In_ CModel *pModel, _In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor, _In_ const std::string sSlicePath); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertex.h b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertex.h index 8d1d807e3..b7d1d955b 100644 --- a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertex.h +++ b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertex.h @@ -53,7 +53,7 @@ namespace NMR { public: CModelReaderNode_Slices1507_Vertex() = delete; - CModelReaderNode_Slices1507_Vertex(_In_ CSlice *pSlice, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode_Slices1507_Vertex(_In_ CSlice *pSlice, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertices.h b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertices.h index 55dc360a6..3fbd90caf 100644 --- a/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertices.h +++ b/Include/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertices.h @@ -50,7 +50,7 @@ namespace NMR { public: CModelReaderNode_Slices1507_Vertices() = delete; - CModelReaderNode_Slices1507_Vertices(_In_ CSlice *pSlice, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode_Slices1507_Vertices(_In_ CSlice *pSlice, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Build.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Build.h index b146e395c..3f3347333 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Build.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Build.h @@ -45,7 +45,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode093_Build() = delete; - CModelReaderNode093_Build(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Build(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_BuildItem.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_BuildItem.h index 3d98b273b..f8053d843 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_BuildItem.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_BuildItem.h @@ -48,7 +48,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode093_BuildItem() = delete; - CModelReaderNode093_BuildItem(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_BuildItem(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Color.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Color.h index dc9ab91dc..eee96c4e6 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Color.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Color.h @@ -50,7 +50,7 @@ namespace NMR { void parseColor(); public: CModelReaderNode093_Color() = delete; - CModelReaderNode093_Color(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Color(_In_ PModelWarnings pWarnings); virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Component.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Component.h index 4079ee524..9201f696c 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Component.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Component.h @@ -47,7 +47,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode093_Component() = delete; - CModelReaderNode093_Component(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Component(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Components.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Components.h index 14c7899f7..ca9e179a7 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Components.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Components.h @@ -47,7 +47,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode093_Components() = delete; - CModelReaderNode093_Components(_In_ CModelComponentsObject * pComponentsObject, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Components(_In_ CModelComponentsObject * pComponentsObject, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Material.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Material.h index de2a26aba..fd3ef160e 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Material.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Material.h @@ -47,7 +47,7 @@ namespace NMR { ModelResourceID m_nColorID; public: CModelReaderNode093_Material() = delete; - CModelReaderNode093_Material(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Material(_In_ PModelWarnings pWarnings); virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Mesh.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Mesh.h index 1b43048ec..02cfd7c9d 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Mesh.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Mesh.h @@ -55,7 +55,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode093_Mesh() = delete; - CModelReaderNode093_Mesh(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelBaseMaterialResource pMaterialResource, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Mesh(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelBaseMaterialResource pMaterialResource, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Object.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Object.h index fbd98de1b..f67caf6e9 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Object.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Object.h @@ -63,7 +63,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode093_Object() = delete; - CModelReaderNode093_Object(_In_ CModel * pModel, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Object(_In_ CModel * pModel, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Resources.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Resources.h index 62ae66885..8c2792a4c 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Resources.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Resources.h @@ -53,7 +53,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode093_Resources() = delete; - CModelReaderNode093_Resources(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Resources(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Texture.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Texture.h index 67376cf6f..08a529823 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Texture.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Texture.h @@ -56,7 +56,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode093_Texture() = delete; - CModelReaderNode093_Texture(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Texture(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertex.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertex.h index ce2a12ee3..77e5daa9a 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertex.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertex.h @@ -48,7 +48,7 @@ namespace NMR { nfBool m_bHasV; public: CModelReaderNode093_TextureVertex() = delete; - CModelReaderNode093_TextureVertex(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_TextureVertex(_In_ PModelWarnings pWarnings); virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertices.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertices.h index 2823a8eed..e5e076291 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertices.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertices.h @@ -51,7 +51,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode093_TextureVertices() = delete; - CModelReaderNode093_TextureVertices(_In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings, _In_ PModelReader_TexCoordMapping pTexCoordMapping); + CModelReaderNode093_TextureVertices(_In_ CMesh * pMesh, _In_ PModelWarnings pWarnings, _In_ PModelReader_TexCoordMapping pTexCoordMapping); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Triangle.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Triangle.h index bf6a3429e..33456f60f 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Triangle.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Triangle.h @@ -57,7 +57,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode093_Triangle() = delete; - CModelReaderNode093_Triangle(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Triangle(_In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); void retrieveIndices(_Out_ nfInt32 & nIndex1, _Out_ nfInt32 & nIndex2, _Out_ nfInt32 & nIndex3, nfInt32 nNodeCount); diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Triangles.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Triangles.h index c39b48cdf..9d297c36b 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Triangles.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Triangles.h @@ -60,7 +60,7 @@ namespace NMR { _Ret_notnull_ CMeshInformation_Properties * createPropertiesInformation(); public: CModelReaderNode093_Triangles() = delete; - CModelReaderNode093_Triangles(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelReader_TexCoordMapping pTexCoordMapping, PModelBaseMaterialResource pMaterialResource, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Triangles(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelReader_TexCoordMapping pTexCoordMapping, PModelBaseMaterialResource pMaterialResource, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Vertex.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Vertex.h index 7426fd9a6..79d6575f9 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Vertex.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Vertex.h @@ -50,7 +50,7 @@ namespace NMR { nfBool m_bHasZ; public: CModelReaderNode093_Vertex() = delete; - CModelReaderNode093_Vertex(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Vertex(_In_ PModelWarnings pWarnings); virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); diff --git a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Vertices.h b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Vertices.h index 51206ff76..e95b7394c 100644 --- a/Include/Model/Reader/v093/NMR_ModelReaderNode093_Vertices.h +++ b/Include/Model/Reader/v093/NMR_ModelReaderNode093_Vertices.h @@ -48,7 +48,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode093_Vertices() = delete; - CModelReaderNode093_Vertices(_In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode093_Vertices(_In_ CMesh * pMesh, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterial.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterial.h index ee31bb453..6a971ee86 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterial.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterial.h @@ -54,7 +54,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode100_BaseMaterial() = delete; - CModelReaderNode100_BaseMaterial(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_BaseMaterial(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterials.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterials.h index eb6c9ab65..0e6234ee6 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterials.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterials.h @@ -51,7 +51,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_BaseMaterials() = delete; - CModelReaderNode100_BaseMaterials(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_BaseMaterials(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Build.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Build.h index 63aa2ab55..712b3cd62 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Build.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Build.h @@ -47,7 +47,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_Build() = delete; - CModelReaderNode100_Build(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Build(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_BuildItem.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_BuildItem.h index 82399bd0f..f2af2c496 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_BuildItem.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_BuildItem.h @@ -59,7 +59,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_BuildItem() = delete; - CModelReaderNode100_BuildItem(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_BuildItem(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Color.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Color.h index d64e8b3a3..28ebd7eb4 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Color.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Color.h @@ -51,7 +51,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode100_Color() = delete; - CModelReaderNode100_Color(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Color(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Colors.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Colors.h index 0661c8edd..194cbf5f6 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Colors.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Colors.h @@ -52,7 +52,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_Colors() = delete; - CModelReaderNode100_Colors(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Colors(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Component.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Component.h index 3e4219800..bb981b23d 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Component.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Component.h @@ -52,7 +52,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode100_Component() = delete; - CModelReaderNode100_Component(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Component(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Components.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Components.h index 8fb8c436c..d9896bc1c 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Components.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Components.h @@ -48,7 +48,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_Components() = delete; - CModelReaderNode100_Components(_In_ CModelComponentsObject * pComponentsObject, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Components(_In_ CModelComponentsObject * pComponentsObject, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Composite.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Composite.h index f89529c33..d45892a6a 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Composite.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Composite.h @@ -50,7 +50,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode100_Composite() = delete; - CModelReaderNode100_Composite(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings, _In_z_ const std::vector& baseMaterialPropertyIds); + CModelReaderNode100_Composite(_In_ CModel * pModel, _In_ PModelWarnings pWarnings, _In_z_ const std::vector& baseMaterialPropertyIds); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_CompositeMaterials.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_CompositeMaterials.h index 030f226fe..a393d1abe 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_CompositeMaterials.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_CompositeMaterials.h @@ -55,7 +55,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_CompositeMaterials() = delete; - CModelReaderNode100_CompositeMaterials(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_CompositeMaterials(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.h index 5b918b0ae..573f7f808 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.h @@ -46,7 +46,7 @@ namespace NMR { CMesh * m_pMesh; CModel * m_pModel; - ModelResourceID m_nObjectLevelPropertyID; + PPackageResourceID m_pObjectLevelPropertyID; ModelResourceIndex m_nObjectLevelPropertyIndex; eModelBeamLatticeClipMode m_eClipMode; @@ -59,7 +59,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_Mesh() = delete; - CModelReaderNode100_Mesh(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor, _In_ ModelResourceID nDefaultPropertyID, _In_ ModelResourceIndex nDefaultPropertyIndex); + CModelReaderNode100_Mesh(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor, _In_ PPackageResourceID m_pObjectLevelPropertyID, _In_ ModelResourceIndex nDefaultPropertyIndex); virtual void parseXML(_In_ CXmlReader * pXMLReader); void retrieveClippingInfo(_Out_ eModelBeamLatticeClipMode &eClipMode, _Out_ nfBool & bHasClippingMode, _Out_ ModelResourceID & nClippingMeshID); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_MetaData.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_MetaData.h index a9a4e0257..609f98b52 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_MetaData.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_MetaData.h @@ -49,7 +49,7 @@ namespace NMR { virtual void OnText(_In_z_ const nfChar * pText, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_MetaData() = delete; - CModelReaderNode100_MetaData(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_MetaData(_In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_MetaDataGroup.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_MetaDataGroup.h index 9e14a7346..b48182eb9 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_MetaDataGroup.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_MetaDataGroup.h @@ -48,7 +48,7 @@ namespace NMR { virtual void OnText(_In_z_ const nfChar * pText, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_MetaDataGroup() = delete; - CModelReaderNode100_MetaDataGroup(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_MetaDataGroup(_In_ PModelWarnings pWarnings); PModelMetaDataGroup getMetaDataGroup(); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Multi.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Multi.h index d1a81133b..75d9f8a22 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Multi.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Multi.h @@ -49,7 +49,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode100_Multi() = delete; - CModelReaderNode100_Multi(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Multi(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_MultiProperties.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_MultiProperties.h index f9028bea9..d3476e750 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_MultiProperties.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_MultiProperties.h @@ -51,7 +51,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_MultiProperties() = delete; - CModelReaderNode100_MultiProperties(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_MultiProperties(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Object.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Object.h index c1050a209..7ec4450f3 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Object.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Object.h @@ -59,7 +59,8 @@ namespace NMR { PModelObject m_pObject; nfBool m_bHasDefaultPropertyID; nfBool m_bHasDefaultPropertyIndex; - ModelResourceID m_nObjectLevelPropertyID; + ModelResourceID m_nObjectLevelPropertyModelID; + PPackageResourceID m_pObjectLevelPropertyID; ModelResourceIndex m_nObjectLevelPropertyIndex; nfUint32 m_nSliceStackId; @@ -76,7 +77,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_Object() = delete; - CModelReaderNode100_Object(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor); + CModelReaderNode100_Object(_In_ CModel * pModel, _In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Resources.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Resources.h index 8f8b9b33b..ba7d36285 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Resources.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Resources.h @@ -50,7 +50,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_Resources() = delete; - CModelReaderNode100_Resources(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings, _In_z_ const std::string sPath, _In_ PProgressMonitor pProgressMonitor); + CModelReaderNode100_Resources(_In_ CModel * pModel, _In_ PModelWarnings pWarnings, _In_z_ const std::string sPath, _In_ PProgressMonitor pProgressMonitor); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Tex2Coord.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Tex2Coord.h index 9e3abff2d..86be8e576 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Tex2Coord.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Tex2Coord.h @@ -52,7 +52,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode100_Tex2Coord() = delete; - CModelReaderNode100_Tex2Coord(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Tex2Coord(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Tex2DGroup.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Tex2DGroup.h index 1987cd8d7..32c6689a6 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Tex2DGroup.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Tex2DGroup.h @@ -53,7 +53,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_Tex2DGroup() = delete; - CModelReaderNode100_Tex2DGroup(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Tex2DGroup(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Texture2D.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Texture2D.h index e9011fd0b..c07bd60e2 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Texture2D.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Texture2D.h @@ -62,7 +62,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode100_Texture2D() = delete; - CModelReaderNode100_Texture2D(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Texture2D(_In_ CModel * pModel, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Triangle.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Triangle.h index 5a31f7b74..8912f174f 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Triangle.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Triangle.h @@ -53,7 +53,7 @@ namespace NMR { virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); public: CModelReaderNode100_Triangle() = delete; - CModelReaderNode100_Triangle(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Triangle(_In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); void retrieveIndices(_Out_ nfInt32 & nIndex1, _Out_ nfInt32 & nIndex2, _Out_ nfInt32 & nIndex3, nfInt32 nNodeCount); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Triangles.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Triangles.h index c5a15a3b3..b6ba9f408 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Triangles.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Triangles.h @@ -47,7 +47,7 @@ namespace NMR { CMesh * m_pMesh; CModel * m_pModel; - ModelResourceID m_nDefaultResourceID; + PPackageResourceID m_pObjectLevelPropertyID; ModelResourceIndex m_nDefaultResourceIndex; ModelResourceID m_nUsedResourceID; @@ -57,7 +57,8 @@ namespace NMR { _Ret_notnull_ CMeshInformation_Properties * createPropertiesInformation(); public: CModelReaderNode100_Triangles() = delete; - CModelReaderNode100_Triangles(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings, _In_ ModelResourceID nDefaultPropertyID, _In_ ModelResourceIndex nDefaultPropertyIndex); + CModelReaderNode100_Triangles(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelWarnings pWarnings, + _In_ PPackageResourceID pObjectLevelPropertyID, _In_ ModelResourceIndex nDefaultPropertyIndex); virtual void parseXML(_In_ CXmlReader * pXMLReader); ModelResourceID getUsedPropertyID() const; diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Vertex.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Vertex.h index 6260efeaf..34c02f416 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Vertex.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Vertex.h @@ -50,7 +50,7 @@ namespace NMR { nfBool m_bHasZ; public: CModelReaderNode100_Vertex() = delete; - CModelReaderNode100_Vertex(_In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Vertex(_In_ PModelWarnings pWarnings); virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Vertices.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Vertices.h index cb36681eb..27500742c 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Vertices.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Vertices.h @@ -48,7 +48,7 @@ namespace NMR { virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); public: CModelReaderNode100_Vertices() = delete; - CModelReaderNode100_Vertices(_In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings); + CModelReaderNode100_Vertices(_In_ CMesh * pMesh, _In_ PModelWarnings pWarnings); virtual void parseXML(_In_ CXmlReader * pXMLReader); }; diff --git a/Include/Model/Writer/NMR_KeyStoreOpcPackageWriter.h b/Include/Model/Writer/NMR_KeyStoreOpcPackageWriter.h new file mode 100644 index 000000000..83a50e9b6 --- /dev/null +++ b/Include/Model/Writer/NMR_KeyStoreOpcPackageWriter.h @@ -0,0 +1,81 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStoreOpcPackageWriter.h defines an OPC Package writer in a portable way. + +--*/ + +#ifndef NMR_KEYSTOREOPCPACKAGEWRITER +#define NMR_KEYSTOREOPCPACKAGEWRITER + +#include + +#include "Common/OPC/NMR_IOpcPackageWriter.h" +#include "Common/Platform/NMR_ExportStream.h" + +namespace NMR { + + class CModelContext; + class CKeyStoreResourceData; + class CKeyStoreAccessRight; + class CXmlWriter; + + using PKeyStoreResourceData = std::shared_ptr; + using PKeyStoreAccessRight = std::shared_ptr; + + class CKeyStoreOpcPackageWriter : public IOpcPackageWriter { + private: + bool pathIsEncrypted(_In_ std::string sPath); + protected: + CModelContext const & m_pContext; + PIOpcPackageWriter m_pPackageWriter; + + void writeKeyStoreStream(_In_ CXmlWriter * pXMLWriter); + void refreshAllResourceDataGroups(); + POpcPackagePart wrapPartStream(PKeyStoreResourceData rd, POpcPackagePart part); + void refreshResourceDataTag(PKeyStoreResourceData rd); + void refreshAccessRight(PKeyStoreAccessRight ar, std::vector const & key); + public: + CKeyStoreOpcPackageWriter( + _In_ PExportStream pImportStream, + _In_ CModelContext const & context); + + POpcPackagePart addPart(_In_ std::string sPath) override; + void close() override; + void addContentType(std::string sExtension, std::string sContentType) override; + void addContentType(_In_ POpcPackagePart pOpcPackagePart, _In_ std::string sContentType) override; + POpcPackageRelationship addRootRelationship(std::string sType, COpcPackagePart * pTargetPart) override; + POpcPackageRelationship addPartRelationship(_In_ POpcPackagePart pOpcPackagePart, _In_ std::string sType, _In_ COpcPackagePart * pTargetPart) override; + std::list addWriterSpecificRelationships(_In_ POpcPackagePart pOpcPackagePart, _In_ COpcPackagePart* pTargetPart) override; + }; + + using PKeyStoreOpcPackageWriter = std::shared_ptr; + +} + +#endif // !NMR_KEYSTOREOPCPACKAGEWRITER diff --git a/Include/Model/Writer/NMR_ModelWriter.h b/Include/Model/Writer/NMR_ModelWriter.h index aa2a5b34e..295d2ee8f 100644 --- a/Include/Model/Writer/NMR_ModelWriter.h +++ b/Include/Model/Writer/NMR_ModelWriter.h @@ -34,29 +34,23 @@ A model writer exports the in memory represenation into the 3MF file. #ifndef __NMR_MODELWRITER #define __NMR_MODELWRITER -#include "Model/Classes/NMR_Model.h" +#include "Model/Classes/NMR_Model.h" +#include "Model/Classes/NMR_ModelContext.h" #include "Common/Platform/NMR_ExportStream.h" #include "Common/3MF_ProgressMonitor.h" #include namespace NMR { - class CModelWriter { + class CModelWriter : public CModelContext{ private: nfUint32 m_nDecimalPrecision; - protected: - PModel m_pModel; - PProgressMonitor m_pProgressMonitor; public: CModelWriter() = delete; CModelWriter(_In_ PModel pModel); virtual ~CModelWriter() = default; virtual void exportToStream(_In_ PExportStream pStream) = 0; - void addCustomContentType(_In_ std::wstring sExtension, _In_ std::wstring sContentType); - void removeCustomContentType(_In_ std::wstring sExtension); - - void SetProgressCallback(Lib3MFProgressCallback callback, void* userData); void SetDecimalPrecision(nfUint32); nfUint32 GetDecimalPrecision(); diff --git a/Include/Model/Writer/NMR_ModelWriterNode.h b/Include/Model/Writer/NMR_ModelWriterNode.h index 544af61c1..0a3caee4f 100644 --- a/Include/Model/Writer/NMR_ModelWriterNode.h +++ b/Include/Model/Writer/NMR_ModelWriterNode.h @@ -34,8 +34,6 @@ This is the abstract base class for all 3MF model stream exporters. #ifndef __NMR_MODELWRITERNODE #define __NMR_MODELWRITERNODE -#include "Model/Classes/NMR_Model.h" -#include "Model/Classes/NMR_ModelConstants.h" #include "Common/Platform/NMR_XmlWriter.h" #include "Common/3MF_ProgressMonitor.h" @@ -43,7 +41,6 @@ namespace NMR { class CModelWriterNode { protected: - CModel * m_pModel; CXmlWriter * m_pXMLWriter; PProgressMonitor m_pProgressMonitor; @@ -63,10 +60,9 @@ namespace NMR { void writeEndElement(); void writeFullEndElement(); void writeText(_In_z_ const nfChar * pwszText, _In_ nfUint32 cbLength); - public: CModelWriterNode() = delete; - CModelWriterNode(_In_ CModel * pModel, _In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor); + CModelWriterNode(_In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor); virtual void writeToXML () = 0; }; diff --git a/Include/Model/Writer/NMR_ModelWriterNode_KeyStoreBase.h b/Include/Model/Writer/NMR_ModelWriterNode_KeyStoreBase.h new file mode 100644 index 000000000..69b4010c8 --- /dev/null +++ b/Include/Model/Writer/NMR_ModelWriterNode_KeyStoreBase.h @@ -0,0 +1,55 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelWriterNode_KeyStoreBase.h defines the base class for all Model Writer Node classes that are related to . + +--*/ + +#ifndef __NMR_MODELWRITERNODE_KEYSTOREBASE +#define __NMR_MODELWRITERNODE_KEYSTOREBASE + +#include "Common/Platform/NMR_XmlWriter.h" +#include "Common/3MF_ProgressMonitor.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Writer/NMR_ModelWriterNode.h" + +namespace NMR { + + class CModelWriterNode_KeyStoreBase : public CModelWriterNode { + protected: + PKeyStore m_pKeyStore; + + public: + CModelWriterNode_KeyStoreBase() = delete; + CModelWriterNode_KeyStoreBase(_In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor, _In_ PKeyStore pKeyStore); + }; + +} + +#endif // __NMR_MODELWRITERNODE_KEYSTOREBASE \ No newline at end of file diff --git a/Include/Model/Writer/NMR_ModelWriterNode_ModelBase.h b/Include/Model/Writer/NMR_ModelWriterNode_ModelBase.h new file mode 100644 index 000000000..a3b03d7cd --- /dev/null +++ b/Include/Model/Writer/NMR_ModelWriterNode_ModelBase.h @@ -0,0 +1,57 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelWriterNode_ModelBase.h defines the Base class for all Model Writer Node classes that are related to . +This is the abstract base class for all 3MF model stream exporters. + +--*/ + +#ifndef __NMR_MODELWRITERNODE_MODELBASE +#define __NMR_MODELWRITERNODE_MODELBASE + +#include "Common/Platform/NMR_XmlWriter.h" +#include "Common/3MF_ProgressMonitor.h" +#include "Model/Classes/NMR_Model.h" +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Writer/NMR_ModelWriterNode.h" + +namespace NMR { + + class CModelWriterNode_ModelBase : public CModelWriterNode { + protected: + CModel * m_pModel; + + void assertResourceIsInCurrentPath(PPackageResourceID pID); + public: + CModelWriterNode_ModelBase() = delete; + CModelWriterNode_ModelBase(_In_ CModel * pModel, _In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor); + }; + +} + +#endif // __NMR_MODELWRITERNODE_MODELBASE \ No newline at end of file diff --git a/Include/Model/Writer/NMR_ModelWriter_3MF.h b/Include/Model/Writer/NMR_ModelWriter_3MF.h index 2e85cbc14..7c6e8a924 100644 --- a/Include/Model/Writer/NMR_ModelWriter_3MF.h +++ b/Include/Model/Writer/NMR_ModelWriter_3MF.h @@ -34,6 +34,7 @@ A model writer exports the in memory represenation into a 3MF file. #ifndef __NMR_MODELWRITER_3MF #define __NMR_MODELWRITER_3MF +#include "Model/Classes/NMR_KeyStore.h" #include "Model/Writer/NMR_ModelWriter.h" #include "Common/Platform/NMR_XmlWriter.h" @@ -45,7 +46,7 @@ namespace NMR { void writeModelStream(_In_ CXmlWriter * pXMLWriter, _In_ CModel * pModel); // Creates a slicestack attachment stream - void writeSliceStackStream(_In_ CXmlWriter *pXMLWriter); + void writeNonRootModelStream(_In_ CXmlWriter *pXMLWriter); // These are OPC dependent functions virtual void createPackage(_In_ CModel * pModel) = 0; diff --git a/Include/Model/Writer/NMR_ModelWriter_3MF_Native.h b/Include/Model/Writer/NMR_ModelWriter_3MF_Native.h index c3767b703..77a2953c8 100644 --- a/Include/Model/Writer/NMR_ModelWriter_3MF_Native.h +++ b/Include/Model/Writer/NMR_ModelWriter_3MF_Native.h @@ -37,6 +37,7 @@ using LibZ and a native XML writer implementation. #include "Common/OPC/NMR_OpcPackageWriter.h" #include "Model/Writer/NMR_ModelWriter_3MF.h" +#include "Model/Writer/NMR_KeyStoreOpcPackageWriter.h" #define MODELWRITER_NATIVE_BUFFERSIZE 65536 @@ -44,18 +45,17 @@ namespace NMR { class CModelWriter_3MF_Native : public CModelWriter_3MF { protected: - nfInt32 m_nRelationIDCounter; - CModel * m_pModel; - std::vector m_aSliceStreamBuffer; + std::shared_ptr m_pPackageWriter; + CModel * m_pOtherModel; // These are OPC dependent functions virtual void createPackage(_In_ CModel * pModel); virtual void writePackageToStream(_In_ PExportStream pStream); virtual void releasePackage(); - std::string generateRelationShipID(); - void addAttachments(_In_ CModel * pModel, _In_ POpcPackageWriter pPackageWriter, _In_ POpcPackagePart pModelPart); - void addSlicerefAttachments(); + void addAttachments(_In_ CModel * pModel, _In_ POpcPackagePart pModelPart); + + void addNonRootModels(); public: CModelWriter_3MF_Native() = delete; diff --git a/Include/Model/Writer/SecureContent101/NMR_ModelWriterNode_KeyStore.h b/Include/Model/Writer/SecureContent101/NMR_ModelWriterNode_KeyStore.h new file mode 100644 index 000000000..b8f6aef41 --- /dev/null +++ b/Include/Model/Writer/SecureContent101/NMR_ModelWriterNode_KeyStore.h @@ -0,0 +1,62 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelWriterNode_KeyStore.h defines the Model Writer KeyStore Node Class. +This is the class for exporting the 3mf keystore stream root node. + +--*/ + +#ifndef __NMR_MODELWRITERNODE_KEYSTORE +#define __NMR_MODELWRITERNODE_KEYSTORE + +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Writer/NMR_ModelWriterNode_KeyStoreBase.h" + +namespace NMR { + + class CModelWriterNode_KeyStore : public CModelWriterNode_KeyStoreBase { + private: + std::map m_consumerIndexes; + protected: + void writeWrapAlgorithmAttribute(eKeyStoreWrapAlgorithm ea); + void writeMgf(eKeyStoreMaskGenerationFunction mgf); + void writeDigest(eKeyStoreMessageDigest md); + void writeEncryptionAlgorithmAttribute(eKeyStoreEncryptAlgorithm ea); + void writeConsumers(); + void writeResourceDatagroup(); + void writeAccessRight(PKeyStoreAccessRight const & ar); + void writeResourceData(PKeyStoreResourceData const & rd); + public: + using CModelWriterNode_KeyStoreBase::CModelWriterNode_KeyStoreBase; + CModelWriterNode_KeyStore() = delete; + virtual void writeToXML(); + }; + +} + +#endif // __NMR_MODELWRITERNODE_KEYSTORE diff --git a/Include/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.h b/Include/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.h index 759b3cfca..6a6954ba5 100644 --- a/Include/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.h +++ b/Include/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.h @@ -34,7 +34,7 @@ This is the class for exporting the 3mf mesh node. #ifndef __NMR_MODELWRITERNODE100_MESH #define __NMR_MODELWRITERNODE100_MESH -#include "Model/Writer/NMR_ModelWriterNode.h" +#include "Model/Writer/NMR_ModelWriterNode_ModelBase.h" #include "Model/Classes/NMR_ModelObject.h" #include "Model/Classes/NMR_ModelMeshObject.h" @@ -50,13 +50,17 @@ This is the class for exporting the 3mf mesh node. #define MODELWRITERMESH100_TRIANGLELINESTARTLENGTH 14 #define MODELWRITERMESH100_BEAMLATTICE_BEAMLINESTART " m_VertexLine; std::array m_TriangleLine; std::array m_BeamLine; + std::array m_BallLine; std::array m_BeamRefLine; + std::array m_BallRefLine; nfUint32 m_nVertexBufferPos; nfUint32 m_nTriangleBufferPos; nfUint32 m_nBeamBufferPos; + nfUint32 m_nBallBufferPos; nfUint32 m_nBeamRefBufferPos; + nfUint32 m_nBallRefBufferPos; private: const int m_nPosAfterDecPoint; const int m_nPutDoubleFactor; @@ -91,15 +99,24 @@ namespace NMR { __NMR_INLINE void putBeamUInt32(_In_ const nfUint32 nValue); __NMR_INLINE void putBeamDouble(_In_ const nfDouble dValue); + __NMR_INLINE void putBallString(_In_ const nfChar * pszString); + __NMR_INLINE void putBallUInt32(_In_ const nfUint32 nValue); + __NMR_INLINE void putBallDouble(_In_ const nfDouble dValue); + __NMR_INLINE void putBeamRefString(_In_ const nfChar * pszString); __NMR_INLINE void putBeamRefUInt32(_In_ const nfUint32 nValue); + __NMR_INLINE void putBallRefString(_In_ const nfChar * pszString); + __NMR_INLINE void putBallRefUInt32(_In_ const nfUint32 nValue); + __NMR_INLINE void writeVertexData(_In_ MESHNODE * pNode); __NMR_INLINE void writeFaceData_Plain(_In_ MESHFACE * pFace, _In_opt_ const nfChar * pszAdditionalString); __NMR_INLINE void writeFaceData_OneProperty(_In_ MESHFACE * pFace, _In_ const ModelResourceID nPropertyID, _In_ const ModelResourceIndex nPropertyIndex, _In_opt_ const nfChar * pszAdditionalString); __NMR_INLINE void writeFaceData_ThreeProperties(_In_ MESHFACE * pFace, _In_ const ModelResourceID nPropertyID, _In_ const ModelResourceIndex nPropertyIndex1, _In_ const ModelResourceIndex nPropertyIndex2, _In_ const ModelResourceIndex nPropertyIndex3, _In_opt_ const nfChar * pszAdditionalString); __NMR_INLINE void writeBeamData(_In_ MESHBEAM * pBeam, _In_ nfDouble dRadius, _In_ eModelBeamLatticeCapMode eDefaultCapMode); + __NMR_INLINE void writeBallData(_In_ MESHBALL * pBall, _In_ eModelBeamLatticeBallMode eBallMode, _In_ nfDouble dRadius); __NMR_INLINE void writeRefData(_In_ INT nRefID); + __NMR_INLINE void writeBallRefData(_In_ INT nRefID); public: CModelWriterNode100_Mesh() = delete; CModelWriterNode100_Mesh(_In_ CModelMeshObject * pModelMeshObject, _In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor, diff --git a/Include/Model/Writer/v100/NMR_ModelWriterNode100_Model.h b/Include/Model/Writer/v100/NMR_ModelWriterNode100_Model.h index ea05e1697..6ed375bb2 100644 --- a/Include/Model/Writer/v100/NMR_ModelWriterNode100_Model.h +++ b/Include/Model/Writer/v100/NMR_ModelWriterNode100_Model.h @@ -35,7 +35,7 @@ This is the class for exporting the 3mf model stream root node. #define __NMR_MODELWRITERNODE100_MODEL #include "Model/Classes/NMR_Model.h" -#include "Model/Writer/NMR_ModelWriterNode.h" +#include "Model/Writer/NMR_ModelWriterNode_ModelBase.h" #include "Model/Classes/NMR_ModelComponentsObject.h" #include "Model/Classes/NMR_ModelMeshObject.h" #include "Common/Platform/NMR_XmlWriter.h" @@ -45,10 +45,9 @@ This is the class for exporting the 3mf model stream root node. namespace NMR { - class CModelWriterNode100_Model : public CModelWriterNode { + class CModelWriterNode100_Model : public CModelWriterNode_ModelBase { protected: nfUint32 m_nDecimalPrecision; - ModelResourceID m_ResourceCounter; PMeshInformation_PropertyIndexMapping m_pPropertyIndexMapping; @@ -57,6 +56,7 @@ namespace NMR { nfBool m_bWriteBeamLatticeExtension; nfBool m_bWriteNurbsExtension; nfBool m_bWriteSliceExtension; + nfBool m_bWriteSecureContentExtension; nfBool m_bWriteBaseMaterials; nfBool m_bWriteObjects; nfBool m_bIsRootModel; @@ -84,8 +84,6 @@ namespace NMR { void writeComponentsObject(_In_ CModelComponentsObject * pComponentsObject); - ModelResourceID generateOutputResourceID(); - void RegisterMetaDataGroupNameSpaces(PModelMetaDataGroup mdg); void RegisterMetaDataNameSpaces(); diff --git a/Include/NMR_Spec_Version.h b/Include/NMR_Spec_Version.h index 8935ecd1c..7d3f75a9c 100644 --- a/Include/NMR_Spec_Version.h +++ b/Include/NMR_Spec_Version.h @@ -48,11 +48,15 @@ NMR_Spec_Version.h defines the current implementation version. #define NMR_SPECVERSION_PRODUCTION_MICRO 2 #define NMR_SPECVERSION_BEAMLATTICE_MAJOR 1 -#define NMR_SPECVERSION_BEAMLATTICE_MINOR 0 -#define NMR_SPECVERSION_BEAMLATTICE_MICRO 4 +#define NMR_SPECVERSION_BEAMLATTICE_MINOR 1 +#define NMR_SPECVERSION_BEAMLATTICE_MICRO 0 #define NMR_SPECVERSION_SLICE_MAJOR 1 #define NMR_SPECVERSION_SLICE_MINOR 0 #define NMR_SPECVERSION_SLICE_MICRO 2 +#define NMR_SPECVERSION_SECURECONTENT_MAJOR 1 +#define NMR_SPECVERSION_SECURECONTENT_MINOR 0 +#define NMR_SPECVERSION_SECURECONTENT_MICRO 2 + #endif // __NMR_SPECVERSION diff --git a/README.md b/README.md index 07ef675ce..c9621f974 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # lib3mf -[![Build Status](https://travis-ci.org/3MFConsortium/lib3mf.svg?branch=release%2F2.0.0)](https://travis-ci.org/3MFConsortium/lib3mf) +[![Build Status](https://travis-ci.org/3MFConsortium/lib3mf.svg?branch=release%2F2.1.0)](https://travis-ci.org/3MFConsortium/lib3mf) [![Documentation Status](https://readthedocs.org/projects/lib3mf/badge/?version=master)](https://readthedocs.org/projects/lib3mf) -[![Version 2.0.0](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.0.0&color=green)]() +[![Version 2.1.0](https://img.shields.io/static/v1.svg?label=lib3mf&message=v2.1.0&color=green)]() [![Supported platforms](https://img.shields.io/static/v1.svg?label=platform&message=windows%20%7C%20macos%20%7C%20linux&color=lightgrey)]() [![Simplified BSD License](https://img.shields.io/static/v1.svg?label=license&message=BSD&color=green)](LICENSE) @@ -37,3 +37,11 @@ lib3mf is an open source project and supported by the [3MF Consortium](https://3 Contributions are welcome and we are always looking for people that improve the implementation of the specification and extensions of 3MF. Have a look at the [contributor's guide](CONTRIBUTING.md) for details. This page also contains a section about building lib3mf from source or obtaining nightly snapshot builds. + +## Licenses and third party code +lib3mf is released under the [BSD license](LICENSE). The library contains code of the following [third parties](SDK/Credits.txt): +1. libzip 1.2.8, https://libzip.org/license/ +2. zlib 1.2.8, http://www.zlib.net/zlib_license.html +3. cpp-base64 1.01.00, https://github.com/ReneNyffenegger/cpp-base64/blob/master/LICENSE + +In addition, the automated tests of lib3mf make use of LibReSSL 3.0.2, [License](Tests/libressl/COPYING). diff --git a/SDK/.gitignore b/SDK/.gitignore index 93af157aa..cfab9db9a 100644 --- a/SDK/.gitignore +++ b/SDK/.gitignore @@ -3,3 +3,5 @@ Lib Include Bin Bindings +Examples/*/*.dll +Examples/*/*.stl diff --git a/SDK/Credits.txt b/SDK/Credits.txt index 7f78067ed..bb501944e 100644 --- a/SDK/Credits.txt +++ b/SDK/Credits.txt @@ -61,3 +61,25 @@ misrepresented as being the original software. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + +cpp-base64 1.01.00 +https://github.com/ReneNyffenegger/cpp-base64/blob/master/LICENSE +Copyright © 2004-2017 by René Nyffenegger + +This source code is provided 'as-is', without any express or implied +warranty. In no event will the author be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + +3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/SDK/Examples/CDynamic/CMakeLists.txt b/SDK/Examples/CDynamic/CMakeLists.txt index 32590e937..2e3ddb141 100644 --- a/SDK/Examples/CDynamic/CMakeLists.txt +++ b/SDK/Examples/CDynamic/CMakeLists.txt @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated CMake Project that demonstrates the usage of the C bindings of the 3MF Library -Interface version: 2.0.0 +Interface version: 2.1.0 ]] diff --git a/SDK/Examples/CDynamic/Source/Lib3MF_example.c b/SDK/Examples/CDynamic/Source/Lib3MF_example.c index 6d742310f..bf76de3c2 100644 --- a/SDK/Examples/CDynamic/Source/Lib3MF_example.c +++ b/SDK/Examples/CDynamic/Source/Lib3MF_example.c @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C application that demonstrates the usage of the C bindings of the 3MF Library -Interface version: 2.0.0 +Interface version: 2.1.0 */ diff --git a/SDK/Examples/CSharp/Lib3MF_Example.cs b/SDK/Examples/CSharp/Lib3MF_Example.cs index 2475d5383..cba7de8b6 100644 --- a/SDK/Examples/CSharp/Lib3MF_Example.cs +++ b/SDK/Examples/CSharp/Lib3MF_Example.cs @@ -24,12 +24,12 @@ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -This file has been generated by the Automatic Component Toolkit (ACT) version 1.5.0. +This file has been generated by the Automatic Component Toolkit (ACT) version 1.6.0. Abstract: This is an autogenerated CSharp application that demonstrates the usage of the CSharp bindings of the 3MF Library -Interface version: 2.0.0 +Interface version: 2.1.0 */ diff --git a/SDK/Examples/Cpp/CMakeLists.txt b/SDK/Examples/Cpp/CMakeLists.txt index 20b28a7de..f2d373e3f 100644 --- a/SDK/Examples/Cpp/CMakeLists.txt +++ b/SDK/Examples/Cpp/CMakeLists.txt @@ -46,6 +46,9 @@ CopySharedLibrary(Example_Converter) add_executable(Example_Cube Source/Cube.cpp) CopySharedLibrary(Example_Cube) +add_executable(Example_SecureCube Source/SecureCube.cpp) +CopySharedLibrary(Example_SecureCube) + add_executable(Example_ExtractInfo Source/ExtractInfo.cpp) CopySharedLibrary(Example_ExtractInfo) diff --git a/SDK/Examples/Cpp/Source/SecureCube.cpp b/SDK/Examples/Cpp/Source/SecureCube.cpp new file mode 100644 index 000000000..de966b61f --- /dev/null +++ b/SDK/Examples/Cpp/Source/SecureCube.cpp @@ -0,0 +1,487 @@ +/*++ + +Copyright (C) 2020 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICROSOFT AND/OR NETFABB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +SecureCube.cpp : 3MF encrypted Cube creation and read example. This is a sample +skeleton code provided to guide you to the process of reading and writing a 3MF +file using the Secure Content spec. Encryption and decryption processes are abstracted +so to avoid binding this sample to any particular implementation. If you would like +to check a working version of the process, there's a unit tests available on the 3MF code +base that implements the entire workflow using LibreSSL: EncryptionMethods.cpp +Tip: you could also copy buffers around - file won't be valid but you will be able +to run the entire process. +--*/ + +#include +#include +#include +#include + +#include "lib3mf_implicit.hpp" + +using namespace Lib3MF; + + +namespace SecureContentCallbacks { + // Sample random number generation callback. Do not use this beyond the scope of this example as it is not really a random number generation function. + static void NotRandomBytesAtAll(Lib3MF_uint64 byteData, Lib3MF_uint64 size, Lib3MF_pvoid userData, Lib3MF_uint64 * bytesWritten) { + static Lib3MF_uint8 random = 0; + Lib3MF_uint8 * buffer = (Lib3MF_uint8 *)byteData; + *bytesWritten = size; + while (size > 0) + *(buffer + (--size)) = ++random; + } + + // Structure to hold encryption context for keys + struct KeyWrappingCbData { + CWrapper * wrapper; + }; + + + // Structure to hold encryption context for resources + struct ContentEncryptionCbData { + CWrapper * wrapper; + std::map context; + }; + + // Sample callback to wrap the key of an encryption process + static void WriteKeyWrappingCbSample( + Lib3MF_AccessRight access, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeeded, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + KeyWrappingCbData * cp = (KeyWrappingCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CAccessRight accessRight(cp->wrapper, access); + cp->wrapper->Acquire(&accessRight); + + // This is going to be called for each consumer you've registered to + PConsumer consumer = accessRight.GetConsumer(); + std::string consumerId = consumer->GetConsumerID(); + std::cout << "ConsumerID " << consumer->GetConsumerID() << std::endl; + // You can also check for keyid and keyvalue + + // A call could be made to first identify what the output buffer size should be. + // In that case, outSize will be 0 or outBuffer will be null, and the proper size must be placed in outNeeded. + if (nullptr == outBuffer || outSize == 0) { + *outNeeded = inSize; + *status = inSize; + return; + } + + // Query the data about the encryption process to be done + eWrappingAlgorithm algorithm = accessRight.GetWrappingAlgorithm(); + eMgfAlgorithm mask = accessRight.GetMgfAlgorithm(); + eDigestMethod diges = accessRight.GetDigestMethod(); + + // You should deal with the encryption process of the key. + // Use the encryption process to wrap inBuffer (plain) into outBuffer (cipher) using details above. + // Use KeyWrappingCbData to hold any information you'll be needing at this point. + throw std::runtime_error("TODO: Add your encryption wrapping process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + + // Finally, this function should use status to return the number of bytes needed, + // encrypted - or zero to indicate a failure. + *status = outSize; + } + + // Sample callback to encrypt contents of a resource + static void WriteContentEncryptionCbSample( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeededSize, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + ContentEncryptionCbData * cb = (ContentEncryptionCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CContentEncryptionParams cd(cb->wrapper, params); + cb->wrapper->Acquire(&cd); + + // A descriptor uniquely identifies the encryption process for a resource + Lib3MF_uint64 descriptor = cd.GetDescriptor(); + + // You can map the descriptor in use as you'll probably keep several + // contexts initialized at same time + auto localDescriptor = cb->context.find(cd.GetDescriptor()); + if (localDescriptor != cb->context.end()) + // Use an existing context + localDescriptor->second++; + else { + // Initialize a new context + + // Retrieve the encryption key, if there is one + std::vector key; + cd.GetKey(key); + + // You can also use keyuuid to look up a key externally + std::string keyUUID = cd.GetKeyUUID(); + + // Retrieve the additional authenticaton data, if it has been used to encrypt + std::vector aad; + cd.GetAdditionalAuthenticationData(aad); + + // TODO: Initialize the encryption context + cb->context[cd.GetDescriptor()] = 0; + } + + // Attention to the order in which params are tested, it matters + if (0 == inSize || nullptr == inBuffer) { + // When input buffer is null or input size is 0, this is a request + // to finalize this encryption process and generating the authentication tag + // TODO: generate proper tag + std::vector tag = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + cd.SetAuthenticationTag(tag); + //add tag verification status here + *status = tag.size(); + } else if (0 == outSize || nullptr == outBuffer) { + // If outSize is zero or outBuffer is null (but inSize and inBuffer are not), + // this is a call to figure out the output buffer size. + // Put the respective value in outNeededSize. + *outNeededSize = inSize; + *status = inSize; + } else { + // Else, perform the encryption process + throw std::runtime_error("TODO: Add your encryption process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + *status = outSize; + } + //This function should use status to return the number of bytes needed, encrypted + // or verified - or zero to indicate a failure. + } + + static void ReadKeyWrappingCbSample( + Lib3MF_AccessRight access, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeeded, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + // A call could be made to first identify what the output buffer size should be. + // In that case, outSize will be 0 or outBuffer will be null, and the proper size must be placed in outNeeded. + if (nullptr == outBuffer || outSize == 0) { + *outNeeded = inSize; + *status = inSize; + return; + } + + KeyWrappingCbData * cp = (KeyWrappingCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CAccessRight accessRight(cp->wrapper, access); + cp->wrapper->Acquire(&accessRight); + + // This is going to be called for each consumer you've registered to + PConsumer consumer = accessRight.GetConsumer(); + std::string consumerId = consumer->GetConsumerID(); + std::cout << "ConsumerID " << consumer->GetConsumerID() << std::endl; + // You can also check for keyid and keyvalue + + // Query the data about the encryption process to be done + eWrappingAlgorithm algorithm = accessRight.GetWrappingAlgorithm(); + eMgfAlgorithm mask = accessRight.GetMgfAlgorithm(); + eDigestMethod diges = accessRight.GetDigestMethod(); + + // You should deal with the encryption process of the key. + // Use the encryption process to wrap inBuffer (cipher) into outBuffer (plain) using details above. + // Use KeyWrappingCbData to hold any information you'll be needing at this point. + throw std::runtime_error("TODO: Add your decryption wrapping process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + + // Finally, this function should use status to return the number of bytes needed, + // decrypted - or zero to indicate a failure. + *status = outSize; + } + + static void ReadContentEncryptionCbSample( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeededSize, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + ContentEncryptionCbData * cb = (ContentEncryptionCbData *)userData; + + // Since we're using CAccessRight constructure, we have to account for + // the use of 'access' by calling Acquire on the CWrapper + CContentEncryptionParams cd(cb->wrapper, params); + cb->wrapper->Acquire(&cd); + + // A descriptor uniquely identifies the encryption process for a resource + Lib3MF_uint64 descriptor = cd.GetDescriptor(); + + // You can map the descriptor in use as you'll probably keep several + // contexts initialized at same time + auto localDescriptor = cb->context.find(cd.GetDescriptor()); + if (localDescriptor != cb->context.end()) + // Use an existing context + localDescriptor->second++; + else { + // Initialize a new context + + // Retrieve the encryption key, if there is one + std::vector key; + cd.GetKey(key); + + // You can also use keyuuid to look up a key externally + std::string keyUUID = cd.GetKeyUUID(); + + // Retrieve the additional authenticaton data, if it has been used to encrypt + std::vector aad; + cd.GetAdditionalAuthenticationData(aad); + + // TODO: Initialize the encryption context + cb->context[cd.GetDescriptor()] = 0; + } + + // Attention to the order in which params are tested, it matters + if (0 == inSize || nullptr == inBuffer) { + // When input buffer is null or input size is 0, this is a request + // to finalize this encryption process and verify the authentication tag + std::vector tag; + cd.GetAuthenticationTag(tag); + // TODO: verify tag + *status = tag.size(); + } else if (0 == outSize || nullptr == outBuffer) { + // If outSize is zero or outBuffer is null (but inSize and inBuffer are not), + // this is a call to figure out the output buffer size. + // Put the respective value in outNeededSize. + *outNeededSize = inSize; + *status = inSize; + return; + } else { + // Else, perform the descryption process + throw std::runtime_error("TODO: Add your encryption process here"); + //std::copy(inBuffer, inBuffer + outSize, outBuffer); + *status = outSize; + } + //This function should use status to return the number of bytes needed, decrypted + // or verified - or zero to indicate a failure. + } +}; + +void printVersion(CWrapper & wrapper) { + Lib3MF_uint32 nMajor, nMinor, nMicro; + wrapper.GetLibraryVersion(nMajor, nMinor, nMicro); + std::cout << "lib3mf version = " << nMajor << "." << nMinor << "." << nMicro; + std::string sReleaseInfo, sBuildInfo; + if (wrapper.GetPrereleaseInformation(sReleaseInfo)) { + std::cout << "-" << sReleaseInfo; + } + if (wrapper.GetBuildInformation(sBuildInfo)) { + std::cout << "+" << sBuildInfo; + } + std::cout << std::endl; +} + +// Utility functions to create vertices and triangles +sLib3MFPosition fnCreateVertex(float x, float y, float z) { + sLib3MFPosition result; + result.m_Coordinates[0] = x; + result.m_Coordinates[1] = y; + result.m_Coordinates[2] = z; + return result; +} + +sLib3MFTriangle fnCreateTriangle(int v0, int v1, int v2) { + sLib3MFTriangle result; + result.m_Indices[0] = v0; + result.m_Indices[1] = v1; + result.m_Indices[2] = v2; + return result; +} + +void WriteSecureContentExample(CWrapper & wrapper) { + + PModel model = wrapper.CreateModel(); + + // After initializing the model, set the random number generation callback + // A default one will be used if you don't, current implementation uses std::mt19937 + model->SetRandomNumberCallback(SecureContentCallbacks::NotRandomBytesAtAll, nullptr); + + PMeshObject meshObject = model->AddMeshObject(); + meshObject->SetName("Box"); + + // Create mesh structure of a cube + std::vector vertices(8); + std::vector triangles(12); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + vertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + vertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + vertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + vertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + vertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + vertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + vertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + vertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + triangles[0] = fnCreateTriangle(2, 1, 0); + triangles[1] = fnCreateTriangle(0, 3, 2); + triangles[2] = fnCreateTriangle(4, 5, 6); + triangles[3] = fnCreateTriangle(6, 7, 4); + triangles[4] = fnCreateTriangle(0, 1, 5); + triangles[5] = fnCreateTriangle(5, 4, 0); + triangles[6] = fnCreateTriangle(2, 3, 7); + triangles[7] = fnCreateTriangle(7, 6, 2); + triangles[8] = fnCreateTriangle(1, 2, 6); + triangles[9] = fnCreateTriangle(6, 5, 1); + triangles[10] = fnCreateTriangle(3, 0, 4); + triangles[11] = fnCreateTriangle(4, 7, 3); + + meshObject->SetGeometry(vertices, triangles); + + // Add build item + model->AddBuildItem(meshObject.get(), wrapper.GetIdentityTransform()); + + // Move this mesh out of the root model file into another model + PPackagePart nonRootModel = model->FindOrCreatePackagePart("/3D/securecube.model"); + meshObject->SetPackagePart(nonRootModel.get()); + + // Locate the keystore and setup the resource as a secure content + PKeyStore keystore = model->GetKeyStore(); + + // Add you (client) as consumer of the resource. You'll need to do this + // to be able to have a chance to wrap the content key + // You can set optional public key and an optional key id + PConsumer consumer = keystore->AddConsumer("MyConsumerID", std::string(), std::string()); + + // Add a container for your secured resources. Resources within the same container will have a shared key. + PResourceDataGroup dataGroup = keystore->AddResourceDataGroup(); + + // Add access rights for your consumer into the datagroup + PAccessRight accessRight = dataGroup->AddAccessRight(consumer.get(), eWrappingAlgorithm::RSA_OAEP, eMgfAlgorithm::MGF1_SHA1, eDigestMethod::SHA1); + + // Specify additional authentication data that you could use to further validate your encryption process + std::vector aad = { '3','M','F','C','o','n','s','o','r','t','i','u','m',' ','S','a','m','p','l','e' }; + + // This will effectively add your nonRootModel as a secure content + PResourceData resourceData = keystore->AddResourceData(dataGroup.get(), nonRootModel.get(), eEncryptionAlgorithm::AES256_GCM, eCompression::Deflate, aad); + + // Query the writer and setup the encryption before saving results + PWriter writer = model->QueryWriter("3mf"); + + // Setup Key Wrapping process + SecureContentCallbacks::KeyWrappingCbData keyData; + keyData.wrapper = &wrapper; + writer->AddKeyWrappingCallback(consumer->GetConsumerID(), SecureContentCallbacks::WriteKeyWrappingCbSample, &keyData); + + // Content Encryption process + SecureContentCallbacks::ContentEncryptionCbData contentData; + contentData.wrapper = &wrapper; + writer->SetContentEncryptionCallback(SecureContentCallbacks::WriteContentEncryptionCbSample, &contentData); + + // You'll need to complete the callback code for this call to work properly. + writer->WriteToFile("secureCube.3mf"); + + std::cout << "Writing Done." << std::endl; +} + +void ReadSecureContentExample(CWrapper & wrapper) { + PModel model = wrapper.CreateModel(); + + // After initializing the model, set the random number generation callback + // A default one will be used if you don't, current implementation uses std::mt19937 + model->SetRandomNumberCallback(SecureContentCallbacks::NotRandomBytesAtAll, nullptr); + + // Query the reader and setup the encryption before saving results + PReader reader = model->QueryReader("3mf"); + + // Setup Key Wrapping process + SecureContentCallbacks::KeyWrappingCbData keyData; + keyData.wrapper = &wrapper; + reader->AddKeyWrappingCallback("MyConsumerID", SecureContentCallbacks::ReadKeyWrappingCbSample, &keyData); + + // Content Encryption process + SecureContentCallbacks::ContentEncryptionCbData contentData; + contentData.wrapper = &wrapper; + reader->SetContentEncryptionCallback(SecureContentCallbacks::ReadContentEncryptionCbSample, &contentData); + + // You'll need to complete the callback code for this call to work properly. + reader->ReadFromFile("secureCube.3mf"); + + PKeyStore keystore = model->GetKeyStore(); + + // If you know the part you're interested in, look for its resource data + PPackagePart partPath = model->FindOrCreatePackagePart("/3D/securecube.model"); + PResourceData resourceData = keystore->FindResourceData(partPath.get()); + + // You can retrieve additional authenticated data using in the encryption + // to further verify the consistency of the process. At this time, it is + // already verified. + std::vector aad; + resourceData->GetAdditionalAuthenticationData(aad); + std::cout << "Additional Authenticated Data: "; + for (auto it = aad.begin(); it != aad.end(); ++it) { + std::cout << (char)*it; + } + std::cout << std::endl; + + std::cout << "Reading Done." << std::endl; + +} + +int main() { + PWrapper wrapper = CWrapper::loadLibrary(); + + std::cout << "------------------------------------------------------------------" << std::endl; + std::cout << "3MF SecureContent example" << std::endl; + printVersion(*wrapper); + std::cout << "------------------------------------------------------------------" << std::endl; + + try { + WriteSecureContentExample(*wrapper); + ReadSecureContentExample(*wrapper); + } catch (ELib3MFException &e) { + std::cout << e.what() << std::endl; + return e.getErrorCode(); + } + return 0; +} diff --git a/SDK/Examples/CppDynamic/CMakeLists.txt b/SDK/Examples/CppDynamic/CMakeLists.txt index aee3b694c..357fa48a8 100644 --- a/SDK/Examples/CppDynamic/CMakeLists.txt +++ b/SDK/Examples/CppDynamic/CMakeLists.txt @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated CMake Project that demonstrates the usage of the Dynamic C++ bindings of the 3MF Library -Interface version: 2.0.0 +Interface version: 2.1.0 ]] diff --git a/SDK/Examples/NodeJS/Readme.md b/SDK/Examples/NodeJS/Readme.md new file mode 100644 index 000000000..678fa41c9 --- /dev/null +++ b/SDK/Examples/NodeJS/Readme.md @@ -0,0 +1,19 @@ +## How to run this example + +Note that the NodeJS bindings are experimental. The _should_ work with Node v12.13 on Windows. + +1. Install node +2. Install Visual Studio 2019 +3. Install node-gyp + + ```npm install -g node-gyp``` + +4. In the folder `../../Bindings/NodeJS` run + + ```node-gyp rebuild --verbose binding.gyp``` + +5. modify `readwrite.js` to point to the generated node-addon, e.g. in `../../Bindings/NodeJS/build/Release`, and to the `lib3mf`-binary, e.g. `'../../Bin/lib3mf.dll'`. + +6. run the example + + ```node readwrite.js``` diff --git a/SDK/Examples/NodeJS/readwrite.js b/SDK/Examples/NodeJS/readwrite.js new file mode 100644 index 000000000..32aff09e0 --- /dev/null +++ b/SDK/Examples/NodeJS/readwrite.js @@ -0,0 +1,20 @@ +console.log("Loading Lib3MF"); + +var wrapper = require('../../Bindings/NodeJS/build/Release/lib3mf_nodeaddon')('../../Bin/lib3mf.dll'); + +console.log("creating Model"); +model = wrapper.CreateModel(); + +console.log("creating Reader"); +reader = model.QueryReader("3mf"); + +console.log("load 3MF file"); +reader.ReadFromFile("../Files/Helix.3mf"); + +console.log("creating Writer"); +writer = model.QueryWriter("stl"); + +console.log("write stl file"); +writer.WriteToFile("Helix.stl"); + +console.log("done"); diff --git a/SDK/Examples/Pascal/Lib3MF_Example.lpr b/SDK/Examples/Pascal/Lib3MF_Example.lpr index 2155a40bf..cfff69657 100644 --- a/SDK/Examples/Pascal/Lib3MF_Example.lpr +++ b/SDK/Examples/Pascal/Lib3MF_Example.lpr @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Pascal application that demonstrates the usage of the Pascal bindings of the 3MF Library -Interface version: 2.0.0 +Interface version: 2.1.0 *) diff --git a/SDK/Examples/Python/Lib3MF_Example.py b/SDK/Examples/Python/Lib3MF_Example.py index 587796557..e4bd0b6d3 100644 --- a/SDK/Examples/Python/Lib3MF_Example.py +++ b/SDK/Examples/Python/Lib3MF_Example.py @@ -29,7 +29,7 @@ Abstract: This is an autogenerated Python application that demonstrates the usage of the Python bindings of the 3MF Library -Interface version: 2.0.0 +Interface version: 2.1.0 ''' diff --git a/SDK/Readme.md b/SDK/Readme.md index 596b92385..82b6c687e 100644 --- a/SDK/Readme.md +++ b/SDK/Readme.md @@ -18,4 +18,4 @@ The specification can be downloaded at ## Documentation -lib3mf's documentation is available on https://lib3mf.readthedocs.io or as PDF in [Documentation/lib3mf_v2.0.0.pdf](Documentation/lib3mf_v2.0.0.pdf). +lib3mf's documentation is available on https://lib3mf.readthedocs.io or as PDF in [Documentation/lib3mf_v2.1.0.pdf](Documentation/lib3mf_v2.1.0.pdf). diff --git a/Source/API/lib3mf.cpp b/Source/API/lib3mf.cpp index 0b26e6b78..f93a130f6 100644 --- a/Source/API/lib3mf.cpp +++ b/Source/API/lib3mf.cpp @@ -29,7 +29,7 @@ This file has been generated by the Automatic Component Toolkit (ACT) version 1. Abstract: This is an autogenerated C++ implementation file in order to allow easy development of the 3MF Library. It needs to be generated only once. -Interface version: 2.0.0 +Interface version: 2.1.0 */ @@ -89,12 +89,19 @@ void CWrapper::GetSpecificationVersion (const std::string & sSpecificationURL, b nMinor = NMR_SPECVERSION_BEAMLATTICE_MINOR; nMicro = NMR_SPECVERSION_BEAMLATTICE_MICRO; bIsSupported = true; - } else if (!sSpecificationURL.compare(std::string(XML_3MF_NAMESPACE_SLICESPEC) )) { + } + else if (!sSpecificationURL.compare(std::string(XML_3MF_NAMESPACE_SLICESPEC))) { nMajor = NMR_SPECVERSION_SLICE_MAJOR; nMinor = NMR_SPECVERSION_SLICE_MINOR; nMicro = NMR_SPECVERSION_SLICE_MICRO; bIsSupported = true; } + else if (!sSpecificationURL.compare(std::string(XML_3MF_NAMESPACE_SECURECONTENTSPEC))) { + nMajor = NMR_SPECVERSION_SECURECONTENT_MAJOR; + nMinor = NMR_SPECVERSION_SECURECONTENT_MINOR; + nMicro = NMR_SPECVERSION_SECURECONTENT_MICRO; + bIsSupported = true; + } else { bIsSupported = false; } @@ -250,3 +257,4 @@ sLib3MFTransform CWrapper::GetTranslationTransform(const Lib3MF_single fVectorX, return Transform; } + diff --git a/Source/API/lib3mf_accessright.cpp b/Source/API/lib3mf_accessright.cpp new file mode 100644 index 000000000..db61aa1f7 --- /dev/null +++ b/Source/API/lib3mf_accessright.cpp @@ -0,0 +1,32 @@ +#include "lib3mf_accessright.hpp" +#include "lib3mf_interfaceexception.hpp" +#include "lib3mf_consumer.hpp" + +using namespace Lib3MF::Impl; + +Lib3MF::Impl::CAccessRight::CAccessRight(NMR::PKeyStoreAccessRight ar) { + m_pAccessRight = ar; +} + +IConsumer * Lib3MF::Impl::CAccessRight::GetConsumer() { + return new CConsumer(m_pAccessRight->getConsumer()); +} + +Lib3MF::eWrappingAlgorithm Lib3MF::Impl::CAccessRight::GetWrappingAlgorithm() { + NMR::eKeyStoreWrapAlgorithm ea = m_pAccessRight->getAlgorithm(); + return static_cast(ea); +} + +Lib3MF::eMgfAlgorithm Lib3MF::Impl::CAccessRight::GetMgfAlgorithm() { + NMR::eKeyStoreMaskGenerationFunction mgf = m_pAccessRight->getMgf(); + return static_cast(mgf); +} + +Lib3MF::eDigestMethod Lib3MF::Impl::CAccessRight::GetDigestMethod() { + NMR::eKeyStoreMessageDigest digest = m_pAccessRight->getDigest(); + return static_cast(digest); +} + +NMR::PKeyStoreAccessRight Lib3MF::Impl::CAccessRight::accessRight() const { + return m_pAccessRight; +} \ No newline at end of file diff --git a/Source/API/lib3mf_attachment.cpp b/Source/API/lib3mf_attachment.cpp index 158640d62..7fde89103 100644 --- a/Source/API/lib3mf_attachment.cpp +++ b/Source/API/lib3mf_attachment.cpp @@ -70,6 +70,11 @@ void CAttachment::SetPath (const std::string & sPath) } } +IPackagePart * CAttachment::PackagePart() +{ + throw ELib3MFInterfaceException(LIB3MF_ERROR_NOTIMPLEMENTED); +} + std::string CAttachment::GetRelationShipType () { return m_pModelAttachment->getRelationShipType(); diff --git a/Source/API/lib3mf_beamlattice.cpp b/Source/API/lib3mf_beamlattice.cpp index 16f4000f1..53942b71c 100644 --- a/Source/API/lib3mf_beamlattice.cpp +++ b/Source/API/lib3mf_beamlattice.cpp @@ -57,29 +57,29 @@ void CBeamLattice::SetMinLength (const Lib3MF_double dMinLength) return m_mesh.setBeamLatticeMinLength(dMinLength); } -void CBeamLattice::GetClipping (eLib3MFBeamLatticeClipMode & eClipMode, Lib3MF_uint32 & nResourceID) +void CBeamLattice::GetClipping(eLib3MFBeamLatticeClipMode & eClipMode, Lib3MF_uint32 & nUniqueResourceID) { if (!m_pAttributes->m_bHasClippingMeshID) { eClipMode = eBeamLatticeClipMode::NoClipMode; - nResourceID = 0; + nUniqueResourceID = 0; } else { eClipMode = eBeamLatticeClipMode(m_pAttributes->m_eClipMode); - nResourceID = m_pAttributes->m_nClippingMeshID->getUniqueID(); + nUniqueResourceID = m_pAttributes->m_pClippingMeshUniqueID->getUniqueID(); } } -void CBeamLattice::SetClipping (const eLib3MFBeamLatticeClipMode eClipMode, const Lib3MF_uint32 nResourceID) +void CBeamLattice::SetClipping(const eLib3MFBeamLatticeClipMode eClipMode, const Lib3MF_uint32 nUniqueResourceID) { - if ( ((int)eClipMode == (NMR::eModelBeamLatticeClipMode::MODELBEAMLATTICECLIPMODE_NONE)) || (nResourceID == 0) ){ + if ( ((int)eClipMode == (NMR::eModelBeamLatticeClipMode::MODELBEAMLATTICECLIPMODE_NONE)) || (nUniqueResourceID == 0) ){ m_pAttributes->m_eClipMode = NMR::eModelBeamLatticeClipMode(eClipMode); m_pAttributes->m_bHasClippingMeshID = false; - m_pAttributes->m_nClippingMeshID = nullptr; + m_pAttributes->m_pClippingMeshUniqueID = nullptr; } else { NMR::CModel* pModel = m_pMeshObject->getModel(); - NMR::CModelMeshObject * pClippingObject = dynamic_cast(pModel->findObject(nResourceID)); + NMR::CModelMeshObject * pClippingObject = dynamic_cast(pModel->findObject(nUniqueResourceID)); if (pClippingObject == nullptr) { throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); } @@ -91,32 +91,32 @@ void CBeamLattice::SetClipping (const eLib3MFBeamLatticeClipMode eClipMode, cons m_pAttributes->m_eClipMode = NMR::eModelBeamLatticeClipMode(eClipMode);; m_pAttributes->m_bHasClippingMeshID = true; - m_pAttributes->m_nClippingMeshID = pClippingObject->getResourceID(); + m_pAttributes->m_pClippingMeshUniqueID = pClippingObject->getPackageResourceID(); } } -bool CBeamLattice::GetRepresentation (Lib3MF_uint32 & nResourceID) +bool CBeamLattice::GetRepresentation (Lib3MF_uint32 & nUniqueResourceID) { if (m_pAttributes->m_bHasRepresentationMeshID) { - nResourceID = m_pAttributes->m_nRepresentationID->getUniqueID(); + nUniqueResourceID = m_pAttributes->m_pRepresentationUniqueID->getUniqueID(); return true; } else { - nResourceID = 0; + nUniqueResourceID = 0; return false; } } -void CBeamLattice::SetRepresentation (const Lib3MF_uint32 nResourceID) +void CBeamLattice::SetRepresentation (const Lib3MF_uint32 nUniqueResourceID) { - if (nResourceID == 0) { + if (nUniqueResourceID == 0) { m_pAttributes->m_bHasRepresentationMeshID = false; - m_pAttributes->m_nRepresentationID = nullptr; + m_pAttributes->m_pRepresentationUniqueID = nullptr; } else { NMR::CModel* pModel = m_pMeshObject->getModel(); - NMR::CModelMeshObject * pRepresentationObject = dynamic_cast(pModel->findObject(nResourceID)); + NMR::CModelMeshObject * pRepresentationObject = dynamic_cast(pModel->findObject(nUniqueResourceID)); if (pRepresentationObject == nullptr) { throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); } @@ -127,7 +127,24 @@ void CBeamLattice::SetRepresentation (const Lib3MF_uint32 nResourceID) } m_pAttributes->m_bHasRepresentationMeshID = true; - m_pAttributes->m_nRepresentationID = pRepresentationObject->getResourceID(); + m_pAttributes->m_pRepresentationUniqueID = pRepresentationObject->getPackageResourceID(); + } +} + +void CBeamLattice::GetBallOptions (eLib3MFBeamLatticeBallMode & eBallMode, Lib3MF_double & dBallRadius) +{ + eBallMode = (eLib3MFBeamLatticeBallMode)m_mesh.getBeamLatticeBallMode(); + dBallRadius = m_mesh.getDefaultBallRadius(); +} + +void CBeamLattice::SetBallOptions (const eLib3MFBeamLatticeBallMode eBallMode, const Lib3MF_double dBallRadius) +{ + if (eBallMode == eLib3MFBeamLatticeBallMode::None || dBallRadius > 0.0) { + m_mesh.setBeamLatticeBallMode((NMR::eModelBeamLatticeBallMode)eBallMode); + m_mesh.setDefaultBallRadius(dBallRadius); + } + else { + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); } } @@ -196,6 +213,10 @@ void CBeamLattice::SetBeam (const Lib3MF_uint32 nIndex, const sLib3MFBeam BeamIn meshBeam->m_radius[0] = BeamInfo.m_Radii[0]; meshBeam->m_radius[1] = BeamInfo.m_Radii[1]; + + // Occupied nodes may have changed, need to validate + m_mesh.scanOccupiedNodes(); + m_mesh.validateBeamLatticeBalls(); } void CBeamLattice::SetBeams(const Lib3MF_uint64 nBeamInfoBufferSize, const sLib3MFBeam * pBeamInfoBuffer) @@ -203,7 +224,7 @@ void CBeamLattice::SetBeams(const Lib3MF_uint64 nBeamInfoBufferSize, const sLib3 if ((nBeamInfoBufferSize>0) && (!m_pMeshObject->isValidForBeamLattices())) throw ELib3MFInterfaceException(LIB3MF_ERROR_BEAMLATTICE_INVALID_OBJECTTYPE); - m_mesh.clearBeamLattice(); + m_mesh.clearBeamLatticeBeams(); const sLib3MFBeam* pBeamInfoCurrent = pBeamInfoBuffer; for (Lib3MF_uint32 nIndex = 0; nIndex < nBeamInfoBufferSize; nIndex++) @@ -219,6 +240,8 @@ void CBeamLattice::SetBeams(const Lib3MF_uint64 nBeamInfoBufferSize, const sLib3 pBeamInfoCurrent++; } + // Occupied nodes may have changed, need to validate + m_mesh.validateBeamLatticeBalls(); } void CBeamLattice::GetBeams(Lib3MF_uint64 nBeamInfoBufferSize, Lib3MF_uint64* pBeamInfoNeededCount, sLib3MFBeam * pBeamInfoBuffer) @@ -246,6 +269,206 @@ void CBeamLattice::GetBeams(Lib3MF_uint64 nBeamInfoBufferSize, Lib3MF_uint64* pB } } +Lib3MF_uint32 CBeamLattice::GetBallCount () +{ + eBeamLatticeBallMode ballMode = (eBeamLatticeBallMode)m_mesh.getBeamLatticeBallMode(); + + if (ballMode == eBeamLatticeBallMode::Mixed) { + return m_mesh.getBallCount(); + } + else if (ballMode == eBeamLatticeBallMode::All) { + return m_mesh.getOccupiedNodeCount(); + } + else { + return 0; + } +} + +sLib3MFBall CBeamLattice::GetBall (const Lib3MF_uint32 nIndex) +{ + sLib3MFBall ball; + + eBeamLatticeBallMode ballMode; + Lib3MF_double defaultBallRadius; + GetBallOptions(ballMode, defaultBallRadius); + + Lib3MF_uint32 ballCount = GetBallCount(); + if (nIndex >= ballCount) { + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDRESOURCEINDEX); + } + + if (ballMode == eBeamLatticeBallMode::Mixed) { + NMR::MESHBALL * meshBall = m_mesh.getBall(nIndex); + + ball.m_Index = meshBall->m_nodeindex; + + ball.m_Radius = meshBall->m_radius; + + return ball; + } + else if (ballMode == eBeamLatticeBallMode::All) { + Lib3MF_uint32 ballNodeIndex = m_mesh.getOccupiedNode(nIndex)->m_index; + + Lib3MF_uint32 meshBallCount = m_mesh.getBallCount(); + for (Lib3MF_uint32 iBall = 0; iBall < meshBallCount; iBall++) { + NMR::MESHBALL * meshBall = m_mesh.getBall(iBall); + + if (meshBall->m_nodeindex == ballNodeIndex) { + ball.m_Index = meshBall->m_nodeindex; + + ball.m_Radius = meshBall->m_radius; + + return ball; + } + } + + ball.m_Index = ballNodeIndex; + + ball.m_Radius = defaultBallRadius; + + return ball; + } + else { + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + } +} + +bool isBallValid(const Lib3MF_uint32 nNodeCount, const sLib3MFBall& BallInfo) +{ + if (BallInfo.m_Index >= nNodeCount) + return false; + if (BallInfo.m_Radius <= 0) + return false; + return true; +} + +Lib3MF_uint32 CBeamLattice::AddBall (const sLib3MFBall BallInfo) +{ + if (!m_pMeshObject->isValidForBeamLattices()) + throw ELib3MFInterfaceException(LIB3MF_ERROR_BEAMLATTICE_INVALID_OBJECTTYPE); + + // Check for input validity + if (!isBallValid(m_mesh.getNodeCount(), BallInfo)) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + + // retrieve node and add ball + NMR::MESHNODE * pNode = m_mesh.getNode(BallInfo.m_Index); + + NMR::MESHBALL * pMeshBall = m_mesh.addBall(pNode, BallInfo.m_Radius); + return pMeshBall->m_index; +} + +void CBeamLattice::SetBall (const Lib3MF_uint32 nIndex, const sLib3MFBall BallInfo) +{ + if (!isBallValid(m_mesh.getNodeCount(), BallInfo)) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + + if (!m_mesh.isNodeOccupied(BallInfo.m_Index)) { + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + } + + eBeamLatticeBallMode ballMode = (eBeamLatticeBallMode(m_mesh.getBeamLatticeBallMode())); + + if (ballMode == eBeamLatticeBallMode::Mixed) { + NMR::MESHBALL * meshBall = m_mesh.getBall(nIndex); + + meshBall->m_nodeindex = BallInfo.m_Index; + + meshBall->m_radius = BallInfo.m_Radius; + } + else if (ballMode == eBeamLatticeBallMode::All) { + Lib3MF_uint32 ballNodeIndex = m_mesh.getOccupiedNode(nIndex)->m_index; + Lib3MF_uint32 meshBallCount = m_mesh.getBallCount(); + for (Lib3MF_uint32 iBall = 0; iBall < meshBallCount; iBall++) { + NMR::MESHBALL * meshBall = m_mesh.getBall(iBall); + + if (meshBall->m_nodeindex == ballNodeIndex) { + meshBall->m_nodeindex = BallInfo.m_Index; + meshBall->m_radius = BallInfo.m_Radius; + return; + } + } + + // Not in mesh, add the ball + NMR::MESHNODE * pNode = m_mesh.getNode(BallInfo.m_Index); + + m_mesh.addBall(pNode, BallInfo.m_Radius); + } + else { + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + } +} + +void CBeamLattice::SetBalls (const Lib3MF_uint64 nBallInfoBufferSize, const sLib3MFBall * pBallInfoBuffer) +{ + if ((nBallInfoBufferSize > 0) && (!m_pMeshObject->isValidForBeamLattices())) + throw ELib3MFInterfaceException(LIB3MF_ERROR_BEAMLATTICE_INVALID_OBJECTTYPE); + + m_mesh.clearBeamLatticeBalls(); + + const sLib3MFBall * pBallInfoCurrent = pBallInfoBuffer; + for (Lib3MF_uint32 nIndex = 0; nIndex < nBallInfoBufferSize; nIndex++) + { + if (!isBallValid(m_mesh.getNodeCount(), *pBallInfoCurrent)) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + + NMR::MESHNODE * pNode = m_mesh.getNode(pBallInfoCurrent->m_Index); + + m_mesh.addBall(pNode, pBallInfoCurrent->m_Radius); + pBallInfoCurrent++; + } +} + +void CBeamLattice::GetBalls(Lib3MF_uint64 nBallInfoBufferSize, Lib3MF_uint64 * pBallInfoNeededCount, sLib3MFBall * pBallInfoBuffer) +{ + Lib3MF_uint32 ballCount = GetBallCount(); + if (pBallInfoNeededCount) + *pBallInfoNeededCount = ballCount; + + if (nBallInfoBufferSize >= ballCount && pBallInfoBuffer) { + eBeamLatticeBallMode ballMode; + Lib3MF_double defaultBallRadius; + GetBallOptions(ballMode, defaultBallRadius); + + if (ballMode == eBeamLatticeBallMode::Mixed) { + sLib3MFBall * ball = pBallInfoBuffer; + for (Lib3MF_uint32 iBall = 0; iBall < ballCount; iBall++) { + const NMR::MESHBALL * meshBall = m_mesh.getBall(iBall); + + ball->m_Index = meshBall->m_nodeindex; + + ball->m_Radius = meshBall->m_radius; + ball++; + } + } + else if (ballMode == eBeamLatticeBallMode::All) { + Lib3MF_uint32 meshBallCount = m_mesh.getBallCount(); + + // Sort balls that are in the mesh into a map by node index + std::map meshBallMap; + for (Lib3MF_uint32 iBall = 0; iBall < meshBallCount; iBall++) { + const NMR::MESHBALL * meshBall = m_mesh.getBall(iBall); + + meshBallMap[meshBall->m_nodeindex] = meshBall->m_radius; + } + + // Fill balls from default or mesh balls + sLib3MFBall * ball = pBallInfoBuffer; + for (Lib3MF_uint32 i = 0; i < ballCount; i++) { + Lib3MF_uint32 currNodeIndex = m_mesh.getOccupiedNode(i)->m_index; + + ball->m_Index = currNodeIndex; + ball->m_Radius = meshBallMap[currNodeIndex] > 0.0 ? meshBallMap[currNodeIndex] : defaultBallRadius; + + ball++; + } + } + else { + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + } + } +} + Lib3MF_uint32 CBeamLattice::GetBeamSetCount () { return m_mesh.getBeamSetCount(); diff --git a/Source/API/lib3mf_beamset.cpp b/Source/API/lib3mf_beamset.cpp index 8616903df..0a96cb15b 100644 --- a/Source/API/lib3mf_beamset.cpp +++ b/Source/API/lib3mf_beamset.cpp @@ -58,6 +58,14 @@ std::string CBeamSet::GetName() void CBeamSet::SetIdentifier(const std::string & sIdentifier) { + // Ensure identifier is unique + if (sIdentifier.compare("") != 0) { + Lib3MF_uint32 nBeamSets = m_mesh.getBeamSetCount(); + for (Lib3MF_uint32 iBeamSet = 0; iBeamSet < nBeamSets; iBeamSet++) + if (sIdentifier.compare(m_mesh.getBeamSet(iBeamSet)->m_sIdentifier) == 0) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + } + m_pBeamSet->m_sIdentifier = sIdentifier; } @@ -100,3 +108,33 @@ void CBeamSet::GetReferences(Lib3MF_uint64 nReferencesBufferSize, Lib3MF_uint64* } } +Lib3MF_uint32 CBeamSet::GetBallReferenceCount() +{ + return (Lib3MF_uint32)m_pBeamSet->m_BallRefs.size(); +} + +void CBeamSet::SetBallReferences(const Lib3MF_uint64 nBallReferencesBufferSize, const Lib3MF_uint32* pBallReferencesBuffer) +{ + m_pBeamSet->m_BallRefs.resize(nBallReferencesBufferSize); + const Lib3MF_uint32 ballCount = m_mesh.getBallCount(); + for (Lib3MF_uint64 i = 0; i < nBallReferencesBufferSize; i++) { + if (ballCount <= pBallReferencesBuffer[i]) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + m_pBeamSet->m_BallRefs[i] = Lib3MF_uint32(pBallReferencesBuffer[i]); + } +} + +void CBeamSet::GetBallReferences(Lib3MF_uint64 nBallReferencesBufferSize, Lib3MF_uint64* pBallReferencesNeededCount, Lib3MF_uint32* pBallReferencesBuffer) +{ + Lib3MF_uint32 ballReferenceCount = GetBallReferenceCount(); + if (pBallReferencesNeededCount) + *pBallReferencesNeededCount = ballReferenceCount; + + if (nBallReferencesBufferSize >= ballReferenceCount && pBallReferencesBuffer) { + Lib3MF_uint32* pBallRef = pBallReferencesBuffer; + for (Lib3MF_uint32 i = 0; i < ballReferenceCount; i++) { + *pBallRef = m_pBeamSet->m_BallRefs[i]; + pBallRef++; + } + } +} diff --git a/Source/API/lib3mf_builditem.cpp b/Source/API/lib3mf_builditem.cpp index ceb247255..a7d414984 100644 --- a/Source/API/lib3mf_builditem.cpp +++ b/Source/API/lib3mf_builditem.cpp @@ -59,7 +59,7 @@ Lib3MF_uint32 CBuildItem::GetHandle() IObject * CBuildItem::GetObjectResource () { - NMR::PModelResource pResource = buildItem().getModel()->findResource(buildItem().getObjectID()); + NMR::PModelResource pResource = buildItem().getModel()->findResource(buildItem().getObject()->getPackageResourceID()); if (!pResource.get()) throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDMODELRESOURCE); @@ -84,9 +84,9 @@ void CBuildItem::SetUUID (const std::string & sUUID) buildItem().setUUID(pUUID); } -Lib3MF_uint32 CBuildItem::GetObjectResourceID () +Lib3MF_uint32 CBuildItem::GetObjectResourceID() { - return buildItem().getObjectID(); + return buildItem().getObject()->getPackageResourceID()->getUniqueID(); } bool CBuildItem::HasObjectTransform () diff --git a/Source/API/lib3mf_component.cpp b/Source/API/lib3mf_component.cpp index 8bb1d152c..2230dcd1c 100644 --- a/Source/API/lib3mf_component.cpp +++ b/Source/API/lib3mf_component.cpp @@ -51,7 +51,7 @@ CComponent::CComponent(NMR::PModelComponent pComponent) IObject * CComponent::GetObjectResource() { - NMR::PModelResource pModelObject = m_pComponent->getModel()->findResource(m_pComponent->getObjectID()); + NMR::PModelResource pModelObject = m_pComponent->getModel()->findResource(m_pComponent->getObject()->getPackageResourceID()); if (!pModelObject.get()) throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDMODELRESOURCE); @@ -62,9 +62,9 @@ IObject * CComponent::GetObjectResource() return pObject.release(); } -Lib3MF_uint32 CComponent::GetObjectResourceID () +Lib3MF_uint32 CComponent::GetObjectResourceID() { - return m_pComponent->getObjectID(); + return m_pComponent->getObject()->getPackageResourceID()->getUniqueID(); } std::string CComponent::GetUUID(bool & bHasUUID) diff --git a/Source/API/lib3mf_componentsobject.cpp b/Source/API/lib3mf_componentsobject.cpp index e2fdbf8ef..6c0658b5e 100644 --- a/Source/API/lib3mf_componentsobject.cpp +++ b/Source/API/lib3mf_componentsobject.cpp @@ -74,7 +74,7 @@ NMR::CModelComponentsObject * CComponentsObject::getComponentsObject() return pComponentsObject; } -IComponent * CComponentsObject::AddComponent (IObject* pObjectResource, const sLib3MFTransform Transform) +IComponent * CComponentsObject::AddComponent(IObject* pObjectResource, const sLib3MFTransform Transform) { NMR::CModelComponentsObject * pComponentsObject = getComponentsObject(); NMR::CModel * pModel = pComponentsObject->getModel(); @@ -82,7 +82,7 @@ IComponent * CComponentsObject::AddComponent (IObject* pObjectResource, const sL throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDMODEL); // Get Resource ID - NMR::PackageResourceID nObjectID = pObjectResource->GetResourceID(); + NMR::UniqueResourceID nObjectID = pObjectResource->GetResourceID(); if (GetResourceID() == nObjectID) throw ELib3MFInterfaceException(LIB3MF_ERROR_FORBIDDENCYCLICREFERENCE); diff --git a/Source/API/lib3mf_consumer.cpp b/Source/API/lib3mf_consumer.cpp new file mode 100644 index 000000000..beb85f39a --- /dev/null +++ b/Source/API/lib3mf_consumer.cpp @@ -0,0 +1,22 @@ +#include "lib3mf_consumer.hpp" +#include "lib3mf_interfaceexception.hpp" +#include "Model/Classes/NMR_KeyStoreConsumer.h" + + +using namespace Lib3MF::Impl; + +Lib3MF::Impl::CConsumer::CConsumer(NMR::PKeyStoreConsumer const & consumer) { + m_Consumer = consumer; +} + +std::string Lib3MF::Impl::CConsumer::GetConsumerID() { + return m_Consumer->getConsumerID(); +} + +std::string Lib3MF::Impl::CConsumer::GetKeyID() { + return m_Consumer->getKeyID(); +} + +std::string Lib3MF::Impl::CConsumer::GetKeyValue() { + return m_Consumer->getKeyValue(); +} diff --git a/Source/API/lib3mf_contentencryptionparams.cpp b/Source/API/lib3mf_contentencryptionparams.cpp new file mode 100644 index 000000000..f43194099 --- /dev/null +++ b/Source/API/lib3mf_contentencryptionparams.cpp @@ -0,0 +1,73 @@ +#include "lib3mf_contentencryptionparams.hpp" +#include "lib3mf_interfaceexception.hpp" + +using namespace Lib3MF::Impl; + + +namespace Lib3MF { + namespace Impl { + CContentEncryptionParams::CContentEncryptionParams(NMR::PCKeyStoreContentEncryptionParams const & p): m_pParams(p) { + if (!p) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + } + + Lib3MF_uint64 CContentEncryptionParams::GetDescriptor() { + return m_pParams->getDescriptor(); + } + + eEncryptionAlgorithm CContentEncryptionParams::GetEncryptionAlgorithm() { + return(eEncryptionAlgorithm)m_pParams->getEncryptionAlgorithm(); + } + + void CContentEncryptionParams::GetKey(Lib3MF_uint64 nByteDataBufferSize, Lib3MF_uint64 *pByteDataNeededCount, Lib3MF_uint8 *pByteDataBuffer) { + const std::vector & buf = m_pParams->getKey(); + if (nByteDataBufferSize < buf.size() || nullptr == pByteDataBuffer) + *pByteDataNeededCount = buf.size(); + else { + std::copy(buf.begin(), buf.end(), pByteDataBuffer); + } + } + + void CContentEncryptionParams::GetInitializationVector(Lib3MF_uint64 nByteDataBufferSize, Lib3MF_uint64 *pByteDataNeededCount, Lib3MF_uint8 *pByteDataBuffer) { + const std::vector & buf = m_pParams->getInitVector(); + if (nByteDataBufferSize < buf.size() || nullptr == pByteDataBuffer) + *pByteDataNeededCount = buf.size(); + else { + std::copy(buf.begin(), buf.end(), pByteDataBuffer); + } + } + + void CContentEncryptionParams::GetAuthenticationTag(Lib3MF_uint64 nByteDataBufferSize, Lib3MF_uint64 *pByteDataNeededCount, Lib3MF_uint8 *pByteDataBuffer) { + const std::vector & buf = m_pParams->getAuthTag(); + if (nByteDataBufferSize < buf.size() || nullptr == pByteDataBuffer) + *pByteDataNeededCount = buf.size(); + else { + std::copy(buf.begin(), buf.end(), pByteDataBuffer); + } + } + + void CContentEncryptionParams::SetAuthenticationTag(Lib3MF_uint64 const nByteDataBufferSize, const Lib3MF_uint8 *pByteDataBuffer) { + std::vector tag(pByteDataBuffer, pByteDataBuffer + nByteDataBufferSize); + m_pParams->setAuthTag(tag); + } + + void CContentEncryptionParams::GetAdditionalAuthenticationData(Lib3MF_uint64 nByteDataBufferSize, Lib3MF_uint64 *pByteDataNeededCount, Lib3MF_uint8 *pByteDataBuffer) { + const std::vector & buf = m_pParams->getAddAuthData(); + if (nByteDataBufferSize < buf.size() || nullptr == pByteDataBuffer) + *pByteDataNeededCount = buf.size(); + else { + std::copy(buf.begin(), buf.end(), pByteDataBuffer); + } + } + + void CContentEncryptionParams::SetAdditionalAuthenticationData(Lib3MF_uint64 const nByteDataBufferSize, const Lib3MF_uint8 *pByteDataBuffer) { + std::vector aad(pByteDataBuffer, pByteDataBuffer + nByteDataBufferSize); + m_pParams->setAddAuthData(aad); + } + + std::string CContentEncryptionParams::GetKeyUUID() { + return std::string(); + } + } +} + diff --git a/Source/API/lib3mf_keystore.cpp b/Source/API/lib3mf_keystore.cpp new file mode 100644 index 000000000..d4b7684c6 --- /dev/null +++ b/Source/API/lib3mf_keystore.cpp @@ -0,0 +1,161 @@ +#include "lib3mf_types.hpp" +#include "lib3mf_keystore.hpp" +#include "lib3mf_interfaceexception.hpp" +#include "lib3mf_consumer.hpp" +#include "lib3mf_resourcedatagroup.hpp" +#include "lib3mf_resourcedata.hpp" +#include "lib3mf_packagepart.hpp" +#include "lib3mf_utils.hpp" + +#include "Model/Classes/NMR_KeyStoreFactory.h" +#include "Model/Classes/NMR_PackageResourceID.h" +#include "Model/Classes/NMR_Model.h" +#include "Common/NMR_SecureContentTypes.h" +#include "Common/NMR_Types.h" + +#include + +using namespace Lib3MF::Impl; + +Lib3MF::Impl::CKeyStore::CKeyStore(NMR::PModel const & pModel) + :m_pModel(pModel) +{ + if (nullptr == pModel) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDKEYSTORE); + m_pKeyStore = pModel->getKeyStore(); +} + +IConsumer * Lib3MF::Impl::CKeyStore::AddConsumer(const std::string & sConsumerID, const std::string & sKeyID, const std::string & sKeyValue) +{ + NMR::PKeyStoreConsumer consumer = NMR::CKeyStoreFactory::makeConsumer(sConsumerID); + consumer->setKeyID(sKeyID); + consumer->setKeyValue(sKeyValue); + m_pKeyStore->addConsumer(consumer); + return new CConsumer(consumer); +} + +Lib3MF_uint64 Lib3MF::Impl::CKeyStore::GetConsumerCount() +{ + return m_pKeyStore->getConsumerCount(); +} + +IConsumer * Lib3MF::Impl::CKeyStore::GetConsumer(const Lib3MF_uint64 nConsumerIndex) +{ + NMR::PKeyStoreConsumer consumer = m_pKeyStore->getConsumer(nConsumerIndex); + return new CConsumer(consumer); +} + +IConsumer * Lib3MF::Impl::CKeyStore::FindConsumer(const std::string & sConsumerID) +{ + NMR::PKeyStoreConsumer consumer = m_pKeyStore->findConsumerById(sConsumerID); + if (!consumer) + return nullptr; + return new CConsumer(consumer); +} + +void Lib3MF::Impl::CKeyStore::RemoveConsumer(IConsumer * pConsumerInstance) +{ + CConsumer * pConsumer = dynamic_cast(pConsumerInstance); + if (!pConsumer) { + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDKEYSTORECONSUMER); + } + m_pKeyStore->removeConsumer(pConsumer->consumer()); +} + +std::string Lib3MF::Impl::CKeyStore::GetUUID(bool & bHasUUID) { + bHasUUID = m_pKeyStore->getUUID() != nullptr; + if (bHasUUID) + return m_pKeyStore->getUUID()->toString(); + return ""; +} + +void Lib3MF::Impl::CKeyStore::SetUUID(const std::string & sUUID) +{ + NMR::PUUID pUUID = std::make_shared(sUUID); + m_pKeyStore->setUUID(pUUID); +} + +Lib3MF_uint64 Lib3MF::Impl::CKeyStore::GetResourceDataGroupCount() +{ + return (Lib3MF_uint32)m_pKeyStore->getResourceDataGroupCount(); +} + +IResourceDataGroup * Lib3MF::Impl::CKeyStore::GetResourceDataGroup(const Lib3MF_uint64 nResourceDataIndex) +{ + NMR::PKeyStoreResourceDataGroup dg = m_pKeyStore->getResourceDataGroup(nResourceDataIndex); + return new CResourceDataGroup(dg); +} + +IResourceDataGroup * Lib3MF::Impl::CKeyStore::AddResourceDataGroup() { + //this is not ideal, as key size is determined by the encryptionalgorithm inside resourcedata. + //in any case, the spec does not state what happens if different resource datas have different algorithms, + //but resourcedatagroups are supposed to group the same key for a group of resources... + //so far, this should work as aes256 is the only thing we support. + std::vector key(NMR::fnGetAlgorithmKeySize(NMR::eKeyStoreEncryptAlgorithm::AES256_GCM), 0); + m_pModel->generateRandomBytes(key.data(), key.size()); + NMR::PKeyStoreResourceDataGroup dg = NMR::CKeyStoreFactory::makeResourceDataGroup(std::make_shared(), key); + m_pKeyStore->addResourceDataGroup(dg); + return new CResourceDataGroup(dg); +} + +void Lib3MF::Impl::CKeyStore::RemoveResourceDataGroup(IResourceDataGroup * pTheResourceDataGroup) { + CResourceDataGroup * dg = dynamic_cast(pTheResourceDataGroup); + if (!dg) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + m_pKeyStore->removeResourceDataGroup(dg->resourceDataGroup()); +} + +Lib3MF::Impl::IResourceDataGroup * Lib3MF::Impl::CKeyStore::FindResourceDataGroup(Lib3MF::Impl::IPackagePart *pPartPath) { + NMR::PPackageModelPath pPath = m_pModel->findOrCreateModelPath(pPartPath->GetPath()); + if (!pPath) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + + NMR::PKeyStoreResourceDataGroup dg = m_pKeyStore->findResourceDataGroupByResourceDataPath(pPath); + if (!dg) + return nullptr; + return new CResourceDataGroup(dg); +} + +Lib3MF::Impl::IResourceData * Lib3MF::Impl::CKeyStore::AddResourceData(Lib3MF::Impl::IResourceDataGroup *pResourceDataGroup, Lib3MF::Impl::IPackagePart *pPartPath, Lib3MF::eEncryptionAlgorithm eAlgorithm, Lib3MF::eCompression eCompression, Lib3MF_uint64 nAdditionalAuthenticationDataBufferSize, const Lib3MF_uint8 *pAdditionalAuthenticationDataBuffer) { + bool compression = translateCompression(eCompression); + NMR::eKeyStoreEncryptAlgorithm algorithm = translateEncryptionAlgorithm(eAlgorithm); + CResourceDataGroup * dg = dynamic_cast(pResourceDataGroup); + if (!dg) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + //pPartPath might have different implementations, so asking model get us right to what we need. + NMR::PPackageModelPath pPath = m_pModel->findOrCreateModelPath(pPartPath->GetPath()); + if (!pPath) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + + std::vector aad(pAdditionalAuthenticationDataBuffer, pAdditionalAuthenticationDataBuffer + nAdditionalAuthenticationDataBufferSize); + NMR::PKeyStoreCEKParams params = NMR::CKeyStoreFactory::makeCEKParams(compression, algorithm, aad); + NMR::PKeyStoreResourceData rd = NMR::CKeyStoreFactory::makeResourceData(dg->resourceDataGroup(), pPath, params); + m_pKeyStore->addResourceData(rd); + return new CResourceData(rd); +} + +void Lib3MF::Impl::CKeyStore::RemoveResourceData(Lib3MF::Impl::IResourceData *pResourceData) { + CResourceData * rd = dynamic_cast(pResourceData); + if (!rd) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + m_pKeyStore->removeResourceData(rd->resourceData()); +} + +Lib3MF_uint64 Lib3MF::Impl::CKeyStore::GetResourceDataCount() { + return m_pKeyStore->getResourceDataCount(); +} + +Lib3MF::Impl::IResourceData * Lib3MF::Impl::CKeyStore::GetResourceData(Lib3MF_uint64 nResourceDataIndex) { + NMR::PKeyStoreResourceData rd = m_pKeyStore->getResourceData(nResourceDataIndex); + return new CResourceData(rd); +} + +IResourceData * Lib3MF::Impl::CKeyStore::FindResourceData(IPackagePart * pResourcePath) { + NMR::PPackageModelPath pPath = m_pModel->findOrCreateModelPath(pResourcePath->GetPath()); + if (!pPath) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + NMR::PKeyStoreResourceData rd = m_pKeyStore->findResourceData(pPath); + if (!rd) + return nullptr; + return new CResourceData(rd); +} diff --git a/Source/API/lib3mf_meshobject.cpp b/Source/API/lib3mf_meshobject.cpp index 3a7571771..7c7e4f52c 100644 --- a/Source/API/lib3mf_meshobject.cpp +++ b/Source/API/lib3mf_meshobject.cpp @@ -187,12 +187,12 @@ void CMeshObject::GetTriangleIndices (Lib3MF_uint64 nIndicesBufferSize, Lib3MF_u } } -void CMeshObject::SetObjectLevelProperty(const Lib3MF_uint32 nResourceID, const Lib3MF_uint32 nPropertyID) +void CMeshObject::SetObjectLevelProperty(const Lib3MF_uint32 nUniqueResourceID, const Lib3MF_uint32 nPropertyID) { NMR::CMeshInformation_Properties * pInformation = getMeshInformationProperties(); NMR::MESHINFORMATION_PROPERTIES * pDefaultData = new NMR::MESHINFORMATION_PROPERTIES; - pDefaultData->m_nResourceID = nResourceID; + pDefaultData->m_nUniqueResourceID = nUniqueResourceID; pDefaultData->m_nPropertyIDs[0] = nPropertyID; pDefaultData->m_nPropertyIDs[1] = nPropertyID; pDefaultData->m_nPropertyIDs[2] = nPropertyID; @@ -200,13 +200,13 @@ void CMeshObject::SetObjectLevelProperty(const Lib3MF_uint32 nResourceID, const pInformation->setDefaultData((NMR::MESHINFORMATIONFACEDATA*)pDefaultData); } -bool CMeshObject::GetObjectLevelProperty(Lib3MF_uint32 & nResourceID, Lib3MF_uint32 & nPropertyID) +bool CMeshObject::GetObjectLevelProperty(Lib3MF_uint32 & nUniqueResourceID, Lib3MF_uint32 & nPropertyID) { NMR::CMeshInformation_Properties * pInformation = getMeshInformationProperties(); NMR::MESHINFORMATION_PROPERTIES * pDefaultData = (NMR::MESHINFORMATION_PROPERTIES*)pInformation->getDefaultData(); if (pDefaultData) { - nResourceID = pDefaultData->m_nResourceID; + nUniqueResourceID = pDefaultData->m_nUniqueResourceID; nPropertyID = pDefaultData->m_nPropertyIDs[0]; return true; } @@ -219,7 +219,7 @@ void CMeshObject::SetTriangleProperties(const Lib3MF_uint32 nIndex, const sLib3M NMR::MESHINFORMATION_PROPERTIES * pFaceData = (NMR::MESHINFORMATION_PROPERTIES*)pInformation->getFaceData(nIndex); if (pFaceData != nullptr) { - pFaceData->m_nResourceID = Properties.m_ResourceID; + pFaceData->m_nUniqueResourceID = Properties.m_ResourceID; for (unsigned j = 0; j < 3; j++) { pFaceData->m_nPropertyIDs[j] = Properties.m_PropertyIDs[j]; } @@ -233,7 +233,7 @@ void CMeshObject::GetTriangleProperties(const Lib3MF_uint32 nIndex, sLib3MFTrian NMR::MESHINFORMATION_PROPERTIES * pFaceData = (NMR::MESHINFORMATION_PROPERTIES*)pInformation->getFaceData(nIndex); if (pFaceData != nullptr) { - sProperty.m_ResourceID = pFaceData->m_nResourceID; + sProperty.m_ResourceID = pFaceData->m_nUniqueResourceID; for (unsigned j = 0; j < 3; j++) { sProperty.m_PropertyIDs[j] = pFaceData->m_nPropertyIDs[j]; } @@ -265,7 +265,7 @@ void CMeshObject::SetAllTriangleProperties(const Lib3MF_uint64 nPropertiesArrayB for (uint32_t nIndex = 0; nIndex < nFaceCount; nIndex++) { NMR::MESHINFORMATION_PROPERTIES * pFaceData = (NMR::MESHINFORMATION_PROPERTIES*)pInformation->getFaceData(nIndex); if (pFaceData != nullptr) { - pFaceData->m_nResourceID = pProperty->m_ResourceID; + pFaceData->m_nUniqueResourceID = pProperty->m_ResourceID; for (unsigned j = 0; j < 3; j++) { pFaceData->m_nPropertyIDs[j] = pProperty->m_PropertyIDs[j]; } @@ -277,7 +277,7 @@ void CMeshObject::SetAllTriangleProperties(const Lib3MF_uint64 nPropertiesArrayB if ((nFaceCount > 0) && (pInformation->getDefaultData() == nullptr)) { NMR::MESHINFORMATION_PROPERTIES * pFaceData = (NMR::MESHINFORMATION_PROPERTIES*)pInformation->getFaceData(0); std::unique_ptr pDefaultFaceData(new NMR::MESHINFORMATION_PROPERTIES); - pDefaultFaceData->m_nResourceID = pFaceData->m_nResourceID; + pDefaultFaceData->m_nUniqueResourceID = pFaceData->m_nUniqueResourceID; for (unsigned j = 0; j < 3; j++) { pDefaultFaceData->m_nPropertyIDs[j] = pFaceData->m_nPropertyIDs[j]; } @@ -305,7 +305,7 @@ void CMeshObject::GetAllTriangleProperties(Lib3MF_uint64 nPropertiesArrayBufferS NMR::MESHINFORMATION_PROPERTIES * pFaceData = (NMR::MESHINFORMATION_PROPERTIES*)pInformation->getFaceData(nIndex); if (pFaceData != nullptr) { - pProperty->m_ResourceID = pFaceData->m_nResourceID; + pProperty->m_ResourceID = pFaceData->m_nUniqueResourceID; for (unsigned j = 0; j < 3; j++) { pProperty->m_PropertyIDs[j] = pFaceData->m_nPropertyIDs[j]; } diff --git a/Source/API/lib3mf_model.cpp b/Source/API/lib3mf_model.cpp index 77d198814..514309b87 100644 --- a/Source/API/lib3mf_model.cpp +++ b/Source/API/lib3mf_model.cpp @@ -58,6 +58,9 @@ Abstract: This is a stub class definition of CModel #include "lib3mf_compositematerialsiterator.hpp" #include "lib3mf_multipropertygroup.hpp" #include "lib3mf_multipropertygroupiterator.hpp" +#include "lib3mf_packagepart.hpp" +#include "lib3mf_keystore.hpp" + // Include custom headers here. #include "Model/Classes/NMR_ModelMeshObject.h" @@ -66,7 +69,7 @@ Abstract: This is a stub class definition of CModel #include "Model/Classes/NMR_ModelColorGroup.h" #include "Model/Classes/NMR_ModelTexture2DGroup.h" #include "Model/Classes/NMR_ModelMultiPropertyGroup.h" - +#include "Common/NMR_SecureContentTypes.h" #include "lib3mf_utils.hpp" using namespace Lib3MF::Impl; @@ -86,6 +89,16 @@ NMR::CModel& CModel::model() return *m_model; } +IPackagePart* CModel::RootModelPart() +{ + return new CPackagePart(model().rootModelPath()); +} + +IPackagePart * CModel::FindOrCreatePackagePart(const std::string & sAbsolutePath) +{ + return new CPackagePart(model().findOrCreateModelPath(sAbsolutePath)); +} + void CModel::SetUnit (const eLib3MFModelUnit eUnit) { model().setUnit(NMR::eModelUnit(eUnit)); @@ -116,9 +129,9 @@ IReader * CModel::QueryReader (const std::string & sReaderClass) return new CReader(sReaderClass, m_model); } -ITexture2D * CModel::GetTexture2DByID (const Lib3MF_uint32 nResourceID) +ITexture2D * CModel::GetTexture2DByID(const Lib3MF_uint32 nUniqueResourceID) { - NMR::PModelTexture2DResource pTexture2DResource = model().findTexture2D(nResourceID); + NMR::PModelTexture2DResource pTexture2DResource = model().findTexture2D(nUniqueResourceID); if (pTexture2DResource) { return new CTexture2D(pTexture2DResource); } @@ -126,9 +139,9 @@ ITexture2D * CModel::GetTexture2DByID (const Lib3MF_uint32 nResourceID) throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDTEXTURERESOURCE); } -eLib3MFPropertyType CModel::GetPropertyTypeByID(const Lib3MF_uint32 nResourceID) +eLib3MFPropertyType CModel::GetPropertyTypeByID(const Lib3MF_uint32 nUniqueResourceID) { - NMR::PModelResource pResource = model().findResource(nResourceID); + NMR::PModelResource pResource = model().findResource(nUniqueResourceID); if (!pResource) { throw ELib3MFInterfaceException(LIB3MF_ERROR_RESOURCENOTFOUND); } @@ -152,19 +165,26 @@ eLib3MFPropertyType CModel::GetPropertyTypeByID(const Lib3MF_uint32 nResourceID) return ePropertyType::NoPropertyType; } -IBaseMaterialGroup * CModel::GetBaseMaterialGroupByID (const Lib3MF_uint32 nResourceID) +IBaseMaterialGroup * CModel::GetBaseMaterialGroupByID(const Lib3MF_uint32 nUniqueResourceID) { - NMR::PModelBaseMaterialResource pBaseMaterialResource = model().findBaseMaterial(nResourceID); - if (pBaseMaterialResource) { - return new CBaseMaterialGroup(pBaseMaterialResource); + NMR::PPackageResourceID pID = model().findPackageResourceID(nUniqueResourceID); + if (pID) { + NMR::PModelBaseMaterialResource pBaseMaterialResource = model().findBaseMaterial(pID); + if (pBaseMaterialResource) { + return new CBaseMaterialGroup(pBaseMaterialResource); + } + else + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDBASEMATERIALGROUP); } - else - throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDBASEMATERIALGROUP); + else { + throw ELib3MFInterfaceException(LIB3MF_ERROR_RESOURCENOTFOUND); + } + } -IMeshObject * CModel::GetMeshObjectByID (const Lib3MF_uint32 nResourceID) +IMeshObject * CModel::GetMeshObjectByID(const Lib3MF_uint32 nUniqueResourceID) { - NMR::PModelResource pObjectResource = model().findResource(nResourceID); + NMR::PModelResource pObjectResource = model().findResource(nUniqueResourceID); if (dynamic_cast(pObjectResource.get())) { return new CMeshObject(pObjectResource); } @@ -172,9 +192,9 @@ IMeshObject * CModel::GetMeshObjectByID (const Lib3MF_uint32 nResourceID) throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDMESHOBJECT); } -IComponentsObject * CModel::GetComponentsObjectByID (const Lib3MF_uint32 nResourceID) +IComponentsObject * CModel::GetComponentsObjectByID(const Lib3MF_uint32 nUniqueResourceID) { - NMR::PModelResource pObjectResource = model().findResource(nResourceID); + NMR::PModelResource pObjectResource = model().findResource(nUniqueResourceID); if (dynamic_cast(pObjectResource.get())) { return new CComponentsObject(pObjectResource); } @@ -182,9 +202,9 @@ IComponentsObject * CModel::GetComponentsObjectByID (const Lib3MF_uint32 nResour throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDCOMPONENTSOBJECT); } -IColorGroup * CModel::GetColorGroupByID(const Lib3MF_uint32 nResourceID) +IColorGroup * CModel::GetColorGroupByID(const Lib3MF_uint32 nUniqueResourceID) { - NMR::PModelResource pResource = model().findResource(nResourceID); + NMR::PModelResource pResource = model().findResource(nUniqueResourceID); if (dynamic_cast(pResource.get())) { return new CColorGroup(std::dynamic_pointer_cast(pResource)); } @@ -192,9 +212,9 @@ IColorGroup * CModel::GetColorGroupByID(const Lib3MF_uint32 nResourceID) throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDCOLORGROUP); } -ISliceStack * CModel::GetSliceStackByID(const Lib3MF_uint32 nResourceID) +ISliceStack * CModel::GetSliceStackByID(const Lib3MF_uint32 nUniqueResourceID) { - NMR::PModelResource pResource = model().findResource(nResourceID); + NMR::PModelResource pResource = model().findResource(nUniqueResourceID); if (dynamic_cast(pResource.get())) { return new CSliceStack(std::dynamic_pointer_cast(pResource)); } @@ -202,9 +222,9 @@ ISliceStack * CModel::GetSliceStackByID(const Lib3MF_uint32 nResourceID) throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDSLICESTACKRESOURCE); } -ITexture2DGroup * CModel::GetTexture2DGroupByID(const Lib3MF_uint32 nResourceID) +ITexture2DGroup * CModel::GetTexture2DGroupByID(const Lib3MF_uint32 nUniqueResourceID) { - NMR::PModelResource pResource = model().findResource(nResourceID); + NMR::PModelResource pResource = model().findResource(nUniqueResourceID); if (dynamic_cast(pResource.get())) { return new CTexture2DGroup(std::dynamic_pointer_cast(pResource)); } @@ -212,9 +232,9 @@ ITexture2DGroup * CModel::GetTexture2DGroupByID(const Lib3MF_uint32 nResourceID) throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDTEXTURE2DGROUP); } -ICompositeMaterials * CModel::GetCompositeMaterialsByID(const Lib3MF_uint32 nResourceID) +ICompositeMaterials * CModel::GetCompositeMaterialsByID(const Lib3MF_uint32 nUniqueResourceID) { - NMR::PModelResource pResource = model().findResource(nResourceID); + NMR::PModelResource pResource = model().findResource(nUniqueResourceID); if (dynamic_cast(pResource.get())) { return new CCompositeMaterials(std::dynamic_pointer_cast(pResource)); } @@ -222,9 +242,9 @@ ICompositeMaterials * CModel::GetCompositeMaterialsByID(const Lib3MF_uint32 nRes throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDCOMPOSITEMATERIALS); } -IMultiPropertyGroup * CModel::GetMultiPropertyGroupByID(const Lib3MF_uint32 nResourceID) +IMultiPropertyGroup * CModel::GetMultiPropertyGroupByID(const Lib3MF_uint32 nUniqueResourceID) { - NMR::PModelResource pResource = model().findResource(nResourceID); + NMR::PModelResource pResource = model().findResource(nUniqueResourceID); if (dynamic_cast(pResource.get())) { return new CMultiPropertyGroup(std::dynamic_pointer_cast(pResource)); } @@ -495,7 +515,7 @@ IColorGroup * CModel::AddColorGroup() ITexture2DGroup * CModel::AddTexture2DGroup(ITexture2D* pTexture2DInstance) { - NMR::PackageResourceID nTexture2DID = pTexture2DInstance->GetResourceID(); + NMR::UniqueResourceID nTexture2DID = pTexture2DInstance->GetResourceID(); // Find class instance NMR::PModelTexture2DResource pModelTexture2DObject = model().findTexture2D(nTexture2DID); @@ -510,10 +530,10 @@ ITexture2DGroup * CModel::AddTexture2DGroup(ITexture2D* pTexture2DInstance) ICompositeMaterials * CModel::AddCompositeMaterials(IBaseMaterialGroup* pBaseMaterialGroupInstance) { - NMR::PackageResourceID nBaseMaterialGroupID = pBaseMaterialGroupInstance->GetResourceID(); - + NMR::UniqueResourceID nBaseMaterialGroupID = pBaseMaterialGroupInstance->GetUniqueResourceID(); + NMR::PPackageResourceID pID = model().findPackageResourceID(nBaseMaterialGroupID); // Find class instance - NMR::PModelBaseMaterialResource pModelBaseMaterialGroup = model().findBaseMaterial(nBaseMaterialGroupID); + NMR::PModelBaseMaterialResource pModelBaseMaterialGroup = model().findBaseMaterial(pID); if (pModelBaseMaterialGroup == nullptr) throw ELib3MFInterfaceException(LIB3MF_ERROR_RESOURCENOTFOUND); @@ -534,7 +554,7 @@ IMultiPropertyGroup * CModel::AddMultiPropertyGroup() IBuildItem * CModel::AddBuildItem (IObject* pObject, const sLib3MFTransform Transform) { // Get Resource ID - NMR::PackageResourceID nObjectID = pObject->GetResourceID(); + NMR::UniqueResourceID nObjectID = pObject->GetResourceID(); // Find class instance NMR::CModelObject * pModelObject = model().findObject(nObjectID); @@ -666,3 +686,23 @@ Lib3MF::sBox CModel::GetOutbox() return s; } +IKeyStore * Lib3MF::Impl::CModel::GetKeyStore() { + return new CKeyStore(m_model); +} + +void Lib3MF::Impl::CModel::SetRandomNumberCallback(Lib3MF::RandomNumberCallback pTheCallback, Lib3MF_pvoid pUserData) { + if (nullptr == pTheCallback) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + NMR::CryptoRandGenDescriptor descriptor; + descriptor.m_pUserData = pUserData; + descriptor.m_fnRNG = [pTheCallback](NMR::nfByte * buffer, NMR::nfUint64 size, void * userData) { + Lib3MF_uint64 generated = 0; + (*pTheCallback)((Lib3MF_uint64)buffer, size, userData, &generated); + if (generated > 0) + return generated; + throw NMR::CNMRException(NMR_ERROR_CALCULATIONTERMINATED); + }; + + m_model->setCryptoRandCallback(descriptor); +} + diff --git a/Source/API/lib3mf_multipropertygroup.cpp b/Source/API/lib3mf_multipropertygroup.cpp index 78b7dc7b7..98606364f 100644 --- a/Source/API/lib3mf_multipropertygroup.cpp +++ b/Source/API/lib3mf_multipropertygroup.cpp @@ -138,7 +138,7 @@ sLib3MFMultiPropertyLayer CMultiPropertyGroup::GetLayer (const Lib3MF_uint32 nLa { NMR::MODELMULTIPROPERTYLAYER sLayer = multiPropertyGroup().getLayer(nLayerIndex); sLib3MFMultiPropertyLayer outLayer; - outLayer.m_ResourceID = sLayer.m_nResourceID; + outLayer.m_ResourceID = sLayer.m_nUniqueResourceID; outLayer.m_TheBlendMethod = (eLib3MFBlendMethod)sLayer.m_nMethod; return outLayer; } diff --git a/Source/API/lib3mf_object.cpp b/Source/API/lib3mf_object.cpp index c4f8290c4..aa87cecd7 100644 --- a/Source/API/lib3mf_object.cpp +++ b/Source/API/lib3mf_object.cpp @@ -223,10 +223,12 @@ ISliceStack * CObject::GetSliceStack() void CObject::AssignSliceStack(ISliceStack* pSliceStackInstance) { - Lib3MF_uint32 id = pSliceStackInstance->GetResourceID(); - + NMR::ModelResourceID nID = pSliceStackInstance->GetResourceID(); + std::shared_ptr pPackagePart(pSliceStackInstance->PackagePart()); + std::string sPath = pPackagePart->GetPath(); + NMR::PModelSliceStack pSliceStackResource = std::dynamic_pointer_cast - ( object()->getModel()->findResource(id) ); + ( object()->getModel()->findResource(sPath, nID) ); if (!pSliceStackResource) throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDSLICESTACKRESOURCE); diff --git a/Source/API/lib3mf_packagepart.cpp b/Source/API/lib3mf_packagepart.cpp new file mode 100644 index 000000000..e07cef898 --- /dev/null +++ b/Source/API/lib3mf_packagepart.cpp @@ -0,0 +1,61 @@ +/*++ + +Copyright (C) 2019 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: This is a stub class definition of CPackagePart + +*/ + +#include "lib3mf_packagepart.hpp" +#include "lib3mf_interfaceexception.hpp" + +// Include custom headers here. + +#include "Model/Classes/NMR_PackageResourceID.h" + + + +using namespace Lib3MF::Impl; + +/************************************************************************************************************************* + Class definition of CPackagePart +**************************************************************************************************************************/ + +CPackagePart::CPackagePart(NMR::PPackageModelPath pPath) + : m_pPath(pPath) +{ + if (!pPath.get()) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); +} + +std::string CPackagePart::GetPath() +{ + return m_pPath->getPath(); +} + +void CPackagePart::SetPath(const std::string & sPath) +{ + m_pPath->setPath(sPath); +} diff --git a/Source/API/lib3mf_reader.cpp b/Source/API/lib3mf_reader.cpp index b7e06d55d..97542333a 100644 --- a/Source/API/lib3mf_reader.cpp +++ b/Source/API/lib3mf_reader.cpp @@ -29,12 +29,18 @@ Abstract: This is a stub class definition of CReader */ #include "lib3mf_reader.hpp" -#include "lib3mf_interfaceexception.hpp" // Include custom headers here. +#include "lib3mf_interfaceexception.hpp" +#include "lib3mf_accessright.hpp" +#include "lib3mf_contentencryptionparams.hpp" #include "Common/Platform/NMR_Platform.h" #include "Common/Platform/NMR_ImportStream_Shared_Memory.h" #include "Common/Platform/NMR_ImportStream_Callback.h" +#include "Common/NMR_SecureContentTypes.h" +#include "Common/NMR_SecureContext.h" +#include "Model/Classes/NMR_KeyStore.h" + using namespace Lib3MF::Impl; @@ -150,25 +156,75 @@ void CReader::RemoveRelationToRead (const std::string & sRelationShipType) void CReader::SetStrictModeActive (const bool bStrictModeActive) { if (bStrictModeActive) - reader().getWarnings()->setCriticalWarningLevel(NMR::mrwInvalidOptionalValue); + reader().warnings()->setCriticalWarningLevel(NMR::mrwInvalidOptionalValue); else - reader().getWarnings()->setCriticalWarningLevel(NMR::mrwFatal); + reader().warnings()->setCriticalWarningLevel(NMR::mrwFatal); } bool CReader::GetStrictModeActive () { - return reader().getWarnings()->getCriticalWarningLevel() == NMR::mrwInvalidOptionalValue; + return reader().warnings()->getCriticalWarningLevel() == NMR::mrwInvalidOptionalValue; } std::string CReader::GetWarning (const Lib3MF_uint32 nIndex, Lib3MF_uint32 & nErrorCode) { - auto warning = reader().getWarnings()->getWarning(nIndex); + auto warning = reader().warnings()->getWarning(nIndex); nErrorCode = warning->getErrorCode(); return warning->getMessage(); } Lib3MF_uint32 CReader::GetWarningCount () { - return reader().getWarnings()->getWarningCount(); + return reader().warnings()->getWarningCount(); +} + +void Lib3MF::Impl::CReader::AddKeyWrappingCallback(const std::string &sConsumerID, const Lib3MF::KeyWrappingCallback pTheCallback, const Lib3MF_pvoid pUserData) { + NMR::KeyWrappingDescriptor descriptor; + descriptor.m_sKekDecryptData.m_pUserData = pUserData; + descriptor.m_fnWrap = + [this, pTheCallback]( + std::vector const & cipher, + std::vector & plain, + NMR::KeyWrappingContext & ctx) { + + std::shared_ptr pAccessRight = std::make_shared(ctx.m_pAccessRight); + IBase * pBaseEntity(nullptr); + pBaseEntity = pAccessRight.get(); + Lib3MF_AccessRight entityHandle = pBaseEntity; + + //figure out the size of the key. + Lib3MF_uint64 needed = 0; + Lib3MF_uint64 result = 0; + (*pTheCallback)(entityHandle, cipher.size(), cipher.data(), + 0, &needed, nullptr, ctx.m_pUserData, &result); + if (result == 0) + throw ELib3MFInterfaceException(LIB3MF_ERROR_CALCULATIONABORTED); + + plain.resize(needed, 0); + + result = 0; + (*pTheCallback)(entityHandle, cipher.size(), cipher.data(), + plain.size(), nullptr, plain.data(), ctx.m_pUserData, &result); + if (result == 0) + throw ELib3MFInterfaceException(LIB3MF_ERROR_CALCULATIONABORTED); + return (NMR::nfUint64)result; + }; + reader().secureContext()->addKekCtx(sConsumerID, descriptor); +} +void Lib3MF::Impl::CReader::SetContentEncryptionCallback(const Lib3MF::ContentEncryptionCallback pTheCallback, const Lib3MF_pvoid pUserData) { + NMR::ContentEncryptionDescriptor descriptor; + descriptor.m_sDekDecryptData.m_pUserData = pUserData; + descriptor.m_fnCrypt = [this, pTheCallback](NMR::nfUint64 size, NMR::nfByte const * cipher, NMR::nfByte * plain, NMR::ContentEncryptionContext & ctx) { + std::shared_ptr pCekParams = std::make_shared(ctx.m_sParams); + IBase * pBaseEntity(nullptr); + pBaseEntity = pCekParams.get(); + Lib3MF_ContentEncryptionParams entityHandle = pBaseEntity; + Lib3MF_uint64 result = 0; + (*pTheCallback)(entityHandle, (Lib3MF_uint64)size, cipher, (Lib3MF_uint64)size, nullptr, plain, ctx.m_pUserData, &result); + if (result == 0) + throw ELib3MFInterfaceException(LIB3MF_ERROR_CALCULATIONABORTED); + return (NMR::nfUint64)result; + }; + reader().secureContext()->setDekCtx(descriptor); } diff --git a/Source/API/lib3mf_resource.cpp b/Source/API/lib3mf_resource.cpp index fa6b0fe69..d06de188c 100644 --- a/Source/API/lib3mf_resource.cpp +++ b/Source/API/lib3mf_resource.cpp @@ -32,6 +32,7 @@ Abstract: This is a stub class definition of CResource #include "lib3mf_interfaceexception.hpp" // Include custom headers here. +#include "lib3mf_packagepart.hpp" #include "Model/Classes/NMR_ModelObject.h" #include "lib3mf_object.hpp" #include @@ -58,9 +59,19 @@ CResource::CResource(NMR::PModelResource pResource) m_pResource = pResource; } -Lib3MF_uint32 CResource::GetResourceID () +Lib3MF_uint32 CResource::GetResourceID() { - return m_pResource->getResourceID()->getUniqueID(); + return m_pResource->getPackageResourceID()->getUniqueID(); +} + +Lib3MF_uint32 CResource::GetUniqueResourceID() +{ + return m_pResource->getPackageResourceID()->getUniqueID(); +} + +Lib3MF_uint32 CResource::GetModelResourceID() +{ + return m_pResource->getPackageResourceID()->getModelResourceID(); } IObject * CResource::AsObject() @@ -72,3 +83,23 @@ IObject * CResource::AsObject() throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDCAST); } +IPackagePart * CResource::PackagePart() +{ + return new CPackagePart(m_pResource->getPackageResourceID()->getPackageModelPath()); +} + +void CResource::SetPackagePart(IPackagePart* pPackagePart) +{ + std::string sPath = pPackagePart->GetPath(); + NMR::ModelResourceID nID = m_pResource->getPackageResourceID()->getModelResourceID(); + NMR::PPackageResourceID pTargetPackageResourceID = m_pResource->getModel()->findPackageResourceID(sPath, nID); + if (pTargetPackageResourceID) { + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDMODELRESOURCE); + } + NMR::PPackageResourceID pIDOld = m_pResource->getPackageResourceID(); + NMR::PPackageResourceID pID = m_pResource->getModel()->generatePackageResourceID(sPath, nID); + m_pResource->setPackageResourceID(pID); + + m_pResource->getModel()->removePackageResourceID(pIDOld); +} + diff --git a/Source/API/lib3mf_resourcedata.cpp b/Source/API/lib3mf_resourcedata.cpp new file mode 100644 index 000000000..00ffd546e --- /dev/null +++ b/Source/API/lib3mf_resourcedata.cpp @@ -0,0 +1,38 @@ +#include "lib3mf_resourcedata.hpp" +#include "lib3mf_interfaceexception.hpp" +#include "lib3mf_consumer.hpp" +#include "lib3mf_packagepart.hpp" +#include "lib3mf_utils.hpp" + +namespace Lib3MF { + namespace Impl { + Lib3MF::Impl::CResourceData::CResourceData(NMR::PKeyStoreResourceData resourceData) + :m_pResourceData(resourceData) + { + if (!resourceData) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + } + + Lib3MF::eEncryptionAlgorithm Lib3MF::Impl::CResourceData::GetEncryptionAlgorithm() { + NMR::eKeyStoreEncryptAlgorithm ea = m_pResourceData->getEncryptionAlgorithm(); + return static_cast(ea); + } + + Lib3MF::eCompression Lib3MF::Impl::CResourceData::GetCompression() { + return translateCompression(m_pResourceData->isCompressed()); + } + + IPackagePart * CResourceData::GetPath() { + return new CPackagePart(m_pResourceData->packagePath()); + } + + void CResourceData::GetAdditionalAuthenticationData(Lib3MF_uint64 nByteDataBufferSize, Lib3MF_uint64 * pByteDataNeededCount, Lib3MF_uint8 * pByteDataBuffer) { + std::vector const & aad = m_pResourceData->getAddAuthData(); + if (nByteDataBufferSize < aad.size()) { + *pByteDataNeededCount = aad.size(); + } else { + std::copy(aad.begin(), aad.end(), pByteDataBuffer); + } + } + } +} \ No newline at end of file diff --git a/Source/API/lib3mf_resourcedatagroup.cpp b/Source/API/lib3mf_resourcedatagroup.cpp new file mode 100644 index 000000000..e26f4eea2 --- /dev/null +++ b/Source/API/lib3mf_resourcedatagroup.cpp @@ -0,0 +1,47 @@ + + +#include "lib3mf_resourcedatagroup.hpp" +#include "lib3mf_interfaceexception.hpp" + +#include "lib3mf_consumer.hpp" +#include "lib3mf_accessright.hpp" + +#include "Model/Classes/NMR_KeyStoreFactory.h" +namespace Lib3MF { + namespace Impl { + CResourceDataGroup::CResourceDataGroup(NMR::PKeyStoreResourceDataGroup const & dg) + : m_pDataGroup(dg) + { + if (!dg) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + } + + IAccessRight * CResourceDataGroup::AddAccessRight(IConsumer * pConsumer, const Lib3MF::eWrappingAlgorithm eWrappingAlgorithm, const Lib3MF::eMgfAlgorithm eMgfAlgorithm, const Lib3MF::eDigestMethod eDigestMethod) { + CConsumer * c = dynamic_cast(pConsumer); + if (nullptr == c) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM); + NMR::PKeyStoreAccessRight ar = NMR::CKeyStoreFactory::makeAccessRight( + c->consumer(), + (NMR::eKeyStoreWrapAlgorithm)eWrappingAlgorithm, + (NMR::eKeyStoreMaskGenerationFunction)eMgfAlgorithm, + (NMR::eKeyStoreMessageDigest)eDigestMethod); + m_pDataGroup->addAccessRight(ar); + return new CAccessRight(ar); + } + + IAccessRight * CResourceDataGroup::FindAccessRightByConsumer(IConsumer * pConsumerInstance) { + NMR::PKeyStoreAccessRight ar = m_pDataGroup->findAccessRightByConsumerID(pConsumerInstance->GetConsumerID()); + if (!ar) + return nullptr; + return new CAccessRight(ar); + } + + void CResourceDataGroup::RemoveAccessRight(IConsumer * pConsumerInstance) { + m_pDataGroup->removeAccessRight(pConsumerInstance->GetConsumerID()); + } + + std::string CResourceDataGroup::GetKeyUUID() { + return m_pDataGroup->getKeyUUID()->toString(); + } + } +} \ No newline at end of file diff --git a/Source/API/lib3mf_slicestack.cpp b/Source/API/lib3mf_slicestack.cpp index ef283892d..2e2cec29c 100644 --- a/Source/API/lib3mf_slicestack.cpp +++ b/Source/API/lib3mf_slicestack.cpp @@ -80,8 +80,12 @@ Lib3MF_uint64 CSliceStack::GetSliceRefCount() void CSliceStack::AddSliceStackReference(ISliceStack* pTheSliceStack) { - Lib3MF_uint32 nID = pTheSliceStack->GetResourceID(); - NMR::PModelResource pResource = sliceStack()->getModel()->findResource(nID); + NMR::ModelResourceID nID = pTheSliceStack->GetResourceID(); + + std::shared_ptr pPackagePart(pTheSliceStack->PackagePart()); + std::string sPath = pPackagePart->GetPath(); + + NMR::PModelResource pResource = sliceStack()->getModel()->findResource(sPath, nID); NMR::PModelSliceStack pModelSliceStack = std::dynamic_pointer_cast(pResource); if (!pModelSliceStack) throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDSLICESTACKRESOURCE); diff --git a/Source/API/lib3mf_utils.cpp b/Source/API/lib3mf_utils.cpp index 635942774..c58611bdf 100644 --- a/Source/API/lib3mf_utils.cpp +++ b/Source/API/lib3mf_utils.cpp @@ -57,3 +57,37 @@ sLib3MFTransform Lib3MF::MatrixToTransform(const NMR::NMATRIX3 matrix) return transform; } + +eLib3MFEncryptionAlgorithm Lib3MF::translateEncryptionAlgorithm(const NMR::eKeyStoreEncryptAlgorithm algorithm) { + if (NMR::eKeyStoreEncryptAlgorithm::AES256_GCM == algorithm) + return eLib3MFEncryptionAlgorithm::AES256_GCM; + throw ELib3MFInterfaceException(LIB3MF_ERROR_NOTIMPLEMENTED); +} +NMR::eKeyStoreEncryptAlgorithm Lib3MF::translateEncryptionAlgorithm(const eLib3MFEncryptionAlgorithm algorithm) { + if (eLib3MFEncryptionAlgorithm::AES256_GCM == algorithm) + return NMR::eKeyStoreEncryptAlgorithm::AES256_GCM; + throw ELib3MFInterfaceException(LIB3MF_ERROR_NOTIMPLEMENTED); +} + +eLib3MFWrappingAlgorithm Lib3MF::translateWrappingAlgorithm(const NMR::eKeyStoreWrapAlgorithm algorithm) { + if (NMR::eKeyStoreWrapAlgorithm::RSA_OAEP == algorithm) + return eLib3MFWrappingAlgorithm::RSA_OAEP; + throw ELib3MFInterfaceException(LIB3MF_ERROR_NOTIMPLEMENTED); +} +NMR::eKeyStoreWrapAlgorithm Lib3MF::translateWrappingAlgorithm(const eLib3MFWrappingAlgorithm algorithm) { + if (eLib3MFWrappingAlgorithm::RSA_OAEP == algorithm) + return NMR::eKeyStoreWrapAlgorithm::RSA_OAEP; + throw ELib3MFInterfaceException(LIB3MF_ERROR_NOTIMPLEMENTED); +} + + + +eLib3MFCompression Lib3MF::translateCompression(bool compression) { + if (compression) + return eLib3MFCompression::Deflate; + return eLib3MFCompression::NoCompression; +} + +bool Lib3MF::translateCompression(const eLib3MFCompression compression) { + return eLib3MFCompression::Deflate == compression; +} \ No newline at end of file diff --git a/Source/API/lib3mf_writer.cpp b/Source/API/lib3mf_writer.cpp index c57739add..33b26c4c5 100644 --- a/Source/API/lib3mf_writer.cpp +++ b/Source/API/lib3mf_writer.cpp @@ -29,17 +29,21 @@ Abstract: This is a stub class definition of CWriter */ #include "lib3mf_writer.hpp" -#include "lib3mf_interfaceexception.hpp" // Include custom headers here. -// Include custom headers here. +#include "lib3mf_interfaceexception.hpp" +#include "lib3mf_accessright.hpp" +#include "lib3mf_contentencryptionparams.hpp" #include "Common/Platform/NMR_Platform.h" #include "Common/Platform/NMR_ExportStream_Callback.h" #include "Common/Platform/NMR_ExportStream_Memory.h" #include "Common/Platform/NMR_ExportStream_Dummy.h" +#include "Common/NMR_SecureContentTypes.h" +#include "Common/NMR_SecureContext.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Common/NMR_ModelWarnings.h" + -// for memcpy -#include using namespace Lib3MF::Impl; @@ -78,8 +82,10 @@ void CWriter::WriteToFile (const std::string & sFilename) catch (NMR::CNMRException&e) { if (e.getErrorCode() == NMR_USERABORTED) { throw ELib3MFInterfaceException(LIB3MF_ERROR_CALCULATIONABORTED); - } - else throw e; + } else if (e.getErrorCode() == NMR_ERROR_DEKDESCRIPTORNOTFOUND + || e.getErrorCode() == NMR_ERROR_KEKDESCRIPTORNOTFOUND) { + throw ELib3MFInterfaceException(LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED); + } else throw e; } } @@ -93,24 +99,34 @@ Lib3MF_uint64 CWriter::GetStreamSize () catch (NMR::CNMRException&e) { if (e.getErrorCode() == NMR_USERABORTED) { throw ELib3MFInterfaceException(LIB3MF_ERROR_CALCULATIONABORTED); - } - else throw e; + } else if (e.getErrorCode() == NMR_ERROR_DEKDESCRIPTORNOTFOUND + || e.getErrorCode() == NMR_ERROR_KEKDESCRIPTORNOTFOUND) { + throw ELib3MFInterfaceException(LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED); + } else throw e; } return pStream->getDataSize(); } +#include + void CWriter::WriteToBuffer(Lib3MF_uint64 nBufferBufferSize, Lib3MF_uint64* pBufferNeededCount, Lib3MF_uint8 * pBufferBuffer) { - NMR::PExportStreamMemory pStream = std::make_shared(); - try { - writer().exportToStream(pStream); - } - catch (NMR::CNMRException&e) { - if (e.getErrorCode() == NMR_USERABORTED) { - throw ELib3MFInterfaceException(LIB3MF_ERROR_CALCULATIONABORTED); + NMR::PExportStreamMemory pStream; + if (!momentBuffer || momentBuffer->getDataSize() > nBufferBufferSize) { + pStream = std::make_shared(); + try { + writer().exportToStream(pStream); + } catch (NMR::CNMRException&e) { + if (e.getErrorCode() == NMR_USERABORTED) { + throw ELib3MFInterfaceException(LIB3MF_ERROR_CALCULATIONABORTED); + } else if (e.getErrorCode() == NMR_ERROR_DEKDESCRIPTORNOTFOUND + || e.getErrorCode() == NMR_ERROR_KEKDESCRIPTORNOTFOUND) { + throw ELib3MFInterfaceException(LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED); + } else throw e; } - else throw e; + } else { + pStream = momentBuffer; } Lib3MF_uint64 cbStreamSize = pStream->getDataSize(); @@ -119,7 +135,10 @@ void CWriter::WriteToBuffer(Lib3MF_uint64 nBufferBufferSize, Lib3MF_uint64* pBuf if (nBufferBufferSize >= cbStreamSize) { // TODO eliminate this copy, perhaps by allowing CExportStreamMemory to use existing buffers - std::memcpy(pBufferBuffer, pStream->getData(), static_cast(cbStreamSize)); + memcpy(pBufferBuffer, pStream->getData(), static_cast(cbStreamSize)); + momentBuffer.reset(); + } else { + momentBuffer = pStream; } } @@ -173,3 +192,78 @@ void CWriter::SetDecimalPrecision(const Lib3MF_uint32 nDecimalPrecision) m_pWriter->SetDecimalPrecision(nDecimalPrecision); } +void Lib3MF::Impl::CWriter::AddKeyWrappingCallback(const std::string & sConsumerID, const Lib3MF::KeyWrappingCallback pTheCallback, const Lib3MF_pvoid pUserData){ + NMR::KeyWrappingDescriptor descriptor; + descriptor.m_sKekDecryptData.m_pUserData = pUserData; + descriptor.m_fnWrap = + [this, pTheCallback]( + std::vector const & plain, + std::vector & cipher, + NMR::KeyWrappingContext & ctx) { + + std::shared_ptr pAccessRight = std::make_shared(ctx.m_pAccessRight); + IBase * pBaseEntity(nullptr); + pBaseEntity = pAccessRight.get(); + Lib3MF_AccessRight entityHandle = pBaseEntity; + + Lib3MF_uint64 needed = 0; + Lib3MF_uint64 result = 0; + (*pTheCallback)(entityHandle, plain.size(), plain.data(), 0, + &needed, nullptr, ctx.m_pUserData, &result); + if (result == 0) + throw ELib3MFInterfaceException(LIB3MF_ERROR_CALCULATIONABORTED); + + cipher.resize(needed, 0); + + result = 0; + (*pTheCallback)(entityHandle, plain.size(), plain.data(), plain.size(), + nullptr, cipher.data(), ctx.m_pUserData, &result); + if (result == 0) + throw ELib3MFInterfaceException(LIB3MF_ERROR_CALCULATIONABORTED); + return (NMR::nfUint64)result; + }; + writer().secureContext()->addKekCtx(sConsumerID, descriptor); +} + +void Lib3MF::Impl::CWriter::SetContentEncryptionCallback(const Lib3MF::ContentEncryptionCallback pTheCallback, const Lib3MF_pvoid pUserData) +{ + NMR::ContentEncryptionDescriptor descriptor; + descriptor.m_sDekDecryptData.m_pUserData = pUserData; + descriptor.m_fnCrypt = [this, pTheCallback]( + NMR::nfUint64 size, + NMR::nfByte const * plain, + NMR::nfByte * cipher, + NMR::ContentEncryptionContext & ctx) { + std::shared_ptr pCekParams = std::make_shared(ctx.m_sParams); + IBase * pBaseEntity(nullptr); + pBaseEntity = pCekParams.get(); + Lib3MF_ContentEncryptionParams entityHandle = pBaseEntity; + Lib3MF_uint64 result = 0; + (*pTheCallback)(entityHandle, (Lib3MF_uint64)size, plain, (Lib3MF_uint64)size, nullptr, cipher, ctx.m_pUserData, &result); + if (result == 0) + throw ELib3MFInterfaceException(LIB3MF_ERROR_CALCULATIONABORTED); + return (NMR::nfUint64)result; + }; + m_pWriter->secureContext()->setDekCtx(descriptor); +} + +void CWriter::SetStrictModeActive(const bool bStrictModeActive) { + if (bStrictModeActive) + writer().warnings()->setCriticalWarningLevel(NMR::mrwInvalidOptionalValue); + else + writer().warnings()->setCriticalWarningLevel(NMR::mrwFatal); +} + +bool CWriter::GetStrictModeActive() { + return writer().warnings()->getCriticalWarningLevel() == NMR::mrwInvalidOptionalValue; +} + +std::string CWriter::GetWarning(const Lib3MF_uint32 nIndex, Lib3MF_uint32 & nErrorCode) { + auto warning = writer().warnings()->getWarning(nIndex); + nErrorCode = warning->getErrorCode(); + return warning->getMessage(); +} + +Lib3MF_uint32 CWriter::GetWarningCount() { + return writer().warnings()->getWarningCount(); +} \ No newline at end of file diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 35f490aa5..ee3ccf557 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -7,6 +7,7 @@ if (USE_INCLUDED_ZLIB) file(GLOB ZLIB_FILES ./Source/Libraries/zlib/*.c) endif() +file (GLOB CPPBASE64_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "Source/Libraries/cpp-base64/*.cpp") # sources for COM emulation set(SRCS_PLATFORM @@ -22,6 +23,7 @@ set(SRCS_PLATFORM set(SRCS_COMMON ${SRCS_PLATFORM} ${ZLIB_FILES} +${CPPBASE64_FILES} Source/API/lib3mf.cpp Source/API/lib3mf_attachment.cpp Source/API/lib3mf_base.cpp @@ -44,9 +46,16 @@ Source/API/lib3mf_metadata.cpp Source/API/lib3mf_metadatagroup.cpp Source/API/lib3mf_multipropertygroup.cpp Source/API/lib3mf_multipropertygroupiterator.cpp +Source/API/lib3mf_contentencryptionparams.cpp +Source/API/lib3mf_accessright.cpp +Source/API/lib3mf_consumer.cpp +Source/API/lib3mf_resourcedata.cpp +Source/API/lib3mf_resourcedatagroup.cpp +Source/API/lib3mf_keystore.cpp Source/API/lib3mf_model.cpp Source/API/lib3mf_object.cpp Source/API/lib3mf_objectiterator.cpp +Source/API/lib3mf_packagepart.cpp Source/API/lib3mf_reader.cpp Source/API/lib3mf_resource.cpp Source/API/lib3mf_resourceiterator.cpp @@ -60,7 +69,6 @@ Source/API/lib3mf_texture2diterator.cpp Source/API/lib3mf_writer.cpp Source/API/lib3mf_utils.cpp Source/Common/3MF_ProgressMonitor.cpp -Source/Model/Reader/NMR_ModelReader_InstructionElement.cpp Source/Common/Math/NMR_Matrix.cpp Source/Common/Math/NMR_PairMatchingTree.cpp Source/Common/Math/NMR_Vector.cpp @@ -79,7 +87,9 @@ Source/Common/Mesh/NMR_BeamLattice.cpp Source/Common/Mesh/NMR_MeshBuilder.cpp Source/Common/NMR_Exception.cpp Source/Common/NMR_Exception_Windows.cpp +Source/Common/NMR_ModelWarnings.cpp Source/Common/NMR_StringUtils.cpp +Source/Common/NMR_SecureContext.cpp Source/Common/NMR_UUID.cpp Source/Common/OPC/NMR_OpcPackagePart.cpp Source/Common/OPC/NMR_OpcPackageRelationship.cpp @@ -88,17 +98,21 @@ Source/Common/OPC/NMR_OpcPackageContentTypesReader.cpp Source/Common/OPC/NMR_OpcPackageRelationshipReader.cpp Source/Common/OPC/NMR_OpcPackageWriter.cpp Source/Common/Platform/NMR_XmlReader_Native.cpp -Source/Model/Reader/NMR_ModelReader_3MF_Native.cpp +Source/Common/Platform/NMR_EncryptionHeader.cpp Source/Common/Platform/NMR_ExportStream.cpp Source/Common/Platform/NMR_ExportStream_Callback.cpp +Source/Common/Platform/NMR_ExportStream_Compressed.cpp +Source/Common/Platform/NMR_ExportStream_Encrypted.cpp Source/Common/Platform/NMR_ExportStream_Memory.cpp Source/Common/Platform/NMR_ExportStream_Dummy.cpp Source/Common/Platform/NMR_ExportStream_ZIP.cpp Source/Common/Platform/NMR_ImportStream_Callback.cpp +Source/Common/Platform/NMR_ImportStream_Compressed.cpp Source/Common/Platform/NMR_ImportStream_Memory.cpp Source/Common/Platform/NMR_ImportStream_Shared_Memory.cpp Source/Common/Platform/NMR_ImportStream_Unique_Memory.cpp Source/Common/Platform/NMR_ImportStream_ZIP.cpp +Source/Common/Platform/NMR_ImportStream_Encrypted.cpp Source/Common/Platform/NMR_PortableZIPWriter.cpp Source/Common/Platform/NMR_PortableZIPWriterEntry.cpp Source/Common/Platform/NMR_Time.cpp @@ -110,6 +124,7 @@ Source/Model/Classes/NMR_Model.cpp Source/Model/Classes/NMR_ModelAttachment.cpp Source/Model/Classes/NMR_ModelBaseMaterial.cpp Source/Model/Classes/NMR_ModelBaseMaterials.cpp +Source/Model/Classes/NMR_ModelContext.cpp Source/Model/Classes/NMR_ModelColorGroup.cpp Source/Model/Classes/NMR_ModelCompositeMaterials.cpp Source/Model/Classes/NMR_ModelBuildItem.cpp @@ -126,6 +141,16 @@ Source/Model/Classes/NMR_ModelTexture2D.cpp Source/Model/Classes/NMR_ModelTexture2DGroup.cpp Source/Model/Classes/NMR_ModelSlice.cpp Source/Model/Classes/NMR_ModelSliceStack.cpp +Source/Model/Classes/NMR_KeyStore.cpp +Source/Model/Classes/NMR_KeyStoreConsumer.cpp +Source/Model/Classes/NMR_KeyStoreAccessRight.cpp +Source/Model/Classes/NMR_KeyStoreFactory.cpp +Source/Model/Classes/NMR_KeyStoreResourceData.cpp +Source/Model/Classes/NMR_KeyStoreResourceDataGroup.cpp +Source/Model/Classes/NMR_KeyStoreCEKParams.cpp +Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ball.cpp +Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BallRef.cpp +Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Balls.cpp Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beam.cpp Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beams.cpp Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamLattice.cpp @@ -134,12 +159,15 @@ Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSets Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ref.cpp Source/Model/Reader/NMR_ModelReader.cpp Source/Model/Reader/NMR_ModelReaderNode.cpp -Source/Model/Reader/NMR_ModelReaderNode_Model.cpp -Source/Model/Reader/NMR_ModelReaderWarnings.cpp +Source/Model/Reader/NMR_ModelReaderNode_ModelBase.cpp +Source/Model/Reader/NMR_ModelReaderNode_KeyStoreBase.cpp Source/Model/Reader/NMR_ModelReader_3MF.cpp +Source/Model/Reader/NMR_ModelReader_3MF_Native.cpp Source/Model/Reader/NMR_ModelReader_ColorMapping.cpp +Source/Model/Reader/NMR_ModelReader_InstructionElement.cpp Source/Model/Reader/NMR_ModelReader_STL.cpp Source/Model/Reader/NMR_ModelReader_TexCoordMapping.cpp +Source/Model/Reader/NMR_KeyStoreOpcPackageReader.cpp Source/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterial.cpp Source/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterials.cpp Source/Model/Reader/v100/NMR_ModelReaderNode100_Build.cpp @@ -189,14 +217,27 @@ Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefResources.cpp Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceStack.cpp Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertex.cpp Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertices.cpp +Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStore.cpp +Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.cpp +Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreKEKParams.cpp +Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.cpp +Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreConsumer.cpp +Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreAccessRight.cpp +Source/Model/Reader/NMR_ModelReaderNode_StringValue.cpp +Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceData.cpp +Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceDataGroup.cpp +Source/Model/Writer/NMR_KeyStoreOpcPackageWriter.cpp Source/Model/Writer/NMR_ModelWriter.cpp Source/Model/Writer/NMR_ModelWriterNode.cpp +Source/Model/Writer/NMR_ModelWriterNode_ModelBase.cpp +Source/Model/Writer/NMR_ModelWriterNode_KeyStoreBase.cpp Source/Model/Writer/NMR_ModelWriter_3MF.cpp Source/Model/Writer/NMR_ModelWriter_3MF_Native.cpp Source/Model/Writer/NMR_ModelWriter_ColorMapping.cpp Source/Model/Writer/NMR_ModelWriter_STL.cpp Source/Model/Writer/NMR_ModelWriter_TexCoordMapping.cpp Source/Model/Writer/NMR_ModelWriter_TexCoordMappingContainer.cpp +Source/Model/Writer/SecureContent101/NMR_ModelWriterNode_KeyStore.cpp Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp Source/Model/Writer/v100/NMR_ModelWriterNode100_Model.cpp ) diff --git a/Source/Common/Mesh/NMR_BeamLattice.cpp b/Source/Common/Mesh/NMR_BeamLattice.cpp index 9ca772e4c..ae5a4f15e 100644 --- a/Source/Common/Mesh/NMR_BeamLattice.cpp +++ b/Source/Common/Mesh/NMR_BeamLattice.cpp @@ -37,11 +37,23 @@ namespace NMR { CBeamLattice::CBeamLattice(_In_ MESHNODES &nodes) : m_Nodes(nodes) { m_dMinLength = 0.0001; + m_eBallMode = eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_NONE; + m_dDefaultBallRadius = 0.0; } - void CBeamLattice::clear() { + void CBeamLattice::clearBeams() { m_Beams.clearAllData(); m_pBeamSets.clear(); + m_OccupiedNodes.clear(); + } + + void CBeamLattice::clearBalls() { + m_Balls.clearAllData(); + } + + void CBeamLattice::clear() { + clearBeams(); + clearBalls(); } } diff --git a/Source/Common/Mesh/NMR_Mesh.cpp b/Source/Common/Mesh/NMR_Mesh.cpp index 8a5b166e2..b02d3dcea 100644 --- a/Source/Common/Mesh/NMR_Mesh.cpp +++ b/Source/Common/Mesh/NMR_Mesh.cpp @@ -70,12 +70,14 @@ namespace NMR { if (!pMesh) throw CNMRException(NMR_ERROR_INVALIDPARAM); - nfInt32 nIdx, nNodeCount, nFaceCount, nBeamCount, j; + nfInt32 nIdx, nNodeCount, nFaceCount, nBeamCount, nBallCount, j; MESHNODE * pNode; MESHFACE * pFace; MESHBEAM * pBeam; + MESHBALL * pBall; MESHNODE * pFaceNodes[3]; MESHNODE * pBeamNodes[2]; + MESHNODE * pBallNode; // Copy Mesh Information CMeshInformationHandler * pOtherMeshInformationHandler = pMesh->getMeshInformationHandler(); @@ -87,6 +89,7 @@ namespace NMR { nNodeCount = pMesh->getNodeCount(); nFaceCount = pMesh->getFaceCount(); nBeamCount = pMesh->getBeamCount(); + nBallCount = pMesh->getBallCount(); if (nNodeCount > 0) { std::vector aNewNodes; @@ -130,6 +133,16 @@ namespace NMR { addBeam(pBeamNodes[0], pBeamNodes[1], pBeam->m_radius[0], pBeam->m_radius[1], pBeam->m_capMode[0], pBeam->m_capMode[1]); } } + if (nBallCount > 0) { + for (nIdx = 0; nIdx < nBallCount; nIdx++) { + pBall = pMesh->getBall(nIdx); + if ((pBall->m_nodeindex < 0) || (pBall->m_nodeindex >= nNodeCount)) + throw CNMRException(NMR_ERROR_INVALIDNODEINDEX); + + pBallNode = aNewNodes[pBall->m_nodeindex]; + addBall(pBallNode, pBall->m_radius); + } + } } } @@ -215,7 +228,7 @@ namespace NMR { if (nFaceCount >= NMR_MESH_MAXFACECOUNT) throw CNMRException(NMR_ERROR_TOOMANYFACES); - nfUint32 nNewIndex; + nfUint32 nNewIndex = 0; pFace = m_Faces.allocData (nNewIndex); pFace->m_nodeindices[0] = pNode1->m_index; @@ -282,6 +295,8 @@ namespace NMR { pBeam->m_capMode[0] = eCapMode1; pBeam->m_capMode[1] = eCapMode2; + m_BeamLattice.m_OccupiedNodes.insert({ pNode1->m_index, pNode2->m_index }); + return pBeam; } @@ -291,6 +306,32 @@ namespace NMR { return m_BeamLattice.m_pBeamSets.back(); } + _Ret_notnull_ MESHBALL * CMesh::addBall(_In_ MESHNODE * pNode, _In_ nfDouble dRadius) + { + if ((!pNode)) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + + MESHBALL * pBall; + nfUint32 nBallCount = getBallCount(); + + if (nBallCount >= NMR_MESH_MAXBALLCOUNT) + throw CNMRException(NMR_ERROR_TOOMANYBALLS); + + // Ensure that at least one beam exists at this node + if (m_BeamLattice.m_OccupiedNodes.find(pNode->m_index) == m_BeamLattice.m_OccupiedNodes.end()) { + throw CNMRException(NMR_ERROR_INVALIDPARAM); + } + + nfUint32 nNewIndex; + + pBall = m_BeamLattice.m_Balls.allocData(nNewIndex); + pBall->m_nodeindex = pNode->m_index; + pBall->m_index = nNewIndex; + pBall->m_radius = dRadius; + + return pBall; + } + nfUint32 CMesh::getNodeCount() { return m_Nodes.getCount (); @@ -311,6 +352,21 @@ namespace NMR { return (nfUint32)(m_BeamLattice.m_pBeamSets.size()); } + nfUint32 CMesh::getBallCount() + { + return m_BeamLattice.m_Balls.getCount(); + } + + nfUint32 CMesh::getOccupiedNodeCount() + { + return (nfUint32)m_BeamLattice.m_OccupiedNodes.size(); + } + + nfBool CMesh::isNodeOccupied(_In_ nfUint32 nIdx) + { + return m_BeamLattice.m_OccupiedNodes.find(nIdx) != m_BeamLattice.m_OccupiedNodes.end(); + } + _Ret_notnull_ MESHNODE * CMesh::getNode(_In_ nfUint32 nIdx) { return m_Nodes.getData(nIdx); @@ -333,6 +389,18 @@ namespace NMR { return m_BeamLattice.m_pBeamSets[nIdx]; } + _Ret_notnull_ MESHBALL * CMesh::getBall(_In_ nfUint32 nIdx) + { + return m_BeamLattice.m_Balls.getData(nIdx); + } + + _Ret_notnull_ MESHNODE * CMesh::getOccupiedNode(_In_ nfUint32 nIdx) + { + std::unordered_set::iterator iter = m_BeamLattice.m_OccupiedNodes.begin(); + std::advance(iter, nIdx); + return getNode(*iter); + } + void CMesh::setBeamLatticeMinLength(nfDouble dMinLength) { m_BeamLattice.m_dMinLength = dMinLength; @@ -348,12 +416,32 @@ namespace NMR { return 1.0; } + void CMesh::setDefaultBallRadius(nfDouble dDefaultBallRadius) + { + m_BeamLattice.m_dDefaultBallRadius = dDefaultBallRadius; + } + + nfDouble CMesh::getDefaultBallRadius() + { + return m_BeamLattice.m_dDefaultBallRadius; + } + nfBool CMesh::getBeamLatticeAccuracy(nfDouble& dAccuracy) { dAccuracy = 1.0; return false; } + void CMesh::setBeamLatticeBallMode(eModelBeamLatticeBallMode eBallMode) + { + m_BeamLattice.m_eBallMode = eBallMode; + } + + eModelBeamLatticeBallMode CMesh::getBeamLatticeBallMode() + { + return m_BeamLattice.m_eBallMode; + } + eModelBeamLatticeCapMode CMesh::getBeamLatticeCapMode() { return eModelBeamLatticeCapMode::MODELBEAMLATTICECAPMODE_SPHERE; @@ -366,6 +454,7 @@ namespace NMR { nfUint32 nNodeCount = getNodeCount(); nfUint32 nFaceCount = getFaceCount(); nfUint32 nBeamCount = getBeamCount(); + nfUint32 nBallCount = getBallCount(); // max 2^31-1 billion Nodes/Faces if (nNodeCount > NMR_MESH_MAXNODECOUNT) @@ -374,6 +463,8 @@ namespace NMR { return false; if (nBeamCount > NMR_MESH_MAXBEAMCOUNT) return false; + if (nBallCount > NMR_MESH_MAXBALLCOUNT) + return false; for (nIdx = 0; nIdx < nNodeCount; nIdx++) { MESHNODE * node = getNode(nIdx); @@ -405,6 +496,12 @@ namespace NMR { if (beam->m_nodeindices[0] == beam->m_nodeindices[1]) return false; } + + for (nIdx = 0; nIdx < nBallCount; nIdx++) { + MESHBALL* ball = getBall(nIdx); + if ((ball->m_nodeindex < 0) || (((nfUint32)ball->m_nodeindex) >= nNodeCount)) + return false; + } return true; } @@ -420,31 +517,67 @@ namespace NMR { m_BeamLattice.clear(); } + void CMesh::clearBeamLatticeBeams() { + m_BeamLattice.clearBeams(); + } + + void CMesh::clearBeamLatticeBalls() { + m_BeamLattice.clearBalls(); + } + + void CMesh::scanOccupiedNodes() { + m_BeamLattice.m_OccupiedNodes.clear(); + + nfUint32 beamCount = m_BeamLattice.m_Beams.getCount(); + for (nfUint32 iBeam = 0; iBeam < beamCount; iBeam++) { + MESHBEAM * meshBeam = getBeam(iBeam); + m_BeamLattice.m_OccupiedNodes.insert({ meshBeam->m_nodeindices[0], meshBeam->m_nodeindices[1] }); + } + } + + void CMesh::validateBeamLatticeBalls() { + nfUint32 ballCount = m_BeamLattice.m_Balls.getCount(); + MESHBALL * ballData = new MESHBALL[ballCount]; + for (nfUint32 iBall = 0; iBall < ballCount; iBall++) { + ballData[iBall] = *m_BeamLattice.m_Balls.getData(iBall); + } + + clearBeamLatticeBalls(); + for (nfUint32 iBall = 0; iBall < ballCount; iBall++) { + try { + addBall(getNode(ballData[iBall].m_nodeindex), ballData[iBall].m_radius); + } + catch (CNMRException) {} + } + + delete [] ballData; + } + void CMesh::clearMeshInformationHandler() { m_pMeshInformationHandler.reset(); } - void CMesh::patchMeshInformationResources(_In_ std::map &oldToNewMapping) + void CMesh::patchMeshInformationResources(_In_ std::map &oldToNewMapping) { NMR::CMeshInformationHandler *pMeshInformationHandler = this->getMeshInformationHandler(); if (pMeshInformationHandler) { NMR::CMeshInformation *pProperties = dynamic_cast(pMeshInformationHandler->getInformationByType(0, NMR::emiProperties)); if (pProperties) { NMR::MESHINFORMATION_PROPERTIES * pDefaultData = (NMR::MESHINFORMATION_PROPERTIES*)pProperties->getDefaultData(); - if (pDefaultData && pDefaultData->m_nResourceID != 0) { - NMR::PackageResourceID nNewResourceID = oldToNewMapping[pDefaultData->m_nResourceID]; + if (pDefaultData && pDefaultData->m_nUniqueResourceID != 0) { + NMR::UniqueResourceID nNewResourceID = oldToNewMapping[pDefaultData->m_nUniqueResourceID]; if (nNewResourceID == 0) throw CNMRException(NMR_ERROR_UNKNOWNMODELRESOURCE); - pDefaultData->m_nResourceID = nNewResourceID; + pDefaultData->m_nUniqueResourceID = nNewResourceID; } for (NMR::nfUint32 nFaceIndex = 0; nFaceIndex < this->getFaceCount(); nFaceIndex++) { NMR::MESHINFORMATION_PROPERTIES * pFaceData = (NMR::MESHINFORMATION_PROPERTIES*)pProperties->getFaceData(nFaceIndex); - if (pFaceData && pFaceData->m_nResourceID != 0) { - NMR::PackageResourceID nNewResourceID = oldToNewMapping[pFaceData->m_nResourceID]; + if (pFaceData && pFaceData->m_nUniqueResourceID != 0) { + NMR::UniqueResourceID nNewResourceID = oldToNewMapping[pFaceData->m_nUniqueResourceID]; if (nNewResourceID == 0) throw CNMRException(NMR_ERROR_UNKNOWNMODELRESOURCE); - pFaceData->m_nResourceID = nNewResourceID; + pFaceData->m_nUniqueResourceID = nNewResourceID; } } } diff --git a/Source/Common/MeshImport/NMR_MeshImporter_STL.cpp b/Source/Common/MeshImport/NMR_MeshImporter_STL.cpp index c41a3f53d..95f93fa6d 100644 --- a/Source/Common/MeshImport/NMR_MeshImporter_STL.cpp +++ b/Source/Common/MeshImport/NMR_MeshImporter_STL.cpp @@ -113,15 +113,17 @@ namespace NMR { if (!pStream) throw CNMRException(NMR_ERROR_NOIMPORTSTREAM); - /* - CMeshInformationHandler * pMeshInformationHandler = NULL; - PMeshInformation_NodeColors pMeshInformation = NULL; - if (m_bImportColors) { - pMeshInformation = std::make_shared(); - pMeshInformationHandler->addInformation(pMeshInformation); - } */ + // TODO: handle colors + //CMeshInformationHandler * pMeshInformationHandler = pMesh->createMeshInformationHandler(); + //CMeshInformation * pInformation = pMeshInformationHandler->getInformationByType(0, emiProperties); + //CMeshInformation_Properties * pProperties = nullptr; - // TODO: Color Handling! + //if (!pProperties) { + // PMeshInformation_Properties pNewMeshInformation = std::make_shared(pMesh->getFaceCount()); + // pMeshInformationHandler->addInformation(pNewMeshInformation); + + // pProperties = pNewMeshInformation.get(); + //} std::array aSTLHeader; nfUint32 nFaceCount = 0; @@ -190,27 +192,16 @@ namespace NMR { if ((!bIsValid) && !m_bIgnoreInvalidFaces) throw CNMRException(NMR_ERROR_INVALIDCOORDINATES); - /* if (bIsValid) { MESHFACE * pFace = pMesh->addFace(pNodes[0], pNodes[1], pNodes[2]); - if (pMeshInformation) { - nfUint32 nRed = (nfUint32) ((nfFloat) (Facet.m_attribute & 0x1f) / (255.0f / 31.0f)); - nfUint32 nGreen = (nfUint32)((nfFloat)((Facet.m_attribute >> 5) & 0x1f) / (255.0f / 31.0f)); - nfUint32 nBlue = (nfUint32)((nfFloat)((Facet.m_attribute >> 10) & 0x1f) / (255.0f / 31.0f));; - - MESHINFORMATION_NODECOLOR * pNodeColorInfo = (MESHINFORMATION_NODECOLOR*)pMeshInformation->getFaceData(pFace->m_index); - if ((Facet.m_attribute & 0x8000) == 0) { - pNodeColorInfo->m_cColors[0] = nRed + (nGreen << 8) + (nBlue << 16); - } else { - pNodeColorInfo->m_cColors[0] = nGlobalColor; - } + //if (pProperties) { + // nfUint32 nRed = (nfUint32) ((nfFloat) (Facet.m_attribute & 0x1f) / (255.0f / 31.0f)); + // nfUint32 nGreen = (nfUint32)((nfFloat)((Facet.m_attribute >> 5) & 0x1f) / (255.0f / 31.0f)); + // nfUint32 nBlue = (nfUint32)((nfFloat)((Facet.m_attribute >> 10) & 0x1f) / (255.0f / 31.0f)); - pNodeColorInfo->m_cColors[1] = pNodeColorInfo->m_cColors[0]; - pNodeColorInfo->m_cColors[2] = pNodeColorInfo->m_cColors[0]; - } - } + // // MESHINFORMATION_PROPERTIES * pFaceData = (NMR::MESHINFORMATION_PROPERTIES*)pProperties->getFaceData(pFace->m_index); + //} } - */ } } diff --git a/Source/Common/MeshInformation/NMR_MeshInformation_Properties.cpp b/Source/Common/MeshInformation/NMR_MeshInformation_Properties.cpp index d6867f403..1e55b3468 100644 --- a/Source/Common/MeshInformation/NMR_MeshInformation_Properties.cpp +++ b/Source/Common/MeshInformation/NMR_MeshInformation_Properties.cpp @@ -42,23 +42,23 @@ namespace NMR { { } - nfUint32 CMeshInformation_PropertyIndexMapping::registerPropertyID(nfUint32 nResourceID, ModelPropertyID nPropertyID, nfUint32 nResourceIndex) + nfUint32 CMeshInformation_PropertyIndexMapping::registerPropertyID(UniqueResourceID nUniqueResourceID, ModelPropertyID nPropertyID, nfUint32 nResourceIndex) { - if (nResourceID == 0) + if (nUniqueResourceID == 0) throw CNMRException(NMR_ERROR_INVALIDPROPERTYRESOURCEID); - m_IDMap.insert(std::make_pair(std::make_pair(nResourceID, nPropertyID), nResourceIndex)); + m_IDMap.insert(std::make_pair(std::make_pair(nUniqueResourceID, nPropertyID), nResourceIndex)); return nResourceIndex; } - nfUint32 CMeshInformation_PropertyIndexMapping::mapPropertyIDToIndex(nfUint32 nResourceID, ModelPropertyID nPropertyID) + nfUint32 CMeshInformation_PropertyIndexMapping::mapPropertyIDToIndex(UniqueResourceID nUniqueResourceID, ModelPropertyID nPropertyID) { - if (nResourceID == 0) + if (nUniqueResourceID == 0) throw CNMRException(NMR_ERROR_INVALIDPROPERTYRESOURCEID); - auto iIterator = m_IDMap.find(std::make_pair(nResourceID, nPropertyID)); + auto iIterator = m_IDMap.find(std::make_pair(nUniqueResourceID, nPropertyID)); if (iIterator == m_IDMap.end()) throw CNMRException(NMR_ERROR_PROPERTYIDNOTFOUND); @@ -103,7 +103,7 @@ namespace NMR { MESHINFORMATION_PROPERTIES * pProperties = (MESHINFORMATION_PROPERTIES *)pData; if (pProperties) { - pProperties->m_nResourceID = 0; + pProperties->m_nUniqueResourceID = 0; for (j = 0; j < 3; j++) { pProperties->m_nPropertyIDs[j] = 0; } @@ -127,7 +127,7 @@ namespace NMR { for (nfUint32 j = 0; j < 3; j++) pTargetDefaultData->m_nPropertyIDs[j] = pSourceDefaultData->m_nPropertyIDs[j]; - pTargetDefaultData->m_nResourceID = pSourceDefaultData->m_nResourceID; + pTargetDefaultData->m_nUniqueResourceID = pSourceDefaultData->m_nUniqueResourceID; } } @@ -143,7 +143,7 @@ namespace NMR { for (nfUint32 j = 0; j < 3; j++) pTargetFaceData->m_nPropertyIDs[j] = pSourceFaceData->m_nPropertyIDs[j]; - pTargetFaceData->m_nResourceID = pSourceFaceData->m_nResourceID; + pTargetFaceData->m_nUniqueResourceID = pSourceFaceData->m_nUniqueResourceID; } } @@ -179,7 +179,7 @@ namespace NMR { { MESHINFORMATION_PROPERTIES * pFaceData = (MESHINFORMATION_PROPERTIES*)getFaceData(nFaceIndex); if (pFaceData) - return (pFaceData->m_nResourceID != 0); + return (pFaceData->m_nUniqueResourceID != 0); return false; } diff --git a/Source/Common/NMR_Exception.cpp b/Source/Common/NMR_Exception.cpp index 7b2ba831f..607b32df1 100644 --- a/Source/Common/NMR_Exception.cpp +++ b/Source/Common/NMR_Exception.cpp @@ -178,7 +178,7 @@ namespace NMR { case NMR_ERROR_DUPLICATETEXTURE: return "Texture is already existing"; case NMR_ERROR_DUPLICATETEXTUREID: return "Texture ID is already existing"; case NMR_ERROR_PARTTOOLARGE: return "Part is too large"; - case NMR_ERROR_DUPLICATETEXTUREPATH: return "Texture path is already existing"; + case NMR_ERROR_DUPLICATETEXTUREPATH: return "Texture getPath is already existing"; case NMR_ERROR_DUPLICATETEXTUREWIDTH: return "Texture width is already existing"; case NMR_ERROR_DUPLICATETEXTUREHEIGHT: return "Texture height is already existing"; case NMR_ERROR_DUPLICATETEXTUREDEPTH: return "Texture depth is already existing"; @@ -332,7 +332,7 @@ namespace NMR { case NMR_ERROR_SLICESTACK_SLICESANDSLICEREF: return "Slicestack contains slices and slicerefs"; case NMR_ERROR_ILLFORMATUUID: return "A UUID is ill formatted"; case NMR_ERROR_INVALIDSLICESTACK: return "A slice stack resource is invalid"; - case NMR_ERROR_DUPLICATEPATH: return "Duplicate path attribute"; + case NMR_ERROR_DUPLICATEPATH: return "Duplicate getPath attribute"; case NMR_ERROR_DUPLICATEUUID: return "Duplicate UUID attribute"; case NMR_ERROR_REFERENCESTOODEEP: return "References in production extension go deeper than one level."; case NMR_ERROR_SLICEREFSTOODEEP: return "A slicestack referenced via a slicepath cannot reference another slicestack."; @@ -396,7 +396,40 @@ namespace NMR { case NMR_ERROR_MULTIPROPERTIES_INVALID_MULTI_ELEMENT: return "A multi-element is invalid"; case NMR_ERROR_INVALID_RESOURCE_INDEX: return "A Resource Index is invalid"; case NMR_ERROR_VERSION093_NOT_SUPPORTED: return "This document contains content from Version 093 of the core-specification. This is not fully supported by Lib3MF version 2 or later."; - + case NMR_ERROR_ATTACHMENTMODELMISMATCH: return "The model of an attachment does not match the model of a resource."; + case NMR_ERROR_DUPLICATEPACKAGEPATH: return "The PackagePath of a model is not unique."; + case NMR_ERROR_PRODUCTIONEXTENSION_REQUIRED: return "Serialization of this Model requires the production extension."; + case NMR_ERROR_MODELRESOURCE_IN_DIFFERENT_MODEL: return "Referenced model resource must not be in a different model."; + case NMR_ERROR_PATH_NOT_ABSOLUTE: return "A path attribute element is not absolute."; + case NMR_ERROR_BEAMSET_IDENTIFIER_NOT_UNIQUE: return "A beamset identifier is not unique."; + //keystore error codes + case NMR_ERROR_KEYSTOREDUPLICATECONSUMER: return "A consumer already exists for this consumerid"; + case NMR_ERROR_KEYSTOREDUPLICATECONSUMERID: return "The attribute consumerid is duplicated"; + case NMR_ERROR_KEYSTOREDUPLICATECONSUMERKEYID: return "The KeyStore Consumer key id is not unique "; + case NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATAPATH: return "The attribute path is duplicated"; + case NMR_ERROR_KEYSTOREDUPLICATECONSUMERINDEX: return "The attribute consumerindex is duplicated"; + case NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATA: return "A ResourceData already exists for this path in the KeyStore"; + case NMR_ERROR_KEYSTOREDUPLICATEACCESSRIGHT: return "An AccessRight already exists for this consumer in a ResourceDataGroup"; + case NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATAGROUP: return "A resource data group already exist for this keyuuid"; + case NMR_ERROR_KEYSTOREINVALIDALGORITHM: return "The algorithm attribute is invalid"; + case NMR_ERROR_KEYSTOREINVALIDCOMPRESSION: return "The KeyStore ResourceData compression is invalid"; + case NMR_ERROR_KEYSTOREINVALIDCIPHERVALUE: return "Invalid CipherValue elment value"; + case NMR_ERROR_KEYSTOREINVALIDMGF: return "The mfgalgorithm attribute has invalid value"; + case NMR_ERROR_KEYSTOREINVALIDDIGEST: return "The digestmethod attribute has invalid value"; + case NMR_ERROR_KEYSTOREINVALIDCONSUMERINDEX: return "The attribute consumerindex is invalid"; + case NMR_ERROR_KEYSTOREINVALIDKEYUUID: return "Attribute keyuuid is invalid, a default value has been assigned."; + case NMR_ERROR_KEYSTOREMISSINGCIPHERDATA: return "Element cipherdata is missing"; + case NMR_ERROR_KEYSTOREMISSINGCONSUMERID: return "Attribute consumerid is missing, a default value has been assigned."; + case NMR_ERROR_KEYSTOREMISSINGCONSUMERINDEX: return "Attribute consumerindex is missing, a default value has been assigned."; + case NMR_ERROR_KEYSTOREMISSINGKEKPARAMS: return "Element kekparams is missing, , default values have been assigned."; + case NMR_ERROR_KEYSTOREMISSINGCEKPARAMS: return "Element cekparams is missing."; + case NMR_ERROR_KEYSTOREMISSINGKEYUUID: return "Attribute keyuuid is missing, , a default value has been assigned."; + case NMR_ERROR_KEYSTOREMISSINGPATH: return "Attribute path is missing on a resouredata"; + case NMR_ERROR_KEYSTOREMISSINGALGORTHM: return "An algorithm attribute is missing, a default value has been assigned."; + case NMR_ERROR_KEYSTOREINCONSISTENTKEKPARAMS: return "Element kekparams ha invalid configuration"; + case NMR_ERROR_KEYSTOREOPCCOULDNOTGETSTREAM: return "Could not get KeyStore stream"; + case NMR_ERROR_KEYSTOREUNSUPPORTEDALGORITHM: return "The algorithm attribute is unsupported"; + case NMR_ERROR_KEYSTORETOOMANYELEMENTS: return "Too many elements added to a keystore tree"; // XML Parser Error Constants(0x9XXX) case NMR_ERROR_XMLPARSER_INVALIDATTRIBVALUE: return "Invalid XML attribute value"; @@ -432,6 +465,9 @@ namespace NMR { case NMR_ERROR_INVALIDNAMELENGTH: return "Invalid name length"; case NMR_ERROR_COULDNOTCREATEMODEL: return "Could not create model"; case NMR_ERROR_INVALIDTEXTURETYPE: return "Invalid Texture type"; + case NMR_ERROR_KEKDESCRIPTORNOTFOUND: return "Required key encryption client was not registered for a consumer"; + case NMR_ERROR_DEKDESCRIPTORNOTFOUND: return "Required data encryption client was not registered"; + case NMR_ERROR_RNGCALLBACKNOTCRYPTOSTRONG: return "Using cryptographically weak random number generator"; default: return "unknown error"; diff --git a/Source/Model/Reader/NMR_ModelReaderWarnings.cpp b/Source/Common/NMR_ModelWarnings.cpp similarity index 61% rename from Source/Model/Reader/NMR_ModelReaderWarnings.cpp rename to Source/Common/NMR_ModelWarnings.cpp index 896be5dc9..ae796c607 100644 --- a/Source/Model/Reader/NMR_ModelReaderWarnings.cpp +++ b/Source/Common/NMR_ModelWarnings.cpp @@ -32,65 +32,59 @@ a relaxed import policy on the file format. --*/ -#include "Model/Reader/NMR_ModelReaderWarnings.h" +#include "Common/NMR_ModelWarnings.h" namespace NMR { - CModelReaderWarning::CModelReaderWarning(std::string sMessage, eModelReaderWarningLevel WarningLevel, nfError nErrorCode) + CModelWarning::CModelWarning(std::string sMessage, eModelWarningLevel WarningLevel, nfError nErrorCode) { m_sMessage = sMessage; m_WarningLevel = WarningLevel; m_nErrorCode = nErrorCode; } - std::string CModelReaderWarning::getMessage() + std::string CModelWarning::getMessage() { return m_sMessage; } - eModelReaderWarningLevel CModelReaderWarning::getWarningLevel() + eModelWarningLevel CModelWarning::getWarningLevel() { return m_WarningLevel; } - nfError CModelReaderWarning::getErrorCode() + nfError CModelWarning::getErrorCode() { return m_nErrorCode; } - CModelReaderWarnings::CModelReaderWarnings() + CModelWarnings::CModelWarnings() { setCriticalWarningLevel(mrwFatal); } - eModelReaderWarningLevel CModelReaderWarnings::getCriticalWarningLevel() + eModelWarningLevel CModelWarnings::getCriticalWarningLevel() { return m_CriticalWarningLevel; } - void CModelReaderWarnings::setCriticalWarningLevel(_In_ eModelReaderWarningLevel WarningLevel) + void CModelWarnings::setCriticalWarningLevel(_In_ eModelWarningLevel WarningLevel) { m_CriticalWarningLevel = WarningLevel; } - void CModelReaderWarnings::addWarning(_In_ std::string sMessage, _In_ nfError nErrorCode, eModelReaderWarningLevel WarningLevel) + void CModelWarnings::addWarning(_In_ nfError nErrorCode, eModelWarningLevel WarningLevel) { - if (m_Warnings.size() < NMR_MAXWARNINGCOUNT) { // Failsafe check for Index overflows - PModelReaderWarning pWarning = std::make_shared(sMessage, WarningLevel, nErrorCode); - m_Warnings.push_back(pWarning); - } - - if ((nfInt32)WarningLevel <= (nfInt32)m_CriticalWarningLevel) - throw CNMRException(nErrorCode); - + CNMRException e(nErrorCode); + addException(e, WarningLevel); } - void CModelReaderWarnings::addException(const _In_ CNMRException & Exception, _In_ eModelReaderWarningLevel WarningLevel) + void CModelWarnings::addException(const _In_ CNMRException & Exception, _In_ eModelWarningLevel WarningLevel) { if (m_Warnings.size() < NMR_MAXWARNINGCOUNT) { // Failsafe check for Index overflows std::string sMessage (Exception.what()); - PModelReaderWarning pWarning = std::make_shared(sMessage, WarningLevel, Exception.getErrorCode()); + PModelReaderWarning pWarning = std::make_shared(sMessage, WarningLevel, Exception.getErrorCode()); m_Warnings.push_back(pWarning); } @@ -98,12 +92,12 @@ namespace NMR { throw Exception; } - nfUint32 CModelReaderWarnings::getWarningCount() + nfUint32 CModelWarnings::getWarningCount() { return (nfUint32)m_Warnings.size(); } - PModelReaderWarning CModelReaderWarnings::getWarning(_In_ nfUint32 nIndex) + PModelReaderWarning CModelWarnings::getWarning(_In_ nfUint32 nIndex) { return m_Warnings[nIndex]; } diff --git a/Source/Common/NMR_SecureContext.cpp b/Source/Common/NMR_SecureContext.cpp new file mode 100644 index 000000000..8449ee23f --- /dev/null +++ b/Source/Common/NMR_SecureContext.cpp @@ -0,0 +1,35 @@ + +#include "Common/NMR_SecureContext.h" +#include "Common/NMR_Exception.h" +namespace NMR { + bool CSecureContext::hasDekCtx() const { + return m_bHasDek; + } + ContentEncryptionDescriptor CSecureContext::getDekCtx() const { + return m_sDekDescriptor; + } + void CSecureContext::setDekCtx(ContentEncryptionDescriptor const & descriptor) { + m_sDekDescriptor = descriptor; + m_bHasDek = true; + } + ClientConsumerMap::const_iterator CSecureContext::kekCtxBegin() const { + return m_ConsumerMap.cbegin(); + } + ClientConsumerMap::const_iterator CSecureContext::kekCtxEnd() const { + return m_ConsumerMap.cend(); + } + void CSecureContext::addKekCtx(std::string const & consumerId, KeyWrappingDescriptor const & descriptor) { + if (m_ConsumerMap.find(consumerId) != m_ConsumerMap.end()) + throw CNMRException(NMR_ERROR_KEYSTOREDUPLICATECONSUMERID); + m_ConsumerMap[consumerId] = descriptor; + } + KeyWrappingDescriptor CSecureContext::getKekCtx(std::string const & consumerId) const { + auto it = m_ConsumerMap.find(consumerId); + if (it != m_ConsumerMap.end()) + return (*it).second; + throw CNMRException(NMR_ERROR_KEKDESCRIPTORNOTFOUND); + } + bool CSecureContext::emptyKekCtx() const { + return m_ConsumerMap.empty(); + } +} \ No newline at end of file diff --git a/Source/Common/NMR_StringUtils.cpp b/Source/Common/NMR_StringUtils.cpp index 02108590a..a6d37ddca 100644 --- a/Source/Common/NMR_StringUtils.cpp +++ b/Source/Common/NMR_StringUtils.cpp @@ -823,6 +823,24 @@ namespace NMR { } } - + void decomposeKeyIntoNamespaceAndName(const std::string &sKey, std::string &sNameSpace, std::string &sName) { + size_t cInd = sKey.find(":"); + if (cInd != std::string::npos) { + sNameSpace = sKey.substr(0, cInd); + sName = sKey.substr(cInd + 1, sKey.length() - cInd); + } + else { + sNameSpace = ""; + sName = sKey; + } + } + + std::string composeNamespaceAndNameIntoKey(const std::string &sNameSpace, const std::string &sName) + { + if (sNameSpace.empty()) + return sName; + else + return sNameSpace + ":" + sName; + } } diff --git a/Source/Common/OPC/NMR_OpcPackagePart.cpp b/Source/Common/OPC/NMR_OpcPackagePart.cpp index e3a605b4b..68b2afdbc 100644 --- a/Source/Common/OPC/NMR_OpcPackagePart.cpp +++ b/Source/Common/OPC/NMR_OpcPackagePart.cpp @@ -60,6 +60,22 @@ namespace NMR { m_pImportStream = pImportStream; } + COpcPackagePart::COpcPackagePart(COpcPackagePart const & cp, PExportStream pExportStream) { + if (pExportStream.get() == nullptr) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + m_sURI = cp.m_sURI; + m_Relationships = cp.m_Relationships; + m_pExportStream = pExportStream; + } + + COpcPackagePart::COpcPackagePart(COpcPackagePart const & cp, PImportStream pImportStream) { + if (pImportStream.get() == nullptr) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + m_sURI = cp.m_sURI; + m_Relationships = cp.m_Relationships; + m_pImportStream = pImportStream; + } + std::string COpcPackagePart::getURI() { @@ -132,5 +148,4 @@ namespace NMR { pXMLWriter->WriteFullEndElement(); pXMLWriter->WriteEndDocument(); } - } diff --git a/Source/Common/OPC/NMR_OpcPackageReader.cpp b/Source/Common/OPC/NMR_OpcPackageReader.cpp index d1cd88d07..8f71b5eb5 100644 --- a/Source/Common/OPC/NMR_OpcPackageReader.cpp +++ b/Source/Common/OPC/NMR_OpcPackageReader.cpp @@ -54,7 +54,7 @@ namespace NMR { case ZIP_SOURCE_SUPPORTS: zip_int64_t bitmap; bitmap = zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, - ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_SUPPORTS, -1); + ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_SUPPORTS, -1); return bitmap; case ZIP_SOURCE_SEEK: @@ -94,13 +94,16 @@ namespace NMR { zipStat->valid |= ZIP_STAT_SIZE; return sizeof(zip_stat_t); + case ZIP_SOURCE_FREE: + return 0; + default: throw CNMRException(NMR_ERROR_ZIPCALLBACK); } return -1; } - COpcPackageReader::COpcPackageReader(_In_ PImportStream pImportStream, _In_ PModelReaderWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor) + COpcPackageReader::COpcPackageReader(_In_ PImportStream pImportStream, _In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor) : m_pWarnings(pWarnings), m_pProgressMonitor(pProgressMonitor) { if (!pImportStream) @@ -200,7 +203,7 @@ namespace NMR { } else { if (bMustBeUnique) - m_pWarnings->addException(CNMRException(NMR_ERROR_OPCRELATIONSHIPNOTUNIQUE), eModelReaderWarningLevel::mrwInvalidOptionalValue); + m_pWarnings->addException(CNMRException(NMR_ERROR_OPCRELATIONSHIPNOTUNIQUE), eModelWarningLevel::mrwInvalidOptionalValue); } } @@ -302,7 +305,7 @@ namespace NMR { } } - nfUint64 COpcPackageReader::GetPartSize(_In_ std::string sPath) + nfUint64 COpcPackageReader::getPartSize(_In_ std::string sPath) { std::string sRealPath = fnRemoveLeadingPathDelimiter(sPath); auto iIterator = m_ZIPEntries.find(sRealPath); diff --git a/Source/Common/OPC/NMR_OpcPackageRelationshipReader.cpp b/Source/Common/OPC/NMR_OpcPackageRelationshipReader.cpp index ef24c00e8..eac4a4146 100644 --- a/Source/Common/OPC/NMR_OpcPackageRelationshipReader.cpp +++ b/Source/Common/OPC/NMR_OpcPackageRelationshipReader.cpp @@ -185,7 +185,7 @@ namespace NMR { bContinue = pXMLReader->MoveToNextAttribute(); } - // must be non-empty and absolute path + // must be non-empty and absolute getPath if (sTarget.empty()) // || (sTarget[0] != L'/') ) throw CNMRException(NMR_ERROR_INVALIDOPCPARTURI); diff --git a/Source/Common/OPC/NMR_OpcPackageWriter.cpp b/Source/Common/OPC/NMR_OpcPackageWriter.cpp index 0be177e0f..c0112f9da 100644 --- a/Source/Common/OPC/NMR_OpcPackageWriter.cpp +++ b/Source/Common/OPC/NMR_OpcPackageWriter.cpp @@ -38,6 +38,8 @@ NMR_OpcPackageWriter.cpp defines an OPC Package writer in a portable way. #include "Model/Classes/NMR_ModelConstants.h" +#include + namespace NMR { @@ -48,6 +50,8 @@ namespace NMR { m_pExportStream = pExportStream; m_pZIPWriter = std::make_shared(m_pExportStream, true); + + m_nRelationIDCounter = 0; } COpcPackageWriter::~COpcPackageWriter() @@ -68,19 +72,60 @@ namespace NMR { void COpcPackageWriter::addContentType(_In_ std::string sExtension, _In_ std::string sContentType) { - m_ContentTypes.insert(std::make_pair(sExtension, sContentType)); + m_DefaultContentTypes.insert(std::make_pair(sExtension, sContentType)); } - POpcPackageRelationship COpcPackageWriter::addRootRelationship(_In_ std::string sID, _In_ std::string sType, _In_ COpcPackagePart * pTargetPart) + void COpcPackageWriter::addContentType(POpcPackagePart pOpcPackagePart, std::string sContentType) + { + // Follows section 10.1.2.3 of "Ecma Office Open XML Part 2 - Open Packaging Conventions" + nfBool isOverride = false; + + // Step 1 - Get extension + std::size_t extensionPosition = pOpcPackagePart->getURI().find_last_of('.'); + if (std::string::npos == extensionPosition) // Step 2 - No extension available, use Override Content Type + isOverride = true; + else { + // Step 3 - Compare extensions with Default Content Types + std::string extension = pOpcPackagePart->getURI().substr(extensionPosition + 1); + std::map::iterator defaultSameExtension = m_DefaultContentTypes.find(extension); + if (m_DefaultContentTypes.end() != defaultSameExtension) { + // Step 4 - An extension assigned to a Default Content Type matches + if (defaultSameExtension->second.compare(sContentType) == 0) { + // Step 4.a - Content Types match, nothing else to do + isOverride = false; + addContentType(extension, sContentType); + } + else // Step 4.b - Content Types do not match, use Override Content Type + isOverride = true; + } + else // Step 5 - No Default Content Type that matches, use Override Content Type + isOverride = true; + } + + if (isOverride) + m_OverrideContentTypes.insert(std::make_pair(pOpcPackagePart->getURI(), sContentType)); + } + + POpcPackageRelationship COpcPackageWriter::addRootRelationship(_In_ std::string sType, _In_ COpcPackagePart * pTargetPart) { if (pTargetPart == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); - POpcPackageRelationship pRelationship = std::make_shared(sID, sType, pTargetPart->getURI()); + POpcPackageRelationship pRelationship = std::make_shared(generateRelationShipID(), sType, pTargetPart->getURI()); m_RootRelationships.push_back(pRelationship); return pRelationship; } + POpcPackageRelationship COpcPackageWriter::addPartRelationship(POpcPackagePart pOpcPackagePart, std::string sType, COpcPackagePart * pTargetPart) + { + return pOpcPackagePart->addRelationship(generateRelationShipID(), sType, pTargetPart->getURI()); + } + + std::list COpcPackageWriter::addWriterSpecificRelationships(_In_ POpcPackagePart pOpcPackagePart, _In_ COpcPackagePart* pTargetPart) + { + return std::list(); + } + void COpcPackageWriter::finishPackage() { writeContentTypes(); @@ -113,14 +158,24 @@ namespace NMR { pXMLWriter->WriteStartElement(nullptr, OPC_CONTENTTYPES_CONTAINER, nullptr); pXMLWriter->WriteAttributeString(nullptr, "xmlns", nullptr, OPCPACKAGE_SCHEMA_CONTENTTYPES); - auto iIterator = m_ContentTypes.begin(); - while (iIterator != m_ContentTypes.end()) { + auto iDefaultIterator = m_DefaultContentTypes.begin(); + while (iDefaultIterator != m_DefaultContentTypes.end()) { pXMLWriter->WriteStartElement(nullptr, OPC_CONTENTTYPES_NODE, nullptr); - pXMLWriter->WriteAttributeString(nullptr, OPC_CONTENTTYPES_ATTRIB_EXTENSION, nullptr, iIterator->first.c_str()); - pXMLWriter->WriteAttributeString(nullptr, OPC_CONTENTTYPES_ATTRIB_CONTENTTYPE, nullptr, iIterator->second.c_str()); + pXMLWriter->WriteAttributeString(nullptr, OPC_CONTENTTYPES_ATTRIB_EXTENSION, nullptr, iDefaultIterator->first.c_str()); + pXMLWriter->WriteAttributeString(nullptr, OPC_CONTENTTYPES_ATTRIB_CONTENTTYPE, nullptr, iDefaultIterator->second.c_str()); pXMLWriter->WriteEndElement(); - iIterator++; + iDefaultIterator++; + } + + auto iOverrideIterator = m_OverrideContentTypes.begin(); + while (iOverrideIterator != m_OverrideContentTypes.end()) { + pXMLWriter->WriteStartElement(nullptr, OPC_CONTENTTYPES_NODE_OVERRIDE, nullptr); + pXMLWriter->WriteAttributeString(nullptr, OPC_CONTENTTYPES_ATTRIB_PARTNAME, nullptr, iOverrideIterator->first.c_str()); + pXMLWriter->WriteAttributeString(nullptr, OPC_CONTENTTYPES_ATTRIB_CONTENTTYPE, nullptr, iOverrideIterator->second.c_str()); + pXMLWriter->WriteEndElement(); + + iOverrideIterator++; } pXMLWriter->WriteFullEndElement(); @@ -153,4 +208,12 @@ namespace NMR { } + std::string COpcPackageWriter::generateRelationShipID() + { + // Create Unique ID String + std::stringstream sStream; + sStream << "rel" << m_nRelationIDCounter; + m_nRelationIDCounter++; + return sStream.str(); + } } diff --git a/Source/Common/Platform/NMR_EncryptionHeader.cpp b/Source/Common/Platform/NMR_EncryptionHeader.cpp new file mode 100644 index 000000000..14e3934c0 --- /dev/null +++ b/Source/Common/Platform/NMR_EncryptionHeader.cpp @@ -0,0 +1,58 @@ + + +#include "Common/Platform/NMR_EncryptionHeader.h" +#include "Common/NMR_ErrorConst.h" +#include "Common/NMR_Exception.h" + +#include "Common/Platform/NMR_ImportStream.h" +#include "Common/Platform/NMR_ExportStream.h" + +#include "Common/NMR_Architecture_Utils.h" +#include +namespace NMR { + + CEncryptionHeader::CEncryptionHeader(std::vector const & additionalData) + :m_rgAdditionalData(additionalData) + { + } + + size_t CEncryptionHeader::readFrom(PImportStream from) { + uEncryptedFileHeader header = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; + from->readBuffer(header.bytes, sizeof(header), true); + if (isBigEndian()) { + header.Header.Length.length = swapBytes(header.Header.Length.length); + } + constexpr size_t sigSize = sizeof(header.Header.Signature.bytes); + if (strncmp((char *)header.Header.Signature.bytes, "%3McF", sigSize) != 0) + throw CNMRException(NMR_ERROR_COULDNOTREADENCRYPTEDSTREAM); + if (header.Header.majorVersion != 0 || header.Header.minorVersion != 0) + throw CNMRException(NMR_ERROR_ENCRYPTEDCONTENTVERSIONUNSUPPORTED); + constexpr size_t headerSize = sizeof(header); + nfUint32 remainingBytes = header.Header.Length.length - headerSize; + if (remainingBytes > 0) { + m_rgAdditionalData.resize(remainingBytes, 0); + from->readBuffer(m_rgAdditionalData.data(), remainingBytes, true); + } + m_nfHeaderSize = header.Header.Length.length; + return m_nfHeaderSize; + } + size_t CEncryptionHeader::writeTo(PExportStream to) { + uEncryptedFileHeader header = { { '%', '3', 'M', 'c', 'F', 0, 0, 0, 0, 0, 0, 0 } }; + constexpr size_t headerSize = sizeof(header); + m_nfHeaderSize = (nfUint32)(headerSize + m_rgAdditionalData.size()); + header.Header.Length.length = (nfUint32)m_nfHeaderSize; + if (isBigEndian()) { + header.Header.Length.length = swapBytes(header.Header.Length.length); + } + to->writeBuffer(header.bytes, headerSize); + if (m_rgAdditionalData.size() > 0) + to->writeBuffer(m_rgAdditionalData.data(), m_rgAdditionalData.size()); + return m_nfHeaderSize; + } + std::vector const & CEncryptionHeader::additionalData() const { + return m_rgAdditionalData; + } + nfUint64 CEncryptionHeader::headerSize() const { + return m_nfHeaderSize; + } +} \ No newline at end of file diff --git a/Source/Common/Platform/NMR_ExportStream.cpp b/Source/Common/Platform/NMR_ExportStream.cpp index cc55f094c..a8354da56 100644 --- a/Source/Common/Platform/NMR_ExportStream.cpp +++ b/Source/Common/Platform/NMR_ExportStream.cpp @@ -38,6 +38,11 @@ This is an abstract base stream class for exporting from various data sources. namespace NMR { + void CExportStream::close() + { + // do nothing + } + void CExportStream::copyFrom(_In_ CImportStream * pImportStream, _In_ nfUint64 cbCount, _In_ nfUint32 cbBufferSize) { if (pImportStream == nullptr) @@ -64,6 +69,8 @@ namespace NMR { cbCount -= cbBytesToCopy; } + + close(); } diff --git a/Source/Common/Platform/NMR_ExportStream_Compressed.cpp b/Source/Common/Platform/NMR_ExportStream_Compressed.cpp new file mode 100644 index 000000000..e4b745386 --- /dev/null +++ b/Source/Common/Platform/NMR_ExportStream_Compressed.cpp @@ -0,0 +1,114 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ExportStream_Compressed.h defines a stream to write compressed files + +--*/ + +#include "Common/Platform/NMR_ExportStream_Compressed.h" +#include "Common/NMR_Exception.h" + +namespace NMR { + + CExportStream_Compressed::CExportStream_Compressed(PExportStream pUncompressedStream) + { + if (nullptr == pUncompressedStream) + throw CNMRException(NMR_ERROR_INVALIDPOINTER); + m_pUncompressedStream = pUncompressedStream; + + m_strm.zalloc = Z_NULL; + m_strm.zfree = Z_NULL; + m_strm.opaque = Z_NULL; + if (deflateInit(&m_strm, Z_DEFAULT_COMPRESSION) != Z_OK) + throw CNMRException(NMR_ERROR_COULDNOTINITDEFLATE); + } + + CExportStream_Compressed::~CExportStream_Compressed() + { + (void)deflateEnd(&m_strm); + } + + nfBool CExportStream_Compressed::seekPosition(_In_ nfUint64 position, _In_ nfBool bHasToSucceed) + { + throw CNMRException(NMR_ERROR_NOTIMPLEMENTED); + } + + nfBool CExportStream_Compressed::seekForward(_In_ nfUint64 bytes, _In_ nfBool bHasToSucceed) + { + throw CNMRException(NMR_ERROR_NOTIMPLEMENTED); + } + + nfBool CExportStream_Compressed::seekFromEnd(_In_ nfUint64 bytes, _In_ nfBool bHasToSucceed) + { + throw CNMRException(NMR_ERROR_NOTIMPLEMENTED); + } + + nfUint64 CExportStream_Compressed::getPosition() + { + throw CNMRException(NMR_ERROR_NOTIMPLEMENTED); + } + + nfInt32 CExportStream_Compressed::compress(nfInt32 flush) { + nfInt32 ret; + do { + m_strm.avail_out = (nfUint32) EXPORTSTREAM_WRITE_BUFFER_CHUNKSIZE; + m_strm.next_out = out; + ret = deflate(&m_strm, flush); + switch (ret) { + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)deflateEnd(&m_strm); + throw CNMRException(NMR_ERROR_COULDNOTDEFLATE); + } + int toWrite = EXPORTSTREAM_WRITE_BUFFER_CHUNKSIZE - m_strm.avail_out; + m_pUncompressedStream->writeBuffer(out, toWrite); + } while (m_strm.avail_out == 0); + return ret; + } + + nfUint64 CExportStream_Compressed::writeBuffer(_In_ const void * pBuffer, _In_ nfUint64 cbTotalBytesToWrite) + { + if (nullptr == pBuffer) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + + m_strm.avail_in = (nfUint32) cbTotalBytesToWrite; + m_strm.next_in = (Bytef *) pBuffer; + compress(Z_NO_FLUSH); + + return cbTotalBytesToWrite; + } + + void CExportStream_Compressed::close() + { + if (compress(Z_FINISH) != Z_STREAM_END) { + throw CNMRException(NMR_ERROR_COULDNOTDEFLATE); + } + } + +} diff --git a/Source/Common/Platform/NMR_ExportStream_Encrypted.cpp b/Source/Common/Platform/NMR_ExportStream_Encrypted.cpp new file mode 100644 index 000000000..16c28bed5 --- /dev/null +++ b/Source/Common/Platform/NMR_ExportStream_Encrypted.cpp @@ -0,0 +1,53 @@ +#include "Common/Platform/NMR_ExportStream_Encrypted.h" +#include "Common/NMR_Exception.h" + +namespace NMR { + CExportStream_Encrypted::CExportStream_Encrypted(PExportStream pEncryptedStream, ContentEncryptionDescriptor context) + :m_pEncryptedStream(pEncryptedStream), m_pDecryptContext(context) + { + if (nullptr == pEncryptedStream) + throw CNMRException(NMR_ERROR_INVALIDPOINTER); + m_header.writeTo(m_pEncryptedStream); + } + + nfBool CExportStream_Encrypted::seekPosition(nfUint64 position, nfBool bHasToSucceed) + { + return m_pEncryptedStream->seekPosition(position + m_header.headerSize(), bHasToSucceed); + } + + nfBool CExportStream_Encrypted::seekForward(nfUint64 bytes, nfBool bHasToSucceed) + { + return m_pEncryptedStream->seekForward(bytes, bHasToSucceed); + } + + nfBool CExportStream_Encrypted::seekFromEnd(nfUint64 bytes, nfBool bHasToSucceed) + { + if (m_pEncryptedStream->getPosition() + m_header.headerSize() >= bytes) { + return m_pEncryptedStream->seekFromEnd(bytes, bHasToSucceed); + } else if (bHasToSucceed) { + throw CNMRException(NMR_ERROR_COULDNOTSEEKSTREAM); + } + return false; + } + + nfUint64 CExportStream_Encrypted::getPosition() + { + return m_pEncryptedStream->getPosition() - m_header.headerSize(); + } + + nfUint64 CExportStream_Encrypted::writeBuffer(const void * pBuffer, nfUint64 cbTotalBytesToWrite) + { + nfUint64 encryptedBytes = 0; + if (cbTotalBytesToWrite > 0) { + std::vector encryptBuffer(cbTotalBytesToWrite, 0); + encryptedBytes = m_pDecryptContext.m_fnCrypt(cbTotalBytesToWrite, (const nfByte *)pBuffer, encryptBuffer.data(), m_pDecryptContext.m_sDekDecryptData); + if (encryptedBytes > 0) { + auto writtenBytes = m_pEncryptedStream->writeBuffer(encryptBuffer.data(), encryptedBytes); + if (encryptedBytes != writtenBytes) + throw CNMRException(NMR_ERROR_CALCULATIONTERMINATED); + } + } + return encryptedBytes; + } + +} \ No newline at end of file diff --git a/Source/Common/Platform/NMR_ImportStream_Compressed.cpp b/Source/Common/Platform/NMR_ImportStream_Compressed.cpp new file mode 100644 index 000000000..541c1fa85 --- /dev/null +++ b/Source/Common/Platform/NMR_ImportStream_Compressed.cpp @@ -0,0 +1,139 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ImportStream_Compressed.h defines the CImportStream_Compressed Class. +This is a stream class for importing from a compressed object. + +--*/ + +#include "Common/Platform/NMR_ImportStream_Shared_Memory.h" +#include "Common/Platform/NMR_ImportStream_Compressed.h" +#include "Common/NMR_Exception.h" + +namespace NMR { + + CImportStream_Compressed::CImportStream_Compressed(PImportStream pCompressedStream) + { + if (nullptr == pCompressedStream) + throw CNMRException(NMR_ERROR_INVALIDPOINTER); + m_pCompressedStream = pCompressedStream; + + // Source: http://zlib.net/zpipe.c + m_strm.zalloc = Z_NULL; + m_strm.zfree = Z_NULL; + m_strm.opaque = Z_NULL; + m_strm.avail_in = 0; + m_strm.next_in = Z_NULL; + + if (inflateInit(&m_strm) != Z_OK) + throw CNMRException(NMR_ERROR_COULDNOTINITINFLATE); + } + + CImportStream_Compressed::~CImportStream_Compressed() + { + (void)inflateEnd(&m_strm); + } + + nfBool CImportStream_Compressed::seekPosition(_In_ nfUint64 position, _In_ nfBool bHasToSucceed) + { + return m_pCompressedStream->seekPosition(position, bHasToSucceed); + } + + nfBool CImportStream_Compressed::seekForward(_In_ nfUint64 bytes, _In_ nfBool bHasToSucceed) + { + return m_pCompressedStream->seekForward(bytes, bHasToSucceed); + } + + nfBool CImportStream_Compressed::seekFromEnd(_In_ nfUint64 bytes, _In_ nfBool bHasToSucceed) + { + return m_pCompressedStream->seekFromEnd(bytes, bHasToSucceed); + } + + nfUint64 CImportStream_Compressed::getPosition() + { + return m_pCompressedStream->getPosition(); + } + + nfUint64 CImportStream_Compressed::readBuffer(nfByte * pBuffer, nfUint64 cbTotalBytesToRead, nfBool bNeedsToReadAll) + { + nfBool firstRead = m_strm.next_in == Z_NULL; + nfBool hasDecompressLeftovers = m_strm.avail_out == 0; + if (firstRead || !hasDecompressLeftovers) { + m_strm.avail_in = (nfUint32) m_pCompressedStream->readBuffer(in, IMPORTSTREAM_COMPRESSED_CHUNKSIZE, bNeedsToReadAll); + if (m_strm.avail_in == 0) + return 0; + m_strm.next_in = in; + } + + m_strm.avail_out = (nfUint32) cbTotalBytesToRead; + m_strm.next_out = pBuffer; + nfInt32 ret = inflate(&m_strm, Z_NO_FLUSH); + switch (ret) { + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&m_strm); + throw CNMRException(NMR_ERROR_COULDNOTINFLATE); + } + if (m_strm.avail_out == 0) { + nfBool reachedEndOfBuffer = m_strm.avail_in == 0; + if (reachedEndOfBuffer && ret != Z_STREAM_END) { + throw CNMRException(NMR_ERROR_COULDNOTINFLATE); + } + return cbTotalBytesToRead; + } + + nfUint64 bytesDecompressed = cbTotalBytesToRead - m_strm.avail_out; + return readBuffer(pBuffer + bytesDecompressed, m_strm.avail_out, bNeedsToReadAll) + bytesDecompressed; + } + + nfUint64 CImportStream_Compressed::retrieveSize() + { + return m_decompressedBuffer.size(); + } + + void CImportStream_Compressed::writeToFile(_In_ const nfWChar * pwszFileName) + { + throw CNMRException(NMR_ERROR_NOTIMPLEMENTED); + } + + PImportStream CImportStream_Compressed::copyToMemory() + { + nfUint64 bytesRead; + nfUint64 currentPosition = 0; + nfUint64 chunkSize = IMPORTSTREAM_READ_BUFFER_CHUNKSIZE; + do { + m_decompressedBuffer.resize(m_decompressedBuffer.size() + chunkSize); + bytesRead = readBuffer(&m_decompressedBuffer[currentPosition], chunkSize, false); + currentPosition += bytesRead; + } while (chunkSize == bytesRead); + return std::make_shared(m_decompressedBuffer.data(), m_decompressedBuffer.size()); + } + + +} diff --git a/Source/Common/Platform/NMR_ImportStream_Encrypted.cpp b/Source/Common/Platform/NMR_ImportStream_Encrypted.cpp new file mode 100644 index 000000000..d62e7bafb --- /dev/null +++ b/Source/Common/Platform/NMR_ImportStream_Encrypted.cpp @@ -0,0 +1,91 @@ +/*++ + +Copyright (C) 2020 3MF Consortium (Original Author) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: This is a stub class implementation of CImportStream_Encrypted + +*/ + +#include "Common/Platform/NMR_ImportStream_Encrypted.h" +#include "Common/Platform/NMR_ImportStream_Unique_Memory.h" +#include "Common/NMR_Exception.h" +#include +#include +namespace NMR { + CImportStream_Encrypted::CImportStream_Encrypted(PImportStream pEncryptedStream, ContentEncryptionDescriptor pDecryptContext) + :m_pEncryptedStream(pEncryptedStream), m_pDecryptContext(pDecryptContext) + { + if (nullptr == pEncryptedStream) + throw CNMRException(NMR_ERROR_INVALIDPOINTER); + m_header.readFrom(pEncryptedStream); + } + + nfBool CImportStream_Encrypted::seekPosition(nfUint64 position, nfBool bHasToSucceed) { + return m_pEncryptedStream->seekPosition(position + m_header.headerSize(), bHasToSucceed); + } + + nfBool CImportStream_Encrypted::seekForward(nfUint64 bytes, nfBool bHasToSucceed) { + return m_pEncryptedStream->seekForward(bytes, bHasToSucceed); + } + + nfBool CImportStream_Encrypted::seekFromEnd(nfUint64 bytes, nfBool bHasToSucceed) { + if (m_pEncryptedStream->getPosition() + m_header.headerSize() >= bytes) { + return m_pEncryptedStream->seekFromEnd(bytes, bHasToSucceed); + } else if (bHasToSucceed) { + throw CNMRException(NMR_ERROR_COULDNOTSEEKSTREAM); + } + return false; + } + + nfUint64 CImportStream_Encrypted::readBuffer(nfByte * pBuffer, nfUint64 cbTotalBytesToRead, nfBool bNeedsToReadAll) { + std::vector decBuffer(cbTotalBytesToRead, 0); + nfUint64 bytesRead = m_pEncryptedStream->readBuffer(decBuffer.data(), cbTotalBytesToRead, bNeedsToReadAll); + if (bytesRead > 0) { + nfUint64 decryted = m_pDecryptContext.m_fnCrypt(bytesRead, decBuffer.data(), pBuffer, m_pDecryptContext.m_sDekDecryptData); + if (decryted != bytesRead) + throw CNMRException(NMR_ERROR_CALCULATIONTERMINATED); + } + return bytesRead; + } + + nfUint64 CImportStream_Encrypted::retrieveSize() { + return m_pEncryptedStream->retrieveSize() - m_header.headerSize(); + } + + void CImportStream_Encrypted::writeToFile(const nfWChar * pwszFileName) { + m_pEncryptedStream->writeToFile(pwszFileName); + } + + PImportStream CImportStream_Encrypted::copyToMemory() { + nfUint64 cbStreamSize = retrieveSize(); + return std::make_shared(this, cbStreamSize, false); + } + + nfUint64 CImportStream_Encrypted::getPosition() { + return m_pEncryptedStream->getPosition() - m_header.headerSize(); + } + + +} \ No newline at end of file diff --git a/Source/Libraries/cpp-base64/base64.cpp b/Source/Libraries/cpp-base64/base64.cpp new file mode 100644 index 000000000..82a175a4a --- /dev/null +++ b/Source/Libraries/cpp-base64/base64.cpp @@ -0,0 +1,125 @@ +/* + base64.cpp and base64.h + + base64 encoding and decoding with C++. + + Version: 1.01.00 + + Copyright (C) 2004-2017 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + + DISCLAIMER + This is a modified version. +*/ + +#include "Libraries/cpp-base64/base64.h" + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + +static inline bool is_base64(unsigned char c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +std::string base64_encode(std::vector const & buffer) { + size_t in_len = buffer.size(); + unsigned char const * bytes_to_encode = buffer.data(); + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while((i++ < 3)) + ret += '='; + + } + + return ret; + +} + +std::vector base64_decode(std::string const& encoded_string) { + size_t in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::vector ret; + + while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i ==4) { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]) & 0xff; + + char_array_3[0] = ( char_array_4[0] << 2 ) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret.push_back(char_array_3[i]); + i = 0; + } + } + + if (i) { + for (j = 0; j < i; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]) & 0xff; + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + + for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]); + } + + return ret; +} diff --git a/Source/Model/Classes/NMR_KeyStore.cpp b/Source/Model/Classes/NMR_KeyStore.cpp new file mode 100644 index 000000000..418a85c9d --- /dev/null +++ b/Source/Model/Classes/NMR_KeyStore.cpp @@ -0,0 +1,222 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStore.cpp implements the KeyStore Class. +A KeyStore is an in memory representation of the 3MF file. + +--*/ + +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_KeyStoreConsumer.h" +#include "Model/Classes/NMR_KeyStoreResourceDataGroup.h" +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_PackageResourceID.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_StringUtils.h" +#include +#include + +namespace NMR { + CKeyStore::CKeyStore() { + m_UUID = std::make_shared(); + } + + CKeyStore::~CKeyStore() { + clearAll(); + } + + PUUID CKeyStore::getUUID() + { + return m_UUID; + } + + void CKeyStore::setUUID(PUUID uuid) + { + m_UUID = uuid; + } + + void CKeyStore::addConsumer(PKeyStoreConsumer const & consumer) + { + std::lock_guard guard(mtx); + if (m_Consumers.size() >= XML_3MF_SECURE_CONTENT_MAXELEMENTCOUNT) + throw CNMRException(NMR_ERROR_KEYSTORETOOMANYELEMENTS); + + std::string const id = consumer->getConsumerID(); + if (m_ConsumerRefs.find(id) != m_ConsumerRefs.end()) { + throw CNMRException(NMR_ERROR_KEYSTOREDUPLICATECONSUMER); + } + m_Consumers.push_back(consumer); + m_ConsumerRefs[id] = consumer; + } + + nfUint64 CKeyStore::getConsumerCount() const + { + return m_Consumers.size(); + } + + PKeyStoreConsumer CKeyStore::getConsumer(nfUint64 index) const + { + if (index >= m_Consumers.size()) + throw CNMRException(NMR_ERROR_INVALIDINDEX); + return m_Consumers[index]; + } + + PKeyStoreConsumer CKeyStore::findConsumerById(std::string id) + { + auto ref = m_ConsumerRefs.find(id); + if ( ref != m_ConsumerRefs.end()) + return (*ref).second; + return nullptr; + } + + void CKeyStore::removeConsumer(NMR::PKeyStoreConsumer consumer) + { + std::lock_guard guard(mtx); + size_t n = m_ConsumerRefs.erase(consumer->getConsumerID()); + if (n > 0) { + for (auto it : m_ResourceDataGroups) { + it->removeAccessRight(consumer->getConsumerID()); + } + auto found = std::find(m_Consumers.begin(), m_Consumers.end(), consumer); + m_Consumers.erase(found); + } + } + + nfUint64 CKeyStore::getResourceDataGroupCount() const + { + return m_ResourceDataGroups.size(); + } + + PKeyStoreResourceDataGroup CKeyStore::getResourceDataGroup(nfUint64 index) const { + if (index < m_ResourceDataGroups.size()) + return m_ResourceDataGroups[index]; + throw CNMRException(NMR_ERROR_INVALIDINDEX); + } + + void CKeyStore::addResourceDataGroup(PKeyStoreResourceDataGroup const & dataGroup) + { + std::lock_guard guard(mtx); + + if (m_ResourceDataGroups.size() >= XML_3MF_SECURE_CONTENT_MAXELEMENTCOUNT) + throw CNMRException(NMR_ERROR_KEYSTORETOOMANYELEMENTS); + + PUUID const keyUUID = dataGroup->getKeyUUID(); + if (m_ResourceDataGroupsRefs.find(keyUUID) != m_ResourceDataGroupsRefs.end()) { + throw CNMRException(NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATAGROUP); + } + m_ResourceDataGroups.push_back(dataGroup); + m_ResourceDataGroupsRefs[keyUUID] = dataGroup; + } + + PKeyStoreResourceDataGroup CKeyStore::findResourceDataGroupByResourceDataPath(PPackageModelPath const & rdPath) { + auto found = findResourceData(rdPath); + if (nullptr != found) + return found->getGroup(); + return nullptr; + } + + void CKeyStore::removeResourceDataGroup(PKeyStoreResourceDataGroup rdg) { + throw CNMRException(NMR_ERROR_NOTIMPLEMENTED); + } + + nfUint64 CKeyStore::addResourceData(PKeyStoreResourceData const & rd) { + std::lock_guard guard(mtx); + + if (m_ResourceDatas.size() >= XML_3MF_SECURE_CONTENT_MAXELEMENTCOUNT) + throw CNMRException(NMR_ERROR_KEYSTORETOOMANYELEMENTS); + + if (nullptr == rd->getGroup()) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + + auto found = m_ResourceDataRefs.find(rd->packagePath()); + if (found != m_ResourceDataRefs.end()) + throw CNMRException(NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATA); + + m_ResourceDatas.push_back(rd); + m_ResourceDataRefs[rd->packagePath()] = rd; + return m_ResourceDatas.size() - 1; + } + + void CKeyStore::removeResourceData(NMR::PKeyStoreResourceData const & rd) { + std::lock_guard guard(mtx); + size_t n = m_ResourceDataRefs.erase(rd->packagePath()); + if (n > 0) { + auto found = std::find(m_ResourceDatas.begin(), m_ResourceDatas.end(), rd); + m_ResourceDatas.erase(found); + } + } + + nfUint64 CKeyStore::getResourceDataCount() { + return m_ResourceDatas.size(); + } + + PKeyStoreResourceData CKeyStore::getResourceData(nfUint64 index) const { + if (index < m_ResourceDatas.size()) + return m_ResourceDatas[index]; + throw CNMRException(NMR_ERROR_INVALIDINDEX); + } + + PKeyStoreResourceData CKeyStore::findResourceData(PPackageModelPath const & path) { + auto found = m_ResourceDataRefs.find(path); + if (found != m_ResourceDataRefs.end()) + return (*found).second; + return nullptr; + } + + std::vector CKeyStore::getResourceDataByGroup(PKeyStoreResourceDataGroup const & rdg) const { + throw CNMRException(NMR_ERROR_NOTIMPLEMENTED); + } + + PKeyStoreResourceDataGroup CKeyStore::findResourceDataGroupByResourceDataPath(std::string const & rdPath) { + PKeyStoreResourceData rd = findResourceData(rdPath); + if (nullptr != rd) + return rd->getGroup(); + return nullptr; + } + + PKeyStoreResourceData CKeyStore::findResourceData(std::string const & path) { + auto found = std::find_if(m_ResourceDatas.begin(), m_ResourceDatas.end(), [&path](PKeyStoreResourceData const & rd) { + return rd->packagePath()->getPath() == path; + }); + if (found != m_ResourceDatas.end()) + return *found; + return nullptr; + } + + bool CKeyStore::empty() const { + return m_Consumers.empty() && m_ResourceDataGroups.empty(); + } + + void CKeyStore::clearAll() { + m_ConsumerRefs.clear(); + m_Consumers.clear(); + m_ResourceDataGroupsRefs.clear(); + m_ResourceDataGroups.clear(); + } + +} \ No newline at end of file diff --git a/Source/Model/Classes/NMR_KeyStoreAccessRight.cpp b/Source/Model/Classes/NMR_KeyStoreAccessRight.cpp new file mode 100644 index 000000000..0e5a87814 --- /dev/null +++ b/Source/Model/Classes/NMR_KeyStoreAccessRight.cpp @@ -0,0 +1,49 @@ +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +#include "Common/NMR_Exception.h" +namespace NMR { + CKeyStoreAccessRight::CKeyStoreAccessRight( + PKeyStoreConsumer const & consumer, + eKeyStoreWrapAlgorithm const algorithm, + eKeyStoreMaskGenerationFunction const mgf, + eKeyStoreMessageDigest const digest, + std::vector const & cipherValue) + :m_pConsumer(consumer), m_eAlgorithm(algorithm), m_eMgf(mgf), m_eDigest(digest), m_rgCipherValue(cipherValue) + { + if (nullptr == m_pConsumer) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + + if (algorithm != eKeyStoreWrapAlgorithm::RSA_OAEP) { + throw CNMRException(NMR_ERROR_KEYSTOREUNSUPPORTEDALGORITHM); + } + + if (mgf != eKeyStoreMaskGenerationFunction::MGF1_SHA1 + && mgf != eKeyStoreMaskGenerationFunction::MGF1_SHA256) { + throw CNMRException(NMR_ERROR_KEYSTOREUNSUPPORTEDALGORITHM); + } + + if (digest != eKeyStoreMessageDigest::SHA1 + && digest != eKeyStoreMessageDigest::SHA256) + throw CNMRException(NMR_ERROR_KEYSTOREUNSUPPORTEDALGORITHM); + } + PKeyStoreConsumer CKeyStoreAccessRight::getConsumer() const { + return m_pConsumer; + } + eKeyStoreWrapAlgorithm CKeyStoreAccessRight::getAlgorithm() const { + return m_eAlgorithm; + } + eKeyStoreMaskGenerationFunction CKeyStoreAccessRight::getMgf() const { + return m_eMgf; + } + eKeyStoreMessageDigest CKeyStoreAccessRight::getDigest() const { + return m_eDigest; + } + std::vector const & CKeyStoreAccessRight::getCipherValue() const { + return m_rgCipherValue; + } + void CKeyStoreAccessRight::setCipherValue(std::vector const & cv) { + m_rgCipherValue = cv; + } + nfBool CKeyStoreAccessRight::isNew() const { + return m_rgCipherValue.empty(); + } +} \ No newline at end of file diff --git a/Source/Model/Classes/NMR_KeyStoreCEKParams.cpp b/Source/Model/Classes/NMR_KeyStoreCEKParams.cpp new file mode 100644 index 000000000..6c41421ec --- /dev/null +++ b/Source/Model/Classes/NMR_KeyStoreCEKParams.cpp @@ -0,0 +1,54 @@ +#include "Model/Classes/NMR_KeyStoreCEKParams.h" + +namespace NMR { + CKeyStoreCEKParams::CKeyStoreCEKParams( + nfBool const & compression, + eKeyStoreEncryptAlgorithm const & encryptionAlgorithm, + std::vector const & iv, + std::vector const & tag, + std::vector const & aad, + nfUint64 descriptor): m_bCompression(compression), m_eAlgorithm(encryptionAlgorithm), m_rgIv(iv), m_rgTag(tag), m_rgAad(aad), m_nDescriptor(descriptor) + { + } + + eKeyStoreEncryptAlgorithm CKeyStoreCEKParams::getEncryptionAlgorithm() const { + return m_eAlgorithm; + } + nfBool CKeyStoreCEKParams::isCompressed() const { + return m_bCompression; + } + std::vector const & CKeyStoreCEKParams::getInitVector() const { + return m_rgIv; + } + std::vector const & CKeyStoreCEKParams::getAuthTag() const { + return m_rgTag; + } + std::vector const & CKeyStoreCEKParams::getAddAuthData() const { + return m_rgAad; + } + nfUint64 CKeyStoreCEKParams::getDescriptor() const { + return m_nDescriptor; + } + void CKeyStoreCEKParams::setAuthTag(std::vector const & buf) { + m_rgTag = buf; + } + void CKeyStoreCEKParams::setAddAuthData(std::vector const & buf) { + m_rgAad = buf; + } + + + + CKeyStoreContentEncryptionParams::CKeyStoreContentEncryptionParams( + nfBool const & compression, + eKeyStoreEncryptAlgorithm const & encryptionAlgorithm, + std::vector const & key, + std::vector const & iv, + std::vector const & tag, + std::vector const & aad, + nfUint64 descriptor) : CKeyStoreCEKParams(compression, encryptionAlgorithm, iv, tag, aad, descriptor), m_rgKey(key) {} + + std::vector const & CKeyStoreContentEncryptionParams::getKey() const { + return m_rgKey; + } + +} diff --git a/Source/Model/Classes/NMR_KeyStoreConsumer.cpp b/Source/Model/Classes/NMR_KeyStoreConsumer.cpp new file mode 100644 index 000000000..5d062e249 --- /dev/null +++ b/Source/Model/Classes/NMR_KeyStoreConsumer.cpp @@ -0,0 +1,40 @@ +#include "Model/Classes/NMR_KeyStoreConsumer.h" +namespace NMR { + + CKeyStoreConsumer::CKeyStoreConsumer(std::string const & consumerID, std::string const & keyID, std::string keyValue) + { + m_sConsumerID = consumerID; + m_sKeyID = keyID; + m_sKeyValue = keyValue; + } + + std::string CKeyStoreConsumer::getConsumerID() const { + return m_sConsumerID; + } + + std::string CKeyStoreConsumer::getKeyID() const { + return m_sKeyID; + } + + void CKeyStoreConsumer::setKeyID(std::string const & keyID) { + m_sKeyID = keyID; + } + + nfBool CKeyStoreConsumer::hasKeyID() const { + return !m_sKeyID.empty(); + } + + std::string CKeyStoreConsumer::getKeyValue() const + { + return m_sKeyValue; + } + + void CKeyStoreConsumer::setKeyValue(std::string const & keyValue) + { + m_sKeyValue = keyValue; + } + + nfBool CKeyStoreConsumer::hasKeyValue() const { + return !m_sKeyValue.empty(); + } +} diff --git a/Source/Model/Classes/NMR_KeyStoreFactory.cpp b/Source/Model/Classes/NMR_KeyStoreFactory.cpp new file mode 100644 index 000000000..06298ca16 --- /dev/null +++ b/Source/Model/Classes/NMR_KeyStoreFactory.cpp @@ -0,0 +1,55 @@ + + +#include "Model/Classes/NMR_KeyStoreFactory.h" +#include "Model/Classes/NMR_Model.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_KeyStoreConsumer.h" +#include "Model/Classes/NMR_KeyStoreResourceDataGroup.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreCEKParams.h" +#include "Common/NMR_StringUtils.h" + +namespace NMR { + PKeyStore CKeyStoreFactory::makeKeyStore() { + return std::make_shared(); + } + + PKeyStoreResourceDataGroup CKeyStoreFactory::makeResourceDataGroup(PUUID const & keyUUID, std::vector const & key) { + PUUID uuid = (nullptr != keyUUID) ? keyUUID : std::make_shared(); + return std::make_shared(uuid, key); + } + + PKeyStoreConsumer CKeyStoreFactory::makeConsumer(std::string const & consumerID, std::string const & keyId, std::string const & keyValue) { + return std::make_shared(consumerID, keyId, keyValue); + } + + PKeyStoreAccessRight CKeyStoreFactory::makeAccessRight(PKeyStoreConsumer const & consumer, eKeyStoreWrapAlgorithm const algorithm, eKeyStoreMaskGenerationFunction const mask, eKeyStoreMessageDigest const digest, std::vector const & cipherValue) { + return std::make_shared(consumer, algorithm, mask, digest, cipherValue); + } + + PKeyStoreResourceData CKeyStoreFactory::makeResourceData(PKeyStoreResourceDataGroup const & rdg, PPackageModelPath const & path, PKeyStoreCEKParams params) { + return std::make_shared(rdg, path, + params->isCompressed(), + params->getEncryptionAlgorithm(), + params->getInitVector(), + params->getAuthTag(), + params->getAddAuthData()); + } + + PKeyStoreContentEncryptionParams CKeyStoreFactory::makeContentEncryptionParams(PKeyStoreResourceData rd, PKeyStoreResourceDataGroup rdg) { + return std::make_shared( + rd->isCompressed(), + rd->getEncryptionAlgorithm(), + rdg->getKey(), + rd->getInitVector(), + rd->getAuthTag(), + rd->getAddAuthData(), + rd->getDescriptor() + ); + } + + PKeyStoreCEKParams CKeyStoreFactory::makeCEKParams(nfBool compressed, eKeyStoreEncryptAlgorithm algorithm, std::vector const & aad, std::vector const & iv, std::vector const & tag) { + return std::make_shared(compressed, algorithm, iv, tag, aad, 0); + } +} \ No newline at end of file diff --git a/Source/Model/Classes/NMR_KeyStoreResourceData.cpp b/Source/Model/Classes/NMR_KeyStoreResourceData.cpp new file mode 100644 index 000000000..7d27c9dbf --- /dev/null +++ b/Source/Model/Classes/NMR_KeyStoreResourceData.cpp @@ -0,0 +1,30 @@ +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Common/NMR_Exception.h" +#include + +namespace NMR { + + + nfUint64 CKeyStoreResourceData::s_nfHandleCount = 0; + + CKeyStoreResourceData::CKeyStoreResourceData( + PKeyStoreResourceDataGroup const & rdg, + PPackageModelPath const& path, + bool compression, + eKeyStoreEncryptAlgorithm alg, + std::vector const & iv, + std::vector const & tag, + std::vector const & aad) + : CKeyStoreCEKParams(compression, alg, iv, tag, aad, ++s_nfHandleCount), + m_pGroup(rdg), m_pPath(path) + { + } + + void CKeyStoreResourceData::setInitVector(std::vector const & newIV) { + m_rgIv = newIV; + } + + void CKeyStoreResourceData::setAuthTag(std::vector const & newTag) { + m_rgTag = newTag; + } +} diff --git a/Source/Model/Classes/NMR_KeyStoreResourceDataGroup.cpp b/Source/Model/Classes/NMR_KeyStoreResourceDataGroup.cpp new file mode 100644 index 000000000..a9a33e713 --- /dev/null +++ b/Source/Model/Classes/NMR_KeyStoreResourceDataGroup.cpp @@ -0,0 +1,83 @@ +#include "Model/Classes/NMR_KeyStoreResourceDataGroup.h" +#include "Model/Classes/NMR_ModelConstants.h" +#include "Common/NMR_Exception.h" +#include + +namespace NMR { + + CKeyStoreResourceDataGroup::CKeyStoreResourceDataGroup(PUUID const& keyUUID, std::vector const & key) + { + m_sKeyUUID = keyUUID; + m_rgKey = key; + } + + void CKeyStoreResourceDataGroup::removeAccessRight(std::string const & consumerId) + { + std::lock_guard guard(mtx); + + if (consumerId.empty()) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + size_t n = m_ConsumerAccesstRight.erase(consumerId); + if (n > 0) { + auto it = m_AccessRights.begin(); + while (it != m_AccessRights.end()) { + if ((*it)->getConsumer()->getConsumerID() == consumerId) { + it = m_AccessRights.erase(it); + } + } + } + } + + PUUID CKeyStoreResourceDataGroup::getKeyUUID() const { + return m_sKeyUUID; + } + + nfUint64 CKeyStoreResourceDataGroup::addAccessRight(PKeyStoreAccessRight const & ar) + { + std::lock_guard guard(mtx); + + if (m_AccessRights.size() >= XML_3MF_SECURE_CONTENT_MAXELEMENTCOUNT) + throw CNMRException(NMR_ERROR_KEYSTORETOOMANYELEMENTS); + + std::string consumerId = ar->getConsumer()->getConsumerID(); + if (m_ConsumerAccesstRight.find(consumerId) != m_ConsumerAccesstRight.end()) { + throw CNMRException(NMR_ERROR_KEYSTOREDUPLICATEACCESSRIGHT); + } + + m_AccessRights.push_back(ar); + nfUint64 elIdx = m_AccessRights.size() - 1; + m_ConsumerAccesstRight[consumerId] = ar; + return elIdx; + } + + nfUint64 CKeyStoreResourceDataGroup::getAccessRightCount() + { + return m_AccessRights.size(); + } + + PKeyStoreAccessRight CKeyStoreResourceDataGroup::getAccessRight(nfUint64 index) const + { + if (index >= m_AccessRights.size()) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + return m_AccessRights[index]; + } + + PKeyStoreAccessRight CKeyStoreResourceDataGroup::findAccessRightByConsumerID(std::string const & consumerId) const + { + if (consumerId.empty()) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + auto found = m_ConsumerAccesstRight.find(consumerId); + if (found != m_ConsumerAccesstRight.end()) + return (*found).second; + return nullptr; + } + + std::vector const & CKeyStoreResourceDataGroup::getKey() const { + return m_rgKey; + } + + void CKeyStoreResourceDataGroup::setKey(std::vector const & key) { + m_rgKey = key; + } + +} diff --git a/Source/Model/Classes/NMR_Model.cpp b/Source/Model/Classes/NMR_Model.cpp index c9406ef33..3542c3d45 100644 --- a/Source/Model/Classes/NMR_Model.cpp +++ b/Source/Model/Classes/NMR_Model.cpp @@ -47,6 +47,7 @@ A model is an in memory representation of the 3MF file. #include "Model/Classes/NMR_ModelTexture2D.h" #include "Model/Classes/NMR_ModelSliceStack.h" #include "Model/Classes/NMR_ModelMetaDataGroup.h" +#include "Model/Classes/NMR_KeyStore.h" #include "Common/Mesh/NMR_Mesh.h" #include "Common/MeshInformation/NMR_MeshInformation.h" @@ -54,6 +55,9 @@ A model is an in memory representation of the 3MF file. #include "Common/NMR_Exception.h" #include #include +#include +#include +#include #include "Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefModel.h" #include "Common/Platform/NMR_XmlReader.h" @@ -61,6 +65,9 @@ A model is an in memory representation of the 3MF file. #include "Common/Platform/NMR_ImportStream_Unique_Memory.h" #include "Common/NMR_StringUtils.h" + +#include "Model/Classes/NMR_KeyStoreFactory.h" + namespace NMR { CModel::CModel() @@ -68,9 +75,12 @@ namespace NMR { m_Unit = MODELUNIT_MILLIMETER; m_sLanguage = XML_3MF_LANG_US; m_nHandleCounter = 1; - m_sCurPath = ""; + m_pPath = m_resourceHandler.makePackageModelPath(PACKAGE_3D_MODEL_URI); + m_pCurPath = m_pPath; + m_pKeyStore = CKeyStoreFactory::makeKeyStore(); setBuildUUID(std::make_shared()); + m_MetaDataGroup = std::make_shared(); } @@ -79,24 +89,52 @@ namespace NMR { clearAll(); } - const std::string CModel::curPath() + PPackageModelPath CModel::currentModelPath() + { + return m_pCurPath; + } + + const std::string CModel::currentPath() + { + return m_pCurPath->getPath(); + } + + void CModel::setCurrentPath(const std::string sPath) { - return m_sCurPath; + if (PPackageModelPath pModelPath = m_resourceHandler.findPackageModelPath(sPath)) { + m_pCurPath = pModelPath; + } + else { + m_pCurPath = m_resourceHandler.makePackageModelPath(sPath); + } } - void CModel::setCurPath(const std::string sPath) + PPackageModelPath CModel::rootModelPath() { - m_sCurPath = sPath; + return m_pPath; } const std::string CModel::rootPath() { - return m_sRootPath; + return m_pPath->getPath(); } void CModel::setRootPath(const std::string sPath) { - m_sRootPath = sPath; + m_pPath->setPath(sPath); + } + + PPackageModelPath CModel::findOrCreateModelPath(std::string sPath) + { + if (PPackageModelPath pModelPath = m_resourceHandler.findPackageModelPath(sPath)) { + return pModelPath; + } + return m_resourceHandler.makePackageModelPath(sPath); + } + + std::vector CModel::retrieveAllModelPaths() + { + return m_resourceHandler.retrieveAllModelPaths(); } // Merge all build items into one mesh @@ -172,16 +210,16 @@ namespace NMR { // General Resource Handling PModelResource CModel::findResource(_In_ std::string path, ModelResourceID nID) { - PPackageResourceID pID = m_resourceHandler.findResourceID(path, nID); + PPackageResourceID pID = m_resourceHandler.findResourceIDByPair(path, nID); if (pID.get()) return findResource(pID); else return nullptr; } - PModelResource CModel::findResource(_In_ PackageResourceID nID) + PModelResource CModel::findResource(_In_ UniqueResourceID nID) { - PPackageResourceID pID = m_resourceHandler.findResourceID(nID); + PPackageResourceID pID = m_resourceHandler.findResourceIDByUniqueID(nID); if (pID.get()) return findResource(pID); else @@ -190,7 +228,7 @@ namespace NMR { PModelResource CModel::findResource(_In_ PPackageResourceID pID) { - PackageResourceID uID = pID->getUniqueID(); + UniqueResourceID uID = pID->getUniqueID(); auto iIterator = m_ResourceMap.find(uID); if (iIterator != m_ResourceMap.end()) { @@ -201,11 +239,11 @@ namespace NMR { PPackageResourceID CModel::findPackageResourceID(_In_ std::string path, ModelResourceID nID) { - return m_resourceHandler.findResourceID(path, nID); + return m_resourceHandler.findResourceIDByPair(path, nID); } - PPackageResourceID CModel::findPackageResourceID(_In_ PackageResourceID nID) + PPackageResourceID CModel::findPackageResourceID(_In_ UniqueResourceID nID) { - return m_resourceHandler.findResourceID(nID); + return m_resourceHandler.findResourceIDByUniqueID(nID); } nfUint32 CModel::getResourceCount() @@ -231,7 +269,7 @@ namespace NMR { throw CNMRException(NMR_ERROR_INVALIDRESOURCECOUNT); // Check if ID already exists - PackageResourceID nID = pResource->getResourceID()->getUniqueID(); + UniqueResourceID nID = pResource->getPackageResourceID()->getUniqueID(); auto iIterator = m_ResourceMap.find(nID); if (iIterator != m_ResourceMap.end()) throw CNMRException(NMR_ERROR_DUPLICATEMODELRESOURCE); @@ -365,13 +403,34 @@ namespace NMR { return 1; } - PPackageResourceID CModel::generatePackageResourceID(_In_ std::string path, ModelResourceID nID) // per package + void CModel::updateUniqueResourceID(UniqueResourceID nOldID, UniqueResourceID nNewID) + { + if (m_ResourceMap.find(nNewID) != m_ResourceMap.end()) { + throw CNMRException(NMR_ERROR_DUPLICATEMODELRESOURCE); + } + else + { + auto iIterator = m_ResourceMap.find(nOldID); + if (iIterator == m_ResourceMap.end()) { + throw CNMRException(NMR_ERROR_INVALIDMODELRESOURCE); + } + m_ResourceMap.insert(std::make_pair<>(nNewID, iIterator->second)); + m_ResourceMap.erase(m_ResourceMap.find(nOldID)); + } + } + + PPackageResourceID CModel::generatePackageResourceID(_In_ std::string path, ModelResourceID nID) { - return m_resourceHandler.getNewResourceID(path, nID); + return m_resourceHandler.makePackageResourceID(path, nID); + } + + void CModel::removePackageResourceID(PPackageResourceID pID) + { + m_resourceHandler.removePackageResourceID(pID); } // Convenience functions for objects - _Ret_maybenull_ CModelObject * CModel::findObject(_In_ PackageResourceID nResourceID) + _Ret_maybenull_ CModelObject * CModel::findObject(_In_ UniqueResourceID nResourceID) { PModelResource pResource = findResource(nResourceID); if (pResource != nullptr) { @@ -494,9 +553,9 @@ namespace NMR { m_MetaDataGroup->clear(); } - _Ret_maybenull_ PModelBaseMaterialResource CModel::findBaseMaterial(_In_ PackageResourceID nResourceID) + _Ret_maybenull_ PModelBaseMaterialResource CModel::findBaseMaterial(_In_ PPackageResourceID pID) { - PModelResource pResource = findResource(nResourceID); + PModelResource pResource = findResource(pID); if (pResource != nullptr) { PModelBaseMaterialResource pBaseMaterialResource = std::dynamic_pointer_cast(pResource); if (pBaseMaterialResource.get() == nullptr) @@ -545,12 +604,12 @@ namespace NMR { pNewMaterial->mergeFrom(pOldMaterial); addResource(pNewMaterial); - oldToNewMapping[pOldMaterial->getResourceID()->getUniqueID()] = pNewMaterial->getResourceID()->getUniqueID(); + oldToNewMapping[pOldMaterial->getPackageResourceID()->getUniqueID()] = pNewMaterial->getPackageResourceID()->getUniqueID(); } } - _Ret_maybenull_ PModelColorGroupResource CModel::findColorGroup(_In_ PackageResourceID nResourceID) + _Ret_maybenull_ PModelColorGroupResource CModel::findColorGroup(_In_ UniqueResourceID nResourceID) { PModelResource pResource = findResource(nResourceID); if (pResource != nullptr) { @@ -602,12 +661,12 @@ namespace NMR { pNewColor->mergeFrom(pOldColor); addResource(pNewColor); - oldToNewMapping[pOldColor->getResourceID()->getUniqueID()] = pNewColor->getResourceID()->getUniqueID(); + oldToNewMapping[pOldColor->getPackageResourceID()->getUniqueID()] = pNewColor->getPackageResourceID()->getUniqueID(); } } - _Ret_maybenull_ PModelTexture2DGroupResource CModel::findTexture2DGroup(_In_ PackageResourceID nResourceID) + _Ret_maybenull_ PModelTexture2DGroupResource CModel::findTexture2DGroup(_In_ UniqueResourceID nResourceID) { PModelResource pResource = findResource(nResourceID); if (pResource != nullptr) { @@ -659,7 +718,7 @@ namespace NMR { if (!pOldTexture2D) { throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); } - PackageResourceID packageIDOfOldTexture = oldToNewMapping[pOldTexture2D->getResourceID()->getUniqueID()]; + UniqueResourceID packageIDOfOldTexture = oldToNewMapping[pOldTexture2D->getPackageResourceID()->getUniqueID()]; PModelTexture2DResource pNewTexture2D = findTexture2D(packageIDOfOldTexture); if (!pNewTexture2D) { throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); @@ -669,12 +728,12 @@ namespace NMR { pNewTexture2DGroup->mergeFrom(pOldTexture2DGroup); addResource(pNewTexture2DGroup); - oldToNewMapping[pOldTexture2DGroup->getResourceID()->getUniqueID()] = pNewTexture2DGroup->getResourceID()->getUniqueID(); + oldToNewMapping[pOldTexture2DGroup->getPackageResourceID()->getUniqueID()] = pNewTexture2DGroup->getPackageResourceID()->getUniqueID(); } } - _Ret_maybenull_ PModelCompositeMaterialsResource CModel::findCompositeMaterials(_In_ PackageResourceID nResourceID) + _Ret_maybenull_ PModelCompositeMaterialsResource CModel::findCompositeMaterials(_In_ UniqueResourceID nResourceID) { PModelResource pResource = findResource(nResourceID); if (pResource != nullptr) { @@ -723,8 +782,10 @@ namespace NMR { if (!pOldCompositeMaterials || !pOldBaseMaterial) { throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); } - PackageResourceID packageIDOfOldMaterial = oldToNewMapping[pOldBaseMaterial->getResourceID()->getUniqueID()]; - PModelBaseMaterialResource pNewBaseMaterialResource = findBaseMaterial(packageIDOfOldMaterial); + UniqueResourceID packageIDOfOldMaterial = oldToNewMapping[pOldBaseMaterial->getPackageResourceID()->getUniqueID()]; + + PPackageResourceID pNewIDOfOldMaterial = findPackageResourceID(packageIDOfOldMaterial); + PModelBaseMaterialResource pNewBaseMaterialResource = findBaseMaterial(pNewIDOfOldMaterial); if (!pNewBaseMaterialResource) { throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); } @@ -734,11 +795,11 @@ namespace NMR { pNewCompositeMaterials->mergeFrom(pOldCompositeMaterials); addResource(pNewCompositeMaterials); - oldToNewMapping[pOldCompositeMaterials->getResourceID()->getUniqueID()] = pNewCompositeMaterials->getResourceID()->getUniqueID(); + oldToNewMapping[pOldCompositeMaterials->getPackageResourceID()->getUniqueID()] = pNewCompositeMaterials->getPackageResourceID()->getUniqueID(); } } - _Ret_maybenull_ PModelMultiPropertyGroupResource CModel::findMultiPropertyGroup(_In_ PackageResourceID nResourceID) + _Ret_maybenull_ PModelMultiPropertyGroupResource CModel::findMultiPropertyGroup(_In_ UniqueResourceID nResourceID) { PModelResource pResource = findResource(nResourceID); if (pResource != nullptr) { @@ -788,11 +849,11 @@ namespace NMR { pNewMultiPropertyGroup->mergeFrom(pOldMultiPropertyGroup); addResource(pNewMultiPropertyGroup); - oldToNewMapping[pOldMultiPropertyGroup->getResourceID()->getUniqueID()] = pNewMultiPropertyGroup->getResourceID()->getUniqueID(); + oldToNewMapping[pOldMultiPropertyGroup->getPackageResourceID()->getUniqueID()] = pNewMultiPropertyGroup->getPackageResourceID()->getUniqueID(); } } - _Ret_maybenull_ PModelTexture2DResource CModel::findTexture2D(_In_ PackageResourceID nResourceID) + _Ret_maybenull_ PModelTexture2DResource CModel::findTexture2D(_In_ UniqueResourceID nResourceID) { PModelResource pResource = findResource(nResourceID); if (pResource != nullptr) { @@ -842,11 +903,18 @@ namespace NMR { if (pTextureResource == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); - PModelTexture2DResource pNewTextureResource = CModelTexture2DResource::make(generateResourceID(), this, pTextureResource->getAttachment()); - pNewTextureResource->copyFrom(pTextureResource); + PModelAttachment pSourceAttachment = pTextureResource->getAttachment(); + PModelAttachment pNewAttachment; + if (pSourceAttachment.get()) { + pNewAttachment = findModelAttachment(pSourceAttachment->getPathURI()); + if (pNewAttachment.get() == nullptr) + throw CNMRException(NMR_ERROR_ATTACHMENTNOTFOUND); + } + PModelTexture2DResource pNewTextureResource = CModelTexture2DResource::make(generateResourceID(), this, pNewAttachment); + pNewTextureResource->copyFrom(pTextureResource, false); addResource(pNewTextureResource); - oldToNewMapping[pTextureResource->getResourceID()->getUniqueID()] = pNewTextureResource->getResourceID()->getUniqueID(); + oldToNewMapping[pTextureResource->getPackageResourceID()->getUniqueID()] = pNewTextureResource->getPackageResourceID()->getUniqueID(); } } @@ -1142,9 +1210,15 @@ namespace NMR { return bRequireSliceExtension; } + if (sExtension == XML_3MF_NAMESPACE_SECURECONTENTSPEC) { + if (m_pKeyStore.get() != nullptr) { + return true; + } + } + if (sExtension == XML_3MF_NAMESPACE_PRODUCTIONSPEC) { // We do not write out models that require the production specification - // i.e. we do not make use of the "path"-redirection. + // i.e. we do not make use of the "getPath"-redirection. // Thus, never mark the production extension is required. return false; } @@ -1180,7 +1254,6 @@ namespace NMR { (*iIterator)->calculateComponentDepthLevel(1); } - // sort by (level descending, ResourceID ascending) resultList.sort( [](CModelObject * pObject1, CModelObject * pObject2) { @@ -1188,7 +1261,7 @@ namespace NMR { nfUint32 nLevel2 = pObject2->getComponentDepthLevel(); if (nLevel1 == nLevel2) - return (pObject1->getResourceID()->getUniqueID()) < (pObject2->getResourceID()->getUniqueID()); + return (pObject1->getPackageResourceID()->getUniqueID()) < (pObject2->getPackageResourceID()->getUniqueID()); return nLevel1 > nLevel2; }); @@ -1196,4 +1269,50 @@ namespace NMR { return resultList; } + PKeyStore CModel::getKeyStore() { + return m_pKeyStore; + } + + void CModel::setKeyStore(PKeyStore keyStore) { + m_pKeyStore = keyStore; + } + + void CModel::setCryptoRandCallback(CryptoRandGenDescriptor const & randDescriptor) { + m_sRandDescriptor = randDescriptor; + } + + nfBool CModel::hasCryptoRandCallbak() const { + return (bool)m_sRandDescriptor.m_fnRNG; + } + + nfUint64 CModel::generateRandomBytes(nfByte * bytes, nfUint64 size) { + if (m_sRandDescriptor.m_fnRNG) + return m_sRandDescriptor.m_fnRNG(bytes, size, m_sRandDescriptor.m_pUserData); + + static bool rngInitialized = false; + static std::random_device randDev; + static std::mt19937 mTwister; + static std::mutex mtLock; + + { + //scope the guard to the generator initialization + std::lock_guard guard(mtLock); + if (!rngInitialized) { + std::array seedData; + uint32_t curTime = static_cast(time(nullptr)); + for (auto it = seedData.begin(); it != seedData.end(); ++it) + *it = randDev() ^ curTime; + std::seed_seq seedSeq(seedData.begin(), seedData.end()); + mTwister.seed(seedSeq); + rngInitialized = true; + } + } + + std::uniform_int_distribution distByte(std::numeric_limits::min(), std::numeric_limits::max()); + for (nfUint64 n = 0; n < size; ++n) { + *(bytes + n) = distByte(mTwister); + } + return size; + } + } diff --git a/Source/Model/Classes/NMR_ModelBuildItem.cpp b/Source/Model/Classes/NMR_ModelBuildItem.cpp index 99f2af21b..81ec1efb7 100644 --- a/Source/Model/Classes/NMR_ModelBuildItem.cpp +++ b/Source/Model/Classes/NMR_ModelBuildItem.cpp @@ -81,11 +81,6 @@ namespace NMR { { m_mTransform = mTransform; } - - PackageResourceID CModelBuildItem::getObjectID() - { - return m_pObject->getResourceID()->getUniqueID(); - } nfBool CModelBuildItem::hasTransform() { diff --git a/Source/Model/Classes/NMR_ModelComponent.cpp b/Source/Model/Classes/NMR_ModelComponent.cpp index 26abdd226..4ae41f964 100644 --- a/Source/Model/Classes/NMR_ModelComponent.cpp +++ b/Source/Model/Classes/NMR_ModelComponent.cpp @@ -81,11 +81,6 @@ namespace NMR { m_mTransform = mTransform; } - PackageResourceID CModelComponent::getObjectID() - { - return m_pObject->getResourceID()->getUniqueID(); - } - nfBool CModelComponent::hasTransform() { return (!fnMATRIX3_isIdentity(m_mTransform)); diff --git a/Source/Model/Classes/NMR_ModelComponentsObject.cpp b/Source/Model/Classes/NMR_ModelComponentsObject.cpp index f0ee67932..d77b8a369 100644 --- a/Source/Model/Classes/NMR_ModelComponentsObject.cpp +++ b/Source/Model/Classes/NMR_ModelComponentsObject.cpp @@ -59,7 +59,7 @@ namespace NMR { if (pModel != pModelObject->getModel()) throw CNMRException(NMR_ERROR_MODELMISMATCH); - if (pComponent->getObjectID() == this->getResourceID()->getUniqueID() ) + if (pComponent->getObject()->getPackageResourceID() == this->getPackageResourceID() ) throw CNMRException(NMR_ERROR_MODELMISMATCH); m_Components.push_back(pComponent); diff --git a/Source/Model/Classes/NMR_ModelContext.cpp b/Source/Model/Classes/NMR_ModelContext.cpp new file mode 100644 index 000000000..15baa14ab --- /dev/null +++ b/Source/Model/Classes/NMR_ModelContext.cpp @@ -0,0 +1,66 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +--*/ + +#include "Model/Classes/NMR_ModelContext.h" + +#include "Model/Classes/NMR_Model.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Common/NMR_SecureContext.h" +#include "Common/3MF_ProgressMonitor.h" +#include "Common/NMR_ModelWarnings.h" + +namespace NMR { + + + + CModelContext::CModelContext(_In_ PModel pModel) { + if (!pModel) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + + m_pModel = pModel; + + m_pKeystore = pModel->getKeyStore(); + + m_pProgressMonitor = std::make_shared(); + + m_pSecureContext = std::make_shared(); + + m_pWarnings = std::make_shared(); + } + + nfBool CModelContext::isComplete() const { + return (nullptr != m_pModel && nullptr != m_pProgressMonitor && nullptr != m_pSecureContext); + } + + void CModelContext::SetProgressCallback(Lib3MFProgressCallback callback, void* userData) { + m_pProgressMonitor->SetProgressCallback(callback, userData); + } + + +} \ No newline at end of file diff --git a/Source/Model/Classes/NMR_ModelMeshBeamLatticeAttributes.cpp b/Source/Model/Classes/NMR_ModelMeshBeamLatticeAttributes.cpp index cfca0852d..de37fe3eb 100644 --- a/Source/Model/Classes/NMR_ModelMeshBeamLatticeAttributes.cpp +++ b/Source/Model/Classes/NMR_ModelMeshBeamLatticeAttributes.cpp @@ -39,9 +39,10 @@ namespace NMR { { m_eClipMode = eModelBeamLatticeClipMode::MODELBEAMLATTICECLIPMODE_NONE; m_bHasClippingMeshID = false; - m_nClippingMeshID = nullptr; + m_pClippingMeshUniqueID = nullptr; m_bHasRepresentationMeshID = false; - m_nRepresentationID = nullptr; + m_pRepresentationUniqueID = nullptr; + m_eBallMode = eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_NONE; } CModelMeshBeamLatticeAttributes::~CModelMeshBeamLatticeAttributes() diff --git a/Source/Model/Classes/NMR_ModelMetaData.cpp b/Source/Model/Classes/NMR_ModelMetaData.cpp index e62604483..53c744bea 100644 --- a/Source/Model/Classes/NMR_ModelMetaData.cpp +++ b/Source/Model/Classes/NMR_ModelMetaData.cpp @@ -35,6 +35,7 @@ metadata, and can be attached to any 3MF model node. #include "Model/Classes/NMR_ModelMetaData.h" #include "Model/Classes/NMR_ModelConstants.h" #include "Common/NMR_Exception.h" +#include "Common/NMR_StringUtils.h" namespace NMR { @@ -68,7 +69,7 @@ namespace NMR { std::string CModelMetaData::getKey() { - return calculateKey(m_sNameSpace, m_sName); + return composeNamespaceAndNameIntoKey(m_sNameSpace, m_sName); } std::string CModelMetaData::getValue() @@ -119,25 +120,6 @@ namespace NMR { m_bPreserve = bPreserve; } - void CModelMetaData::decomposeKeyIntoNamespaceAndName(const std::string &sKey, std::string &sNameSpace, std::string &sName) { - size_t cInd = sKey.find(":"); - if (cInd != std::string::npos) { - sNameSpace = sKey.substr(0, cInd); - sName = sKey.substr(cInd + 1, sKey.length() - cInd); - } else{ - sNameSpace = ""; - sName = sKey; - } - } - - std::string CModelMetaData::calculateKey(const std::string &sNameSpace, const std::string &sName) - { - if (sNameSpace.empty()) - return sName; - else - return sNameSpace + ":" + sName; - } - bool CModelMetaData::isValidNamespaceAndName(std::string sNameSpace, std::string sName) { if (sNameSpace.empty()) { diff --git a/Source/Model/Classes/NMR_ModelMetaDataGroup.cpp b/Source/Model/Classes/NMR_ModelMetaDataGroup.cpp index d9c43f6f3..a2608cab6 100644 --- a/Source/Model/Classes/NMR_ModelMetaDataGroup.cpp +++ b/Source/Model/Classes/NMR_ModelMetaDataGroup.cpp @@ -33,6 +33,7 @@ NMR_ModelMetaDataGroup.cpp implements the Model MetaData Group Class. #include "Model/Classes/NMR_ModelMetaDataGroup.h" #include "Common/NMR_Exception.h" #include "Model/Classes/NMR_ModelConstants.h" +#include "Common/NMR_StringUtils.h" namespace NMR { @@ -49,7 +50,7 @@ namespace NMR { PModelMetaData CModelMetaDataGroup::addMetaData(_In_ std::string sNameSpace, _In_ std::string sName, _In_ std::string sValue, _In_ std::string sType, _In_ nfBool bPreserve) { - if (hasMetaData(CModelMetaData::calculateKey(sNameSpace, sName))) { + if (hasMetaData(composeNamespaceAndNameIntoKey(sNameSpace, sName))) { throw CNMRException(NMR_ERROR_DUPLICATEMETADATA); } diff --git a/Source/Model/Classes/NMR_ModelMultiPropertyGroup.cpp b/Source/Model/Classes/NMR_ModelMultiPropertyGroup.cpp index 76827f5c5..6c6a31209 100644 --- a/Source/Model/Classes/NMR_ModelMultiPropertyGroup.cpp +++ b/Source/Model/Classes/NMR_ModelMultiPropertyGroup.cpp @@ -118,13 +118,13 @@ namespace NMR { bool hasColorGroup = false; for (MODELMULTIPROPERTYLAYER layer : m_vctLayers) { - PModelResource pResource = Model()->findResource(layer.m_nResourceID); + PModelResource pResource = Model()->findResource(layer.m_nUniqueResourceID); hasMaterial |= (dynamic_cast(pResource.get())!=nullptr) || (dynamic_cast(pResource.get()) != nullptr); hasColorGroup |= (dynamic_cast(pResource.get()) != nullptr); } - PModelResource pResource = Model()->findResource(sLayer.m_nResourceID); + PModelResource pResource = Model()->findResource(sLayer.m_nUniqueResourceID); if ((dynamic_cast(pResource.get()) != nullptr)) { throw CNMRException(NMR_ERROR_MULTIPROPERTIES_MUST_NOT_CONTAIN_MULTIPROPERTIES); diff --git a/Source/Model/Classes/NMR_ModelResource.cpp b/Source/Model/Classes/NMR_ModelResource.cpp index 882cdcb80..c9a31d929 100644 --- a/Source/Model/Classes/NMR_ModelResource.cpp +++ b/Source/Model/Classes/NMR_ModelResource.cpp @@ -43,7 +43,7 @@ namespace NMR { if (!pModel) throw CNMRException(NMR_ERROR_INVALIDPARAM); m_pModel = pModel; - m_sResourceID = m_pModel->generatePackageResourceID(pModel->curPath(), sResourceID); + m_pPackageResourceID = m_pModel->generatePackageResourceID(pModel->currentPath(), sResourceID); m_bHasResourceIndexMap = false; } @@ -57,9 +57,15 @@ namespace NMR { return m_pModel; } - PPackageResourceID CModelResource::getResourceID() + PPackageResourceID CModelResource::getPackageResourceID() { - return m_sResourceID; + return m_pPackageResourceID; + } + + void CModelResource::setPackageResourceID(PPackageResourceID pID) + { + m_pModel->updateUniqueResourceID(m_pPackageResourceID->getUniqueID(), pID->getUniqueID()); + m_pPackageResourceID = pID; } _Ret_notnull_ CModel * CModelResource::getModel() diff --git a/Source/Model/Classes/NMR_ModelSliceStack.cpp b/Source/Model/Classes/NMR_ModelSliceStack.cpp index 2207cf83b..43f162a2d 100644 --- a/Source/Model/Classes/NMR_ModelSliceStack.cpp +++ b/Source/Model/Classes/NMR_ModelSliceStack.cpp @@ -42,7 +42,6 @@ namespace NMR { : CModelResource(sID, pModel) { m_dZBottom = dZBottom; - m_sOwnPath = ""; } CModelSliceStack::~CModelSliceStack() @@ -141,21 +140,24 @@ namespace NMR { std::string CModelSliceStack::OwnPath() { - return m_sOwnPath; + std::string sPath = getPackageResourceID()->getPath(); + if (sPath.empty()) { + throw CNMRException(NMR_ERROR_INVALID_SLICEPATH); + } + return sPath; } void CModelSliceStack::SetOwnPath(std::string sOwnPath) { - if (sOwnPath == getModel()->rootPath()) - m_sOwnPath = ""; - else - m_sOwnPath = sOwnPath; + PPackageModelPath pModelPath = getModel()->findOrCreateModelPath(sOwnPath); + CPackageResourceID::setModelPath(getPackageResourceID(), pModelPath); } nfDouble CModelSliceStack::getZBottom() { return m_dZBottom; } + void CModelSliceStack::setZBottom(nfDouble dZBottom) { if (!m_pSlices.empty()) { @@ -169,7 +171,6 @@ namespace NMR { m_dZBottom = dZBottom; } - nfDouble CModelSliceStack::getHighestZ() const { nfDouble dHighestZ = m_dZBottom; @@ -197,47 +198,5 @@ namespace NMR { return true; } - - //nfUint32 CSliceStackGeometry::addSlice(PSlice pSlice) - //{ - // if (pSlice->getTopZ() < m_BottomZ) - // throw CNMRException(NMR_ERROR_SLICES_Z_NOTINCREASING); - // if (!m_Slices.empty()) { - // if (pSlice->getTopZ() < m_Slices.rbegin()->get()->getTopZ() ) { - // throw CNMRException(NMR_ERROR_SLICES_Z_NOTINCREASING); - // } - // } - // m_Slices.push_back(pSlice); - // return (nfUint32)m_Slices.size() - 1; - //} - - //nfUint32 CSliceStackGeometry::getSliceCount() - //{ - // return (nfUint32)m_Slices.size(); - //} - - //nfFloat CSliceStackGeometry::getBottomZ() - //{ - // return m_BottomZ; - //} - - //void CSliceStackGeometry::setBottomZ(nfFloat nBottomZ) - //{ - // m_BottomZ = nBottomZ; - //} - - //void CSliceStackGeometry::setUsesSliceRef(nfBool bUsesSliceRef) - //{ - // m_bUsesSliceRef = bUsesSliceRef; - //} - - //nfBool CSliceStackGeometry::usesSliceRef() - //{ - // return m_bUsesSliceRef; - //} - - - - } diff --git a/Source/Model/Classes/NMR_ModelTexture2D.cpp b/Source/Model/Classes/NMR_ModelTexture2D.cpp index a5d59602c..319ea2716 100644 --- a/Source/Model/Classes/NMR_ModelTexture2D.cpp +++ b/Source/Model/Classes/NMR_ModelTexture2D.cpp @@ -62,6 +62,8 @@ namespace NMR { throw CNMRException(NMR_ERROR_INVALIDTEXTURE); if (pAttachment->getRelationShipType() != PACKAGE_TEXTURE_RELATIONSHIP_TYPE) throw CNMRException(NMR_ERROR_INVALIDRELATIONSHIPTYPEFORTEXTURE); + if (pAttachment->getModel() != pModel) + throw CNMRException(NMR_ERROR_ATTACHMENTMODELMISMATCH); return std::make_shared(CModelTexture2DResource(sID, pModel, pAttachment)); } @@ -75,8 +77,15 @@ namespace NMR { void CModelTexture2DResource::setAttachment(PModelAttachment pAttachment) { + if (pAttachment.get() == nullptr) + throw CNMRException(NMR_ERROR_INVALIDPARAM); + + if (pAttachment->getModel() != getModel()) + throw CNMRException(NMR_ERROR_ATTACHMENTMODELMISMATCH); + if (pAttachment->getRelationShipType() != PACKAGE_TEXTURE_RELATIONSHIP_TYPE) throw CNMRException(NMR_ERROR_INVALIDRELATIONSHIPTYPEFORTEXTURE); + m_pAttachment = pAttachment; } @@ -211,12 +220,14 @@ namespace NMR { m_eFilter = eFilter; } - void CModelTexture2DResource::copyFrom(_In_ CModelTexture2DResource * pSourceTexture) + void CModelTexture2DResource::copyFrom(_In_ CModelTexture2DResource * pSourceTexture, _In_ nfBool bCopyAttachment) { if (pSourceTexture == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); - setAttachment(pSourceTexture->getAttachment()); + if (bCopyAttachment) + setAttachment(pSourceTexture->getAttachment()); + setContentType(pSourceTexture->getContentType ()); setTileStyleU(pSourceTexture->getTileStyleU()); setTileStyleV(pSourceTexture->getTileStyleV()); diff --git a/Source/Model/Classes/NMR_PackageResourceID.cpp b/Source/Model/Classes/NMR_PackageResourceID.cpp index a1a59d823..1d5dc9ad8 100644 --- a/Source/Model/Classes/NMR_PackageResourceID.cpp +++ b/Source/Model/Classes/NMR_PackageResourceID.cpp @@ -26,46 +26,135 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Abstract: -NMR_PackageResourceID.cpp implements the PackageResourceID Class. +NMR_PackageResourceID.cpp implements the UniqueResourceID Class. --*/ -#include "Model/Classes/NMR_PackageResourceID.h" +#include "Model/Classes/NMR_PackageResourceID.h" #include "Common/NMR_StringUtils.h" #include "Common/NMR_Exception.h" +#include + namespace NMR { - void CPackageResourceID::setPathAndId(std::string p, ModelResourceID id) { - m_path = p; - m_id = id; + CPackageModelPath::CPackageModelPath(CResourceHandler* pResourceHandler, std::string sPath) + : m_pResourceHandler(pResourceHandler), m_sPath(sPath) + { + if (pResourceHandler == nullptr) { + throw CNMRException(NMR_ERROR_INVALIDPOINTER); + } + } + + std::string CPackageModelPath::getPath() + { + return m_sPath; + } + + void CPackageModelPath::setPath(std::string sPath) + { + if (m_sPath != sPath) { + PPackageModelPath pPath = m_pResourceHandler->findPackageModelPath(sPath); + if (pPath) { + throw CNMRException(NMR_ERROR_DUPLICATEPACKAGEPATH); + } + m_sPath = sPath; + } + } + + CPackageResourceID::CPackageResourceID(CResourceHandler* pResourceHandler, PPackageModelPath pModelPath, ModelResourceID nID) + : m_pResourceHandler(pResourceHandler), m_pModelPath(pModelPath), m_id(nID) + { + if (pResourceHandler == nullptr || pModelPath == nullptr) { + throw CNMRException(NMR_ERROR_INVALIDPOINTER); + } + } + + PPackageModelPath CPackageResourceID::getPackageModelPath() { + return m_pModelPath; } - void CPackageResourceID::get(std::string& p) { - p = m_path; + std::string CPackageResourceID::getPath() { + return m_pModelPath->getPath(); } - void CPackageResourceID::get(ModelResourceID& id) { - id = m_id; + + ModelResourceID CPackageResourceID::getModelResourceID() { + return m_id; + } + + void CPackageResourceID::setModelPath(std::shared_ptr pPackageResourceID, PPackageModelPath pPath) + { + pPackageResourceID->m_pResourceHandler->updateModelPath(pPackageResourceID, pPath); } - void CPackageResourceID::setUniqueID(PackageResourceID id) { + CResourceHandler * CPackageResourceID::getResourceHandler() { + return m_pResourceHandler; + } + + void CPackageResourceID::setUniqueID(UniqueResourceID id) { m_uniqueID = id; } - PackageResourceID CPackageResourceID::getUniqueID() { + UniqueResourceID CPackageResourceID::getUniqueID() { return m_uniqueID; } - PPackageResourceID CResourceHandler::getNewResourceID(std::string path, ModelResourceID id) // this is supposed to be the only way to generate a CPackageResourceID + PPackageModelPath CResourceHandler::makePackageModelPath(std::string sPath) + { + if (findPackageModelPath(sPath)) { + throw CNMRException(NMR_ERROR_DUPLICATEPACKAGEPATH); + } + PPackageModelPath pModelPath = std::make_shared(this, sPath); + m_PathToModelPath.insert(std::make_pair(sPath, pModelPath)); + return pModelPath; + } + + std::vector CResourceHandler::retrieveAllModelPaths() + { + std::vector vctPModelPaths; + vctPModelPaths.reserve(m_PathToModelPath.size()); + for (auto pModelPathPair : m_PathToModelPath) { + vctPModelPaths.push_back(pModelPathPair.second); + } + return vctPModelPaths; + } + + PPackageModelPath CResourceHandler::findPackageModelPath(std::string sPath) + { + auto it = m_PathToModelPath.find(sPath); + if (it != m_PathToModelPath.end()) + { + return it->second; + } + return nullptr; + } + + // this is supposed to be the only way to generate a CPackageResourceID + PPackageResourceID CResourceHandler::makePackageResourceID(std::string path, ModelResourceID id) { - PPackageResourceID p = std::make_shared(); - if (findResourceID(path, id)) + PPackageModelPath pModelPath = findPackageModelPath(path); + if (!pModelPath) { + pModelPath = makePackageModelPath(path); + } + // This can be optimized + if (findResourceIDByPair(pModelPath->getPath(), id)) throw CNMRException(NMR_ERROR_DUPLICATERESOURCEID); - p->setPathAndId(path, id); - p->setUniqueID(int(m_resourceIDs.size())+1); - m_resourceIDs.insert(std::make_pair(p->getUniqueID(), p)); - m_IdAndPathToResourceIDs.insert(std::make_pair(std::make_pair(id, path), p)); - return p; + + PPackageResourceID pPackageResourceID = std::make_shared(this, pModelPath, id); + UniqueIDPackageIdMap::const_iterator biggestId = std::max_element(m_resourceIDs.begin(), m_resourceIDs.end(), [](const UniqueIdPackageIdPair & v1, const UniqueIdPackageIdPair v2) { + return v1.first < v2.first; + }); + if (biggestId != m_resourceIDs.end()) { + pPackageResourceID->setUniqueID(int(biggestId->first) + 1); + } else { + pPackageResourceID->setUniqueID(1); + } + + + m_resourceIDs.insert(std::make_pair(pPackageResourceID->getUniqueID(), pPackageResourceID)); + m_IdAndPathToPackageResourceIDs.insert(std::make_pair(std::make_pair(id, pModelPath), pPackageResourceID)); + return pPackageResourceID; } - PPackageResourceID CResourceHandler::findResourceID(PackageResourceID id) + + PPackageResourceID CResourceHandler::findResourceIDByUniqueID(UniqueResourceID id) { auto it = m_resourceIDs.find(id); if (it != m_resourceIDs.end()) @@ -75,23 +164,70 @@ namespace NMR { return nullptr; } - PPackageResourceID CResourceHandler::findResourceID(std::string path, ModelResourceID id) + PPackageResourceID CResourceHandler::findResourceIDByPair(std::string path, ModelResourceID id) { - auto it = m_IdAndPathToResourceIDs.find(std::make_pair(id, path)); - if (it != m_IdAndPathToResourceIDs.end()) - { - return it->second; + PPackageModelPath pModelPath = findPackageModelPath(path); + if (pModelPath) { + auto it = m_IdAndPathToPackageResourceIDs.find(std::make_pair(id, pModelPath)); + if (it != m_IdAndPathToPackageResourceIDs.end()) + { + return it->second; + } } return nullptr; } - void CResourceHandler::FlattenIDs() { + void CResourceHandler::updateModelPath(PPackageResourceID pPackageResourceID, PPackageModelPath pNewPath) + { + if (pPackageResourceID == nullptr || pNewPath == nullptr) { + throw CNMRException(NMR_ERROR_INVALIDPOINTER); + } + + PPackageModelPath pOldPath = pPackageResourceID->m_pModelPath; + + if (pNewPath == pOldPath) { + return; + } + + auto itOld = m_IdAndPathToPackageResourceIDs.find(std::make_pair(pPackageResourceID->m_id, pOldPath)); + if (itOld == m_IdAndPathToPackageResourceIDs.end()) + { + throw CNMRException(NMR_ERROR_INVALIDPARAM); + } + + auto itNew = m_IdAndPathToPackageResourceIDs.find(std::make_pair(pPackageResourceID->m_id, pNewPath)); + if (itNew != m_IdAndPathToPackageResourceIDs.end()) + { + throw CNMRException(NMR_ERROR_INVALIDPARAM); + } + + m_IdAndPathToPackageResourceIDs.erase(itOld); + //what if idOld was the last one standing pointint to PackageModelPath? + + pPackageResourceID->m_pModelPath = pNewPath; + m_IdAndPathToPackageResourceIDs.insert(std::make_pair(std::make_pair(pPackageResourceID->m_id, pNewPath), pPackageResourceID)); + } + + void CResourceHandler::removePackageResourceID(PPackageResourceID pPackageResourceID) + { + auto it = m_IdAndPathToPackageResourceIDs.find(std::make_pair(pPackageResourceID->m_id, pPackageResourceID->getPackageModelPath())); + if (it == m_IdAndPathToPackageResourceIDs.end()) + { + throw CNMRException(NMR_ERROR_INVALIDPARAM); + } + auto itID = m_resourceIDs.find(pPackageResourceID->m_uniqueID); + if (itID == m_resourceIDs.end()) + { + throw CNMRException(NMR_ERROR_INVALIDPARAM); + } + m_IdAndPathToPackageResourceIDs.erase(it); + m_resourceIDs.erase(itID); } void CResourceHandler::clear() { m_resourceIDs.clear(); - m_IdAndPathToResourceIDs.clear(); + m_IdAndPathToPackageResourceIDs.clear(); } } diff --git a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ball.cpp b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ball.cpp new file mode 100644 index 000000000..0d8d4b578 --- /dev/null +++ b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ball.cpp @@ -0,0 +1,126 @@ +/*++ + +Copyright (C) 2020 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_BeamLattice1702_Ball.cpp covers the official 3MF beamlattice extension. + +--*/ + +#include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ball.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_ModelMeshObject.h" + +#include "Common/NMR_StringUtils.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" + +namespace NMR { + + eModelBeamLatticeBallMode stringToBallMode(const nfChar* ballModeStr) + { + if (strcmp(ballModeStr, XML_3MF_BEAMLATTICE_BALLMODE_MIXED) == 0) + return eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_MIXED; + if (strcmp(ballModeStr, XML_3MF_BEAMLATTICE_BALLMODE_ALL) == 0) + return eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_ALL; + return eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_NONE; + } + + CModelReaderNode_BeamLattice1702_Ball::CModelReaderNode_BeamLattice1702_Ball(_In_ CModel* pModel, _In_ PModelWarnings pWarnings) + : CModelReaderNode(pWarnings) + { + m_nIndex = -1; + + m_bHasRadius = false; + m_dRadius = 0; + + m_bHasRadius = false; + + m_bHasTag = false; + m_nTag = -1; + } + + void CModelReaderNode_BeamLattice1702_Ball::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + } + + void CModelReaderNode_BeamLattice1702_Ball::retrieveIndex(_Out_ nfInt32 & nIndex, nfInt32 nNodeCount) + { + if ((m_nIndex < 0) || m_nIndex >= nNodeCount) + throw CNMRException(NMR_ERROR_INVALIDMODELNODEINDEX); + + nIndex = m_nIndex; + } + + void CModelReaderNode_BeamLattice1702_Ball::retrieveRadius(_Out_ nfBool & bHasRadius, _Out_ nfDouble & dRadius) + { + bHasRadius = m_bHasRadius; + if (bHasRadius) + dRadius = m_dRadius; + } + + void CModelReaderNode_BeamLattice1702_Ball::retrieveTag(_Out_ nfBool & bHasTag, _Out_ nfInt32 & nTag) + { + bHasTag = m_bHasTag; + if (bHasTag) + nTag = m_nTag; + } + + void CModelReaderNode_BeamLattice1702_Ball::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + { + __NMRASSERT(pAttributeName); + __NMRASSERT(pAttributeValue); + + if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_BEAMLATTICE_BALL_VINDEX) == 0) { + nfInt32 nValue = fnStringToInt32(pAttributeValue); + if ((nValue >= 0) && (nValue < XML_3MF_MAXRESOURCEINDEX)) + m_nIndex = nValue; + } + else if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_BEAMLATTICE_BALL_R) == 0) { + nfFloat fValue = fnStringToFloat(pAttributeValue); + if ((fValue >= 0) && (fValue < XML_3MF_MAXIMUMBALLRADIUSVALUE)) { + m_dRadius = fValue; + m_bHasRadius = true; + } + } + else + m_pWarnings->addException(CNMRException(NMR_ERROR_BEAMLATTICEINVALIDATTRIBUTE), mrwInvalidOptionalValue); + } + + void CModelReaderNode_BeamLattice1702_Ball::OnNSAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue, _In_z_ const nfChar * pNameSpace) + { + + } +} \ No newline at end of file diff --git a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BallRef.cpp b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BallRef.cpp new file mode 100644 index 000000000..88d831896 --- /dev/null +++ b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BallRef.cpp @@ -0,0 +1,82 @@ +/*++ + +Copyright (C) 2020 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_BeamLattice1702_BallRef.cpp covers the official 3MF beamlattice extension. + +--*/ + +#include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BallRef.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_ModelMeshObject.h" + +#include "Common/NMR_StringUtils.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" + +namespace NMR { + + CModelReaderNode_BeamLattice1702_BallRef::CModelReaderNode_BeamLattice1702_BallRef(_In_ PModelWarnings pWarnings) + : CModelReaderNode(pWarnings), m_nIndex(0) + { + } + + void CModelReaderNode_BeamLattice1702_BallRef::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + + } + + void CModelReaderNode_BeamLattice1702_BallRef::retrieveIndex(_Out_ nfInt32 & nIndex) + { + nIndex = m_nIndex; + } + + void CModelReaderNode_BeamLattice1702_BallRef::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + { + __NMRASSERT(pAttributeName); + __NMRASSERT(pAttributeValue); + + if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_BEAMLATTICE_INDEX) == 0) { + nfInt32 nValue = fnStringToInt32(pAttributeValue); + if ((nValue >= 0) && (nValue < XML_3MF_MAXBALLCOUNT)) + m_nIndex = nValue; + } + else + m_pWarnings->addException(CNMRException(NMR_ERROR_BEAMLATTICEINVALIDATTRIBUTE), mrwInvalidOptionalValue); + + } + +} diff --git a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Balls.cpp b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Balls.cpp new file mode 100644 index 000000000..9aeb5b447 --- /dev/null +++ b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Balls.cpp @@ -0,0 +1,108 @@ +/*++ + +Copyright (C) 2020 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_BeamLattice1702_Balls.cpp covers the official 3MF beamlattice extension. + +--*/ + +#include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Balls.h" +#include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ball.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_StringUtils.h" + +namespace NMR { + + CModelReaderNode_BeamLattice1702_Balls::CModelReaderNode_BeamLattice1702_Balls(_In_ CModel * pModel, _In_ CMesh * pMesh, + _In_ nfDouble defaultBallRadius, _In_ PModelWarnings pWarnings) + : CModelReaderNode(pWarnings) + { + __NMRASSERT(pMesh); + __NMRASSERT(pModel); + + m_pModel = pModel; + m_pMesh = pMesh; + m_dDefaultBallRadius = defaultBallRadius; + } + + void CModelReaderNode_BeamLattice1702_Balls::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse Name + parseName(pXMLReader); + + // Parse Attributes + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + } + + void CModelReaderNode_BeamLattice1702_Balls::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + { + __NMRASSERT(pAttributeName); + __NMRASSERT(pAttributeValue); + } + + void CModelReaderNode_BeamLattice1702_Balls::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) + { + __NMRASSERT(pChildName); + __NMRASSERT(pXMLReader); + __NMRASSERT(pNameSpace); + + if (strcmp(pNameSpace, XML_3MF_NAMESPACE_BEAMLATTICESPEC) == 0) { + if (strcmp(pChildName, XML_3MF_ELEMENT_BALL) == 0) { + // Parse XML + PModelReaderNode_BeamLattice1702_Ball pXMLNode = std::make_shared(m_pModel, m_pWarnings); + pXMLNode->parseXML(pXMLReader); + + // Retrieve node index + nfInt32 nIndex; + pXMLNode->retrieveIndex(nIndex, m_pMesh->getNodeCount()); + + nfInt32 nTag; + nfBool bHasTag, bHasRadius; + nfDouble dRadius; + pXMLNode->retrieveTag(bHasTag, nTag); + pXMLNode->retrieveRadius(bHasRadius, dRadius); + + if (!bHasRadius) { + dRadius = m_dDefaultBallRadius; + } + + // Create ball + MESHNODE * pNode = m_pMesh->getNode(nIndex); + m_pMesh->addBall(pNode, dRadius); + } + else { + m_pWarnings->addException(CNMRException(NMR_ERROR_NAMESPACE_INVALID_ELEMENT), mrwInvalidOptionalValue); + } + } + } +} \ No newline at end of file diff --git a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beam.cpp b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beam.cpp index e1d033b22..d449d7f16 100644 --- a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beam.cpp +++ b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beam.cpp @@ -53,7 +53,7 @@ namespace NMR { return eModelBeamLatticeCapMode::MODELBEAMLATTICECAPMODE_SPHERE; } - CModelReaderNode_BeamLattice1702_Beam::CModelReaderNode_BeamLattice1702_Beam(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode_BeamLattice1702_Beam::CModelReaderNode_BeamLattice1702_Beam(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_nIndex1 = -1; diff --git a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamLattice.cpp b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamLattice.cpp index bb30ee59e..37c2ce3c0 100644 --- a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamLattice.cpp +++ b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamLattice.cpp @@ -35,6 +35,8 @@ NMR_ModelReaderNode_BeamLattice1702_BeamLattice.cpp covers the official 3MF beam #include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beams.h" #include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beam.h" #include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSets.h" +#include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Balls.h" +#include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ball.h" #include "Model/Classes/NMR_ModelConstants.h" #include "Model/Classes/NMR_ModelMeshObject.h" @@ -46,7 +48,7 @@ NMR_ModelReaderNode_BeamLattice1702_BeamLattice.cpp covers the official 3MF beam namespace NMR { - CModelReaderNode_BeamLattice1702_BeamLattice::CModelReaderNode_BeamLattice1702_BeamLattice(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode_BeamLattice1702_BeamLattice::CModelReaderNode_BeamLattice1702_BeamLattice(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_pModel = pModel; @@ -59,6 +61,7 @@ namespace NMR { m_eClipMode = eModelBeamLatticeClipMode::MODELBEAMLATTICECLIPMODE_NONE; m_dDefaultRadius = 0.0001; m_eDefaultCapMode = eModelBeamLatticeCapMode::MODELBEAMLATTICECAPMODE_SPHERE; + m_dDefaultBallRadius = 0.0; } void CModelReaderNode_BeamLattice1702_BeamLattice::parseXML(_In_ CXmlReader * pXMLReader) @@ -86,6 +89,15 @@ namespace NMR { bHasRepresentation = m_bHasRepresentationMeshID; nRepresentationMeshID = m_nRepresentationMeshID; } + + void CModelReaderNode_BeamLattice1702_BeamLattice::validateBallOptions(_In_ PModelWarnings pWarnings) + { + if (m_pMesh->getBeamLatticeBallMode() != eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_NONE) { + if (m_pMesh->getDefaultBallRadius() <= 0 && m_pMesh->getDefaultBallRadius() >= XML_3MF_MAXIMUMCOORDINATEVALUE) { + pWarnings->addException(CNMRException(NMR_ERROR_BEAMLATTICEINVALIDATTRIBUTE), mrwInvalidOptionalValue); + } + } + } void CModelReaderNode_BeamLattice1702_BeamLattice::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) { @@ -133,6 +145,16 @@ namespace NMR { else if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_BEAMLATTICE_CAPMODE) == 0) { m_eDefaultCapMode = stringToCapMode(pAttributeValue); } + else if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_BEAMLATTICE_BALLMODE) == 0) { + m_pMesh->setBeamLatticeBallMode(stringToBallMode(pAttributeValue)); + } + else if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_BEAMLATTICE_BALLRADIUS) == 0) { + nfDouble dValue = fnStringToDouble(pAttributeValue); + if (std::isnan(dValue) || (dValue <= 0) || (dValue > XML_3MF_MAXIMUMCOORDINATEVALUE)) + throw CNMRException(NMR_ERROR_BEAMLATTICEINVALIDATTRIBUTE); + m_dDefaultBallRadius = dValue; + m_pMesh->setDefaultBallRadius(dValue); + } else m_pWarnings->addException(CNMRException(NMR_ERROR_BEAMLATTICEINVALIDATTRIBUTE), mrwInvalidOptionalValue); } @@ -160,6 +182,11 @@ namespace NMR { PModelReaderNode pXMLNode = std::make_shared(m_pMesh, m_pWarnings); pXMLNode->parseXML(pXMLReader); } + else if (strcmp(pChildName, XML_3MF_ELEMENT_BALLS) == 0) + { + PModelReaderNode pXMLNode = std::make_shared(m_pModel, m_pMesh, m_dDefaultBallRadius, m_pWarnings); + pXMLNode->parseXML(pXMLReader); + } else m_pWarnings->addException(CNMRException(NMR_ERROR_NAMESPACE_INVALID_ELEMENT), mrwInvalidOptionalValue); } diff --git a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSet.cpp b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSet.cpp index be26807f1..7b018a7ee 100644 --- a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSet.cpp +++ b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSet.cpp @@ -33,6 +33,8 @@ NMR_ModelReaderNode_BeamLattice1702_BeamSet.cpp covers the official 3MF beamlatt #include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSet.h" #include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ref.h" +#include "Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BallRef.h" + #include "Model/Classes/NMR_ModelConstants.h" #include "Model/Classes/NMR_ModelMeshObject.h" @@ -43,10 +45,11 @@ NMR_ModelReaderNode_BeamLattice1702_BeamSet.cpp covers the official 3MF beamlatt namespace NMR { - CModelReaderNode_BeamLattice1702_BeamSet::CModelReaderNode_BeamLattice1702_BeamSet(_In_ BEAMSET * pBeamSet, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode_BeamLattice1702_BeamSet::CModelReaderNode_BeamLattice1702_BeamSet(_In_ BEAMSET * pBeamSet, _In_ std::unordered_set * pUniqueIdentifiers, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_pBeamSet = pBeamSet; + m_pUniqueIdentifiers = pUniqueIdentifiers; } void CModelReaderNode_BeamLattice1702_BeamSet::parseXML(_In_ CXmlReader * pXMLReader) @@ -71,7 +74,13 @@ namespace NMR { m_pBeamSet->m_sName = pAttributeValue; } else if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_BEAMLATTICE_IDENTIFIER) == 0) { - m_pBeamSet->m_sIdentifier = pAttributeValue; + std::string attributeString(pAttributeValue); + if (m_pUniqueIdentifiers->find(attributeString) == m_pUniqueIdentifiers->end()) { + m_pUniqueIdentifiers->insert(attributeString); + m_pBeamSet->m_sIdentifier = pAttributeValue; + } + else + m_pWarnings->addException(CNMRException(NMR_ERROR_BEAMSET_IDENTIFIER_NOT_UNIQUE), mrwInvalidOptionalValue); } else m_pWarnings->addException(CNMRException(NMR_ERROR_BEAMLATTICEINVALIDATTRIBUTE), mrwInvalidOptionalValue); @@ -99,6 +108,13 @@ namespace NMR { pXMLNode->retrieveIndex(nIndex); m_pBeamSet->m_Refs.push_back(nIndex); } + else if (strcmp(pChildName, XML_3MF_ELEMENT_BALLREF) == 0) { + PModelReaderNode_BeamLattice1702_BallRef pXMLNode = std::make_shared(m_pWarnings); + pXMLNode->parseXML(pXMLReader); + nfInt32 nIndex; + pXMLNode->retrieveIndex(nIndex); + m_pBeamSet->m_BallRefs.push_back(nIndex); + } else m_pWarnings->addException(CNMRException(NMR_ERROR_NAMESPACE_INVALID_ELEMENT), mrwInvalidOptionalValue); diff --git a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSets.cpp b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSets.cpp index 3fe43ddb1..97a691cbc 100644 --- a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSets.cpp +++ b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_BeamSets.cpp @@ -43,7 +43,7 @@ NMR_ModelReaderNode_BeamLattice1702_BeamSets.cpp covers the official 3MF beamlat namespace NMR { - CModelReaderNode_BeamLattice1702_BeamSets::CModelReaderNode_BeamLattice1702_BeamSets(_In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode_BeamLattice1702_BeamSets::CModelReaderNode_BeamLattice1702_BeamSets(_In_ CMesh * pMesh, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_pMesh = pMesh; @@ -78,7 +78,7 @@ namespace NMR { if (strcmp(pChildName, XML_3MF_ELEMENT_BEAMSET) == 0) { PBEAMSET pBeamSet = m_pMesh->addBeamSet(); - PModelReaderNode pXMLNode = std::make_shared(pBeamSet.get(), m_pWarnings); + PModelReaderNode pXMLNode = std::make_shared(pBeamSet.get(), &m_uniqueIdentifiers, m_pWarnings); pXMLNode->parseXML(pXMLReader); } else diff --git a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beams.cpp b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beams.cpp index 59f66b0d4..6dcef04d1 100644 --- a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beams.cpp +++ b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Beams.cpp @@ -43,7 +43,7 @@ namespace NMR { CModelReaderNode_BeamLattice1702_Beams::CModelReaderNode_BeamLattice1702_Beams(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ nfDouble defaultRadius, _In_ eModelBeamLatticeCapMode defaultCapMode, - _In_ PModelReaderWarnings pWarnings) + _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pMesh); diff --git a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ref.cpp b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ref.cpp index eca723343..d5255cc6d 100644 --- a/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ref.cpp +++ b/Source/Model/Reader/BeamLattice1702/NMR_ModelReaderNode_BeamLattice1702_Ref.cpp @@ -41,7 +41,7 @@ NMR_ModelReaderNode_BeamLattice1702_Ref.cpp covers the official 3MF beamlattice namespace NMR { - CModelReaderNode_BeamLattice1702_Ref::CModelReaderNode_BeamLattice1702_Ref(_In_ PModelReaderWarnings pWarnings) + CModelReaderNode_BeamLattice1702_Ref::CModelReaderNode_BeamLattice1702_Ref(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings), m_nIndex(0) { } diff --git a/Source/Model/Reader/NMR_KeyStoreOpcPackageReader.cpp b/Source/Model/Reader/NMR_KeyStoreOpcPackageReader.cpp new file mode 100644 index 000000000..50a32960c --- /dev/null +++ b/Source/Model/Reader/NMR_KeyStoreOpcPackageReader.cpp @@ -0,0 +1,203 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_KeyStoreOpcPackageReader.cpp defines an OPC Package reader in a portable way. + +--*/ + +#include "Model/Reader/NMR_KeyStoreOpcPackageReader.h" + +#include "Common/NMR_Types.h" +#include "Common/NMR_Local.h" +#include "Common/NMR_SecureContentTypes.h" +#include "Common/NMR_SecureContext.h" +#include "Common/Platform/NMR_Platform.h" +#include "Common/Platform/NMR_ImportStream.h" +#include "Common/Platform/NMR_ImportStream_Compressed.h" +#include "Common/Platform/NMR_ImportStream_Encrypted.h" +#include "Common/OPC/NMR_OpcPackageReader.h" +#include "Common/OPC/NMR_OpcPackagePart.h" +#include "Model/Classes/NMR_ModelContext.h" +#include "Model/Classes/NMR_KeyStoreFactory.h" +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreResourceDataGroup.h" +#include "Model/Reader/NMR_ModelReader_InstructionElement.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStore.h" +#include + +namespace NMR { + CKeyStoreOpcPackageReader::CKeyStoreOpcPackageReader(PImportStream pImportStream, CModelContext const & context) + :m_pContext(context) + { + if (!context.isComplete()) + throw CNMRException(NMR_ERROR_INVALIDPOINTER); + m_pPackageReader = std::make_shared(pImportStream, context.warnings(), context.monitor()); + + PImportStream keyStoreStream = findKeyStoreStream(); + if (nullptr != keyStoreStream) { + parseKeyStore(keyStoreStream); + + if (!context.keyStore()->empty()) { + openAllResourceDataGroups(); + } + } + } + + COpcPackageRelationship * CKeyStoreOpcPackageReader::findRootRelation(std::string sRelationType, nfBool bMustBeUnique) { + return m_pPackageReader->findRootRelation(sRelationType, bMustBeUnique); + } + + POpcPackagePart CKeyStoreOpcPackageReader::createPart(std::string sPath) { + auto pPart = m_pPackageReader->createPart(sPath); + auto keyStore = m_pContext.keyStore(); + auto secureContext = m_pContext.secureContext(); + if (secureContext->hasDekCtx()) { + NMR::PKeyStoreResourceDataGroup rdg = keyStore->findResourceDataGroupByResourceDataPath(sPath); + if (nullptr != rdg) { + auto pIt = m_encryptedParts.find(pPart->getURI()); + if (pIt != m_encryptedParts.end()) { + return pIt->second; + } + NMR::PKeyStoreResourceData rd = keyStore->findResourceData(sPath); + PKeyStoreContentEncryptionParams params = CKeyStoreFactory::makeContentEncryptionParams(rd, rdg); + + ContentEncryptionDescriptor p = secureContext->getDekCtx(); + p.m_sDekDecryptData.m_sParams = params; + + PImportStream stream; + PImportStream decryptStream = std::make_shared(pPart->getImportStream(), p); + if (params->isCompressed()) { + PImportStream decompressStream = std::make_shared(decryptStream); + stream = decompressStream; + } + else { + stream = decryptStream; + } + auto encryptedPart = std::make_shared(*pPart, stream); + m_encryptedParts[pPart->getURI()] = encryptedPart; + return encryptedPart; + } + } + return pPart; + } + + nfUint64 CKeyStoreOpcPackageReader::getPartSize(std::string sPath) { + return m_pPackageReader->getPartSize(sPath); + } + + void CKeyStoreOpcPackageReader::close() { + checkAuthenticatedTags(); + } + + NMR::PImportStream CKeyStoreOpcPackageReader::findKeyStoreStream() { + COpcPackageRelationship * pKeyStoreRelation = m_pPackageReader->findRootRelation(PACKAGE_KEYSTORE_RELATIONSHIP_TYPE, true); + if (pKeyStoreRelation != nullptr) { + std::string sTargetPartURI = pKeyStoreRelation->getTargetPartURI(); + POpcPackagePart pKeystorePart = m_pPackageReader->createPart(sTargetPartURI); + if (pKeystorePart == nullptr) + throw CNMRException(NMR_ERROR_KEYSTOREOPCCOULDNOTGETSTREAM); + return pKeystorePart->getImportStream(); + } + return nullptr; + } + + void CKeyStoreOpcPackageReader::parseKeyStore(NMR::PImportStream keyStoreStream) { + + PXmlReader pXMLReader = fnCreateXMLReaderInstance(keyStoreStream, m_pContext.monitor()); + nfBool bHasModel = false; + eXmlReaderNodeType NodeType; + // Read all XML Root Nodes + while (!pXMLReader->IsEOF()) { + if (!pXMLReader->Read(NodeType)) + break; + + // Get Node Name + LPCSTR pszLocalName = nullptr; + pXMLReader->GetLocalName(&pszLocalName, nullptr); + if (!pszLocalName) + throw CNMRException(NMR_ERROR_COULDNOTGETLOCALXMLNAME); + + if (strcmp(pszLocalName, XML_3MF_ATTRIBUTE_PREFIX_XML) == 0) { + PModelReader_InstructionElement pXMLNode = std::make_shared(m_pContext.warnings()); + pXMLNode->parseXML(pXMLReader.get()); + } + + // Compare with Keystore Node Name + if (strcmp(pszLocalName, XML_3MF_ELEMENT_KEYSTORE) == 0) { + if (bHasModel) + throw CNMRException(NMR_ERROR_DUPLICATEMODELNODE); + bHasModel = true; + + PModelReaderNode_KeyStore pXMLNode = std::make_shared(m_pContext.model().get(), m_pContext.keyStore().get(), m_pContext.warnings()); + pXMLNode->parseXML(pXMLReader.get()); + } + } + } + + void CKeyStoreOpcPackageReader::openAllResourceDataGroups() { + auto keyStore = m_pContext.keyStore(); + auto secureContext = m_pContext.secureContext(); + + for (nfUint64 i = 0; i < keyStore->getResourceDataGroupCount() && !secureContext->emptyKekCtx(); ++i) { + PKeyStoreResourceDataGroup rdg = keyStore->getResourceDataGroup(i); + for (auto it = secureContext->kekCtxBegin(); it != secureContext->kekCtxEnd(); ++it) { + PKeyStoreConsumer consumer = keyStore->findConsumerById((*it).first); + if (consumer) { + PKeyStoreAccessRight accessRight = rdg->findAccessRightByConsumerID(consumer->getConsumerID()); + if (accessRight) { + KeyWrappingDescriptor ctx = (*it).second; + ctx.m_sKekDecryptData.m_pAccessRight = accessRight; + std::vector const & closedKey = accessRight->getCipherValue(); + std::vector openedKey; + size_t decrypted = ctx.m_fnWrap(closedKey, openedKey, ctx.m_sKekDecryptData); + if (decrypted) { + rdg->setKey(openedKey); + break; + } + } + } + } + } + } + void CKeyStoreOpcPackageReader::checkAuthenticatedTags() { + auto secureContext = m_pContext.secureContext(); + auto keyStore = m_pContext.keyStore(); + if (secureContext->hasDekCtx()) { + for (nfUint64 i = 0; i < m_pContext.keyStore()->getResourceDataCount(); ++i) { + NMR::PKeyStoreResourceData rd = keyStore->getResourceData(i); + NMR::PKeyStoreResourceDataGroup rdg = keyStore->findResourceDataGroupByResourceDataPath(rd->packagePath()); + PKeyStoreContentEncryptionParams params = CKeyStoreFactory::makeContentEncryptionParams(rd, rdg); + ContentEncryptionDescriptor descriptor = secureContext->getDekCtx(); + descriptor.m_sDekDecryptData.m_sParams= params; + descriptor.m_fnCrypt(0, nullptr, nullptr, descriptor.m_sDekDecryptData); + } + } + } +} diff --git a/Source/Model/Reader/NMR_ModelReader.cpp b/Source/Model/Reader/NMR_ModelReader.cpp index 3f4248f5c..381d59362 100644 --- a/Source/Model/Reader/NMR_ModelReader.cpp +++ b/Source/Model/Reader/NMR_ModelReader.cpp @@ -34,7 +34,8 @@ A model reader reads in a model file and generates an in-memory representation o #include "Common/NMR_Exception.h" #include "Common/NMR_Exception_Windows.h" #include "Common/Platform/NMR_ImportStream.h" - +#include "Common/NMR_SecureContext.h" +#include "Common/3MF_ProgressMonitor.h" #include "Model/Classes/NMR_ModelObject.h" #include "Model/Classes/NMR_ModelMeshObject.h" #include "Model/Classes/NMR_ModelBuildItem.h" @@ -42,17 +43,8 @@ A model reader reads in a model file and generates an in-memory representation o namespace NMR { CModelReader::CModelReader(_In_ PModel pModel) + :CModelContext(pModel) { - if (!pModel.get()) - throw CNMRException(NMR_ERROR_INVALIDPARAM); - - m_pModel = pModel; - m_pWarnings = std::make_shared(); - - m_pProgressMonitor = std::make_shared(); - - // Clear all legacy settings - m_pModel->clearAll(); } void CModelReader::readFromMeshImporter(_In_ CMeshImporter * pImporter) @@ -66,12 +58,12 @@ namespace NMR { pImporter->loadMesh(pMesh.get(), nullptr); // Add Single Mesh to Model - PModelMeshObject pMeshObject = std::make_shared(m_pModel->generateResourceID(), m_pModel.get(), pMesh); - m_pModel->addResource(pMeshObject); + PModelMeshObject pMeshObject = std::make_shared(model()->generateResourceID(), model().get(), pMesh); + model()->addResource(pMeshObject); // Add Build Item to Model - PModelBuildItem pBuildItem = std::make_shared(pMeshObject.get(), m_pModel->createHandle()); - m_pModel->addBuildItem(pBuildItem); + PModelBuildItem pBuildItem = std::make_shared(pMeshObject.get(), model()->createHandle()); + model()->addBuildItem(pBuildItem); } PImportStream CModelReader::retrievePrintTicket(_Out_ std::string & sContentType) @@ -80,11 +72,6 @@ namespace NMR { return m_pPrintTicketStream; } - PModelReaderWarnings CModelReader::getWarnings() - { - return m_pWarnings; - } - void CModelReader::addRelationToRead(_In_ std::string sRelationShipType) { m_RelationsToRead.insert(sRelationShipType); @@ -95,8 +82,4 @@ namespace NMR { m_RelationsToRead.erase(sRelationShipType); } - void CModelReader::SetProgressCallback(Lib3MFProgressCallback callback, void* userData) - { - m_pProgressMonitor->SetProgressCallback(callback, userData); - } } diff --git a/Source/Model/Reader/NMR_ModelReaderNode.cpp b/Source/Model/Reader/NMR_ModelReaderNode.cpp index 391dbcea8..578207414 100644 --- a/Source/Model/Reader/NMR_ModelReaderNode.cpp +++ b/Source/Model/Reader/NMR_ModelReaderNode.cpp @@ -40,7 +40,7 @@ A model reader node is an abstract base class for all XML nodes of a namespace NMR { - CModelReaderNode::CModelReaderNode(_In_ PModelReaderWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor) + CModelReaderNode::CModelReaderNode(_In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor) { m_bParsedAttributes = false; m_bParsedContent = false; @@ -57,7 +57,7 @@ namespace NMR { m_pWarnings = pWarnings; } else { - m_pWarnings = std::make_shared(); + m_pWarnings = std::make_shared(); } } @@ -84,7 +84,7 @@ namespace NMR { return m_sName; } - PModelReaderWarnings CModelReaderNode::getWarnings() + PModelWarnings CModelReaderNode::getWarnings() const { return m_pWarnings; } diff --git a/Source/Model/Reader/NMR_ModelReaderNode_KeyStoreBase.cpp b/Source/Model/Reader/NMR_ModelReaderNode_KeyStoreBase.cpp new file mode 100644 index 000000000..d16d2d63b --- /dev/null +++ b/Source/Model/Reader/NMR_ModelReaderNode_KeyStoreBase.cpp @@ -0,0 +1,42 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreBase.h defines the base class for all Model Reader Node classes that are related to . + +--*/ + +#include "Model/Reader/NMR_ModelReaderNode_KeyStoreBase.h" + +namespace NMR { + + CModelReaderNode_KeyStoreBase::CModelReaderNode_KeyStoreBase(_In_ CModel * const pModel, _In_ CKeyStore * const pKeyStore, _In_ PModelWarnings pWarnings) + : CModelReaderNode(pWarnings), m_pModel(pModel), m_pKeyStore(pKeyStore) + { + } +} diff --git a/Source/Model/Reader/NMR_ModelReaderNode_Model.cpp b/Source/Model/Reader/NMR_ModelReaderNode_ModelBase.cpp similarity index 76% rename from Source/Model/Reader/NMR_ModelReaderNode_Model.cpp rename to Source/Model/Reader/NMR_ModelReaderNode_ModelBase.cpp index 6ef2375f4..710ac8867 100644 --- a/Source/Model/Reader/NMR_ModelReaderNode_Model.cpp +++ b/Source/Model/Reader/NMR_ModelReaderNode_ModelBase.cpp @@ -26,12 +26,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Abstract: -NMR_ModelReaderNode_Model.cpp implements the Model Reader Node Class. +NMR_ModelReaderNode_ModelBase.cpp implements the Model Reader Node Class. A model reader node is an abstract base class for all XML nodes of a 3MF Model Stream. --*/ -#include "Model/Reader/NMR_ModelReaderNode_Model.h" +#include "Model/Reader/NMR_ModelReaderNode_ModelBase.h" #include "Model/Reader/v100/NMR_ModelReaderNode100_Resources.h" #include "Model/Reader/v100/NMR_ModelReaderNode100_Build.h" #include "Model/Reader/v100/NMR_ModelReaderNode100_MetaData.h" @@ -51,7 +51,7 @@ A model reader node is an abstract base class for all XML nodes of a 3MF Model S namespace NMR { - CModelReaderNode_Model::CModelReaderNode_Model(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings, const std::string sPath, + CModelReaderNode_ModelBase::CModelReaderNode_ModelBase(_In_ CModel * pModel, _In_ PModelWarnings pWarnings, const std::string sPath, _In_ PProgressMonitor pProgressMonitor) : CModelReaderNode(pWarnings, pProgressMonitor), m_bIgnoreBuild(false), m_bIgnoreMetaData(false), m_bHaveWarnedAboutV093(false) { @@ -68,7 +68,7 @@ namespace NMR { m_sPath = sPath; } - void CModelReaderNode_Model::CheckRequiredExtensions() { + void CModelReaderNode_ModelBase::CheckRequiredExtensions() { // check, whether all required extensions are available in this implementation before actually parsing the file std::istringstream iss(m_sRequiredExtensions); std::vector tokens{ std::istream_iterator{iss}, @@ -84,14 +84,15 @@ namespace NMR { strcmp(sExtensionURI.c_str(), XML_3MF_NAMESPACE_MATERIALSPEC) != 0 && strcmp(sExtensionURI.c_str(), XML_3MF_NAMESPACE_PRODUCTIONSPEC) != 0 && strcmp(sExtensionURI.c_str(), XML_3MF_NAMESPACE_SLICESPEC) != 0 && - strcmp(sExtensionURI.c_str(), XML_3MF_NAMESPACE_BEAMLATTICESPEC) != 0 ) + strcmp(sExtensionURI.c_str(), XML_3MF_NAMESPACE_BEAMLATTICESPEC) != 0 && + strcmp(sExtensionURI.c_str(), XML_3MF_NAMESPACE_SECURECONTENTSPEC) != 0 ) { - m_pWarnings->addWarning(MODELREADERWARNING_REQUIREDEXTENSIONNOTSUPPORTED, NMR_ERROR_REQUIREDEXTENSIONNOTSUPPORTED, mrwInvalidMandatoryValue); + m_pWarnings->addWarning(NMR_ERROR_REQUIREDEXTENSIONNOTSUPPORTED, mrwInvalidMandatoryValue); } } } - void CModelReaderNode_Model::parseXML(_In_ CXmlReader * pXMLReader) + void CModelReaderNode_ModelBase::parseXML(_In_ CXmlReader * pXMLReader) { // Parse name parseName(pXMLReader); @@ -107,7 +108,7 @@ namespace NMR { } - void CModelReaderNode_Model::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + void CModelReaderNode_ModelBase::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) { __NMRASSERT(pAttributeName); __NMRASSERT(pAttributeValue); @@ -119,7 +120,7 @@ namespace NMR { m_pModel->setUnitString(pAttributeValue); } catch (CNMRException & e) { - m_pWarnings->addWarning(MODELREADERWARNING_INVALIDMODELUNIT, e.getErrorCode(), mrwInvalidMandatoryValue); + m_pWarnings->addException(e, mrwInvalidMandatoryValue); } } else if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_REQUIREDEXTENSIONS) == 0) { @@ -127,7 +128,7 @@ namespace NMR { } } - void CModelReaderNode_Model::OnNSAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue, _In_z_ const nfChar * pNameSpace) + void CModelReaderNode_ModelBase::OnNSAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue, _In_z_ const nfChar * pNameSpace) { if (strcmp(pNameSpace, XML_3MF_NAMESPACE_XML) == 0) { if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_MODEL_LANG) == 0) { @@ -144,7 +145,7 @@ namespace NMR { } } - void CModelReaderNode_Model::ReadMetaDataNode(_In_ CXmlReader * pXMLReader) + void CModelReaderNode_ModelBase::ReadMetaDataNode(_In_ CXmlReader * pXMLReader) { PModelReaderNode100_MetaData pXMLNode = std::make_shared(m_pWarnings); pXMLNode->parseXML(pXMLReader); @@ -156,33 +157,35 @@ namespace NMR { if (!sKey.empty()) { if (m_pModel->hasMetaData(sKey)) { - m_pWarnings->addWarning(MODELREADERWARNING_DUPLICATEMETADATA, NMR_ERROR_DUPLICATEMETADATA, mrwInvalidOptionalValue); - } - std::string sNameSpace, sName; - CModelMetaData::decomposeKeyIntoNamespaceAndName(sKey, sNameSpace, sName); - if (!sNameSpace.empty()) { - std::string sNameSpaceURI; - if (!pXMLReader->GetNamespaceURI(sNameSpace, sNameSpaceURI)) { - m_pWarnings->addException(CNMRException(NMR_ERROR_METADATA_COULDNOTGETNAMESPACE), mrwInvalidOptionalValue); - sNameSpaceURI = sNameSpace; - } - m_pModel->addMetaData(sNameSpaceURI, sName, sValue, sType, bPreserve); + m_pWarnings->addWarning(NMR_ERROR_DUPLICATEMETADATA, mrwInvalidOptionalValue); } else { - // default namespace - if (CModelMetaData::isValidNamespaceAndName("", sName)) { - m_pModel->addMetaData("", sName, sValue, sType, bPreserve); + std::string sNameSpace, sName; + decomposeKeyIntoNamespaceAndName(sKey, sNameSpace, sName); + if (!sNameSpace.empty()) { + std::string sNameSpaceURI; + if (!pXMLReader->GetNamespaceURI(sNameSpace, sNameSpaceURI)) { + m_pWarnings->addException(CNMRException(NMR_ERROR_METADATA_COULDNOTGETNAMESPACE), mrwInvalidOptionalValue); + sNameSpaceURI = sNameSpace; + } + m_pModel->addMetaData(sNameSpaceURI, sName, sValue, sType, bPreserve); + } + else { + // default namespace + if (CModelMetaData::isValidNamespaceAndName("", sName)) { + m_pModel->addMetaData("", sName, sValue, sType, bPreserve); + } + else + m_pWarnings->addException(CNMRException(NMR_ERROR_UNKNOWNMETADATA), mrwInvalidOptionalValue); } - else - m_pWarnings->addException(CNMRException(NMR_ERROR_UNKNOWNMETADATA), mrwInvalidOptionalValue); } } else { - m_pWarnings->addWarning(MODELREADERWARNING_INVALIDMETADATA, NMR_ERROR_INVALIDMETADATA, mrwInvalidOptionalValue); + m_pWarnings->addWarning(NMR_ERROR_INVALIDMETADATA, mrwInvalidOptionalValue); } } - void CModelReaderNode_Model::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) + void CModelReaderNode_ModelBase::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) { if (strcmp(pNameSpace, XML_3MF_NAMESPACE_CORESPEC100) == 0) { if (strcmp(pChildName, XML_3MF_ELEMENT_RESOURCES) == 0) { @@ -261,30 +264,30 @@ namespace NMR { } } - nfBool CModelReaderNode_Model::getHasResources() + nfBool CModelReaderNode_ModelBase::getHasResources() { return m_bHasResources; } - nfBool CModelReaderNode_Model::getHasBuild() + nfBool CModelReaderNode_ModelBase::getHasBuild() { return m_bHasBuild; } - nfBool CModelReaderNode_Model::ignoreBuild() + nfBool CModelReaderNode_ModelBase::ignoreBuild() { return m_bIgnoreBuild; } - void CModelReaderNode_Model::setIgnoreBuild(bool bIgnoreBuild) + void CModelReaderNode_ModelBase::setIgnoreBuild(bool bIgnoreBuild) { m_bIgnoreBuild = bIgnoreBuild; } - nfBool CModelReaderNode_Model::ignoreMetaData() + nfBool CModelReaderNode_ModelBase::ignoreMetaData() { return m_bIgnoreMetaData; } - void CModelReaderNode_Model::setIgnoreMetaData(bool bIgnoreMetaData) + void CModelReaderNode_ModelBase::setIgnoreMetaData(bool bIgnoreMetaData) { m_bIgnoreMetaData = bIgnoreMetaData; } diff --git a/Source/Model/Reader/NMR_ModelReaderNode_StringValue.cpp b/Source/Model/Reader/NMR_ModelReaderNode_StringValue.cpp new file mode 100644 index 000000000..df604cd10 --- /dev/null +++ b/Source/Model/Reader/NMR_ModelReaderNode_StringValue.cpp @@ -0,0 +1,67 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreKeyValue.h defines the Model Reader Node class that is related to . + +--*/ + +#include "Model/Reader/NMR_ModelReaderNode_StringValue.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_StringUtils.h" + +namespace NMR { + + std::string const & CModelReaderNode_StringValue::getValue() const + { + return m_sKeyValue; + } + + void CModelReaderNode_StringValue::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + } + + void CModelReaderNode_StringValue::OnText(_In_z_ const nfChar * pText, _In_ CXmlReader * pXMLReader) + { + __NMRASSERT(pText); + + m_sKeyValue += std::string(pText); + } + +} diff --git a/Source/Model/Reader/NMR_ModelReader_3MF.cpp b/Source/Model/Reader/NMR_ModelReader_3MF.cpp index 7c9f91d57..c7010ec5d 100644 --- a/Source/Model/Reader/NMR_ModelReader_3MF.cpp +++ b/Source/Model/Reader/NMR_ModelReader_3MF.cpp @@ -32,7 +32,7 @@ NMR_ModelReader_3MF.cpp implements the Model Reader Class for --*/ #include "Model/Reader/NMR_ModelReader_3MF.h" -#include "Model/Reader/NMR_ModelReaderNode_Model.h" +#include "Model/Reader/NMR_ModelReaderNode_ModelBase.h" #include "Model/Classes/NMR_ModelObject.h" #include "Model/Classes/NMR_ModelMeshObject.h" #include "Model/Classes/NMR_ModelConstants.h" @@ -57,7 +57,7 @@ namespace NMR { // empty on purpose } - void readProductionAttachmentModels(_In_ PModel pModel, _In_ PModelReaderWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor) + void readProductionAttachmentModels(_In_ PModel pModel, _In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor) { nfUint32 prodAttCount = pModel->getProductionAttachmentCount(); for (nfInt32 i = prodAttCount-1; i >=0; i--) @@ -68,7 +68,7 @@ namespace NMR { } PModelAttachment pProdAttachment = pModel->getProductionModelAttachment(i); - std::string path = pProdAttachment->getPathURI(); + std::string sPath = pProdAttachment->getPathURI(); PImportStream pSubModelStream = pProdAttachment->getStream(); // Create XML Reader @@ -98,10 +98,10 @@ namespace NMR { throw CNMRException(NMR_ERROR_DUPLICATEMODELNODE); bHasModel = true; - PModelReaderNode_Model pXMLNode; - pModel->setCurPath(path.c_str()); + PModelReaderNode_ModelBase pXMLNode; + pModel->setCurrentPath(sPath); - pXMLNode = std::make_shared(pModel.get(), pWarnings, path.c_str(), pProgressMonitor); + pXMLNode = std::make_shared(pModel.get(), pWarnings, sPath, pProgressMonitor); pXMLNode->setIgnoreBuild(true); pXMLNode->setIgnoreMetaData(true); pXMLNode->parseXML(pXMLReader.get()); @@ -122,21 +122,21 @@ namespace NMR { nfBool bHasModel = false; - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_READSTREAM); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_READSTREAM); - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_EXTRACTOPCPACKAGE); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_EXTRACTOPCPACKAGE); // Extract Stream from Package PImportStream pModelStream = extract3MFOPCPackage(pStream); // before reading the root model, read the other models in the file - readProductionAttachmentModels(m_pModel, m_pWarnings, m_pProgressMonitor); + readProductionAttachmentModels(model(), warnings(), monitor()); - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_READROOTMODEL); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_READROOTMODEL); + monitor()->ReportProgressAndQueryCancelled(true); // Create XML Reader - PXmlReader pXMLReader = fnCreateXMLReaderInstance(pModelStream, m_pProgressMonitor); + PXmlReader pXMLReader = fnCreateXMLReaderInstance(pModelStream, monitor()); eXmlReaderNodeType NodeType; // Read all XML Root Nodes @@ -151,7 +151,7 @@ namespace NMR { throw CNMRException(NMR_ERROR_COULDNOTGETLOCALXMLNAME); if (strcmp(pszLocalName, XML_3MF_ATTRIBUTE_PREFIX_XML) == 0) { - PModelReader_InstructionElement pXMLNode = std::make_shared(m_pWarnings); + PModelReader_InstructionElement pXMLNode = std::make_shared(warnings()); pXMLNode->parseXML(pXMLReader.get()); } @@ -161,8 +161,8 @@ namespace NMR { throw CNMRException(NMR_ERROR_DUPLICATEMODELNODE); bHasModel = true; - m_pModel->setCurPath(m_pModel->rootPath().c_str()); - PModelReaderNode_Model pXMLNode = std::make_shared(m_pModel.get(), m_pWarnings, m_pModel->rootPath().c_str(), m_pProgressMonitor); + model()->setCurrentPath(model()->rootPath()); + PModelReaderNode_ModelBase pXMLNode = std::make_shared(model().get(), warnings(), model()->rootPath(), monitor()); pXMLNode->parseXML(pXMLReader.get()); if (!pXMLNode->getHasResources()) @@ -173,8 +173,8 @@ namespace NMR { } - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_CLEANUP); - m_pProgressMonitor->ReportProgressAndQueryCancelled(false); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_CLEANUP); + monitor()->ReportProgressAndQueryCancelled(false); // Release Memory of 3MF Package release3MFOPCPackage(); @@ -182,8 +182,8 @@ namespace NMR { if (!bHasModel) throw CNMRException(NMR_ERROR_NOMODELNODE); - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_DONE); - m_pProgressMonitor->ReportProgressAndQueryCancelled(false); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_DONE); + monitor()->ReportProgressAndQueryCancelled(false); } void CModelReader_3MF::addTextureAttachment(_In_ std::string sPath, _In_ PImportStream pStream) @@ -191,7 +191,7 @@ namespace NMR { if (pStream.get() == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); - m_pModel->addAttachment(sPath, PACKAGE_TEXTURE_RELATIONSHIP_TYPE, pStream); + model()->addAttachment(sPath, PACKAGE_TEXTURE_RELATIONSHIP_TYPE, pStream); } } diff --git a/Source/Model/Reader/NMR_ModelReader_3MF_Native.cpp b/Source/Model/Reader/NMR_ModelReader_3MF_Native.cpp index 5eca3c605..b531a5d2b 100644 --- a/Source/Model/Reader/NMR_ModelReader_3MF_Native.cpp +++ b/Source/Model/Reader/NMR_ModelReader_3MF_Native.cpp @@ -33,12 +33,16 @@ It uses libzip and irrxml to parse the OPC package. --*/ #include "Model/Reader/NMR_ModelReader_3MF_Native.h" -#include "Model/Reader/NMR_ModelReaderNode_Model.h" +#include "Model/Reader/NMR_ModelReaderNode_ModelBase.h" #include "Model/Classes/NMR_ModelConstants.h" #include "Model/Classes/NMR_ModelAttachment.h" +#include "Model/Classes/NMR_KeyStore.h" +#include "Common/NMR_SecureContext.h" #include "Common/NMR_Exception.h" #include "Common/NMR_Exception_Windows.h" #include "Common/NMR_StringUtils.h" +#include "Common/Platform/NMR_Platform.h" +#include "Model/Reader/NMR_ModelReader_InstructionElement.h" namespace NMR { @@ -48,20 +52,22 @@ namespace NMR { // empty on purpose } + + PImportStream CModelReader_3MF_Native::extract3MFOPCPackage(_In_ PImportStream pPackageStream) { - m_pPackageReader = std::make_shared(pPackageStream, m_pWarnings, m_pProgressMonitor); + m_pPackageReader = std::make_shared(pPackageStream, *this); COpcPackageRelationship * pModelRelation = m_pPackageReader->findRootRelation(PACKAGE_START_PART_RELATIONSHIP_TYPE, true); if (pModelRelation == nullptr) throw CNMRException(NMR_ERROR_OPCRELATIONSHIPSETREADFAILED); std::string sTargetPartURI = pModelRelation->getTargetPartURI(); - POpcPackagePart pModelPart = m_pPackageReader->createPart (sTargetPartURI); + POpcPackagePart pModelPart = m_pPackageReader->createPart(sTargetPartURI); if (pModelPart == nullptr) throw CNMRException(NMR_ERROR_OPCCOULDNOTGETMODELSTREAM); - m_pModel->setRootPath(sTargetPartURI.c_str()); + model()->setRootPath(sTargetPartURI.c_str()); // calculate current level at this stage std::string sTargetPartURIDir = fnExtractFileDir(sTargetPartURI); @@ -70,10 +76,10 @@ namespace NMR { extractCustomDataFromRelationships(sTargetPartURIDir, pModelPart.get()); extractModelDataFromRelationships(sTargetPartURIDir, pModelPart.get()); - nfUint32 prodAttCount = m_pModel->getProductionAttachmentCount(); + nfUint32 prodAttCount = model()->getProductionAttachmentCount(); for (nfUint32 i = 0; i < prodAttCount; i++) { - PModelAttachment pProdAttachment = m_pModel->getProductionModelAttachment(i); + PModelAttachment pProdAttachment = model()->getProductionModelAttachment(i); std::string pathURI = pProdAttachment->getPathURI(); POpcPackagePart pSubModelPart = m_pPackageReader->createPart(pathURI); extractModelDataFromRelationships(sTargetPartURIDir, pSubModelPart.get()); @@ -87,9 +93,9 @@ namespace NMR { if (pThumbnailPart == nullptr) throw CNMRException(NMR_ERROR_OPCCOULDNOTGETTHUMBNAILSTREAM); PImportStream pThumbnailStream = pThumbnailPart->getImportStream()->copyToMemory(); - m_pModel->addPackageThumbnail()->setStream(pThumbnailStream); - m_pProgressMonitor->IncrementProgress((double)pThumbnailStream->retrieveSize()); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + model()->addPackageThumbnail()->setStream(pThumbnailStream); + monitor()->IncrementProgress((double)pThumbnailStream->retrieveSize()); + monitor()->ReportProgressAndQueryCancelled(true); } return pModelPart->getImportStream(); @@ -97,6 +103,8 @@ namespace NMR { void CModelReader_3MF_Native::release3MFOPCPackage() { + //foreach part, finalize encryption contexts + m_pPackageReader->close(); m_pPackageReader = nullptr; } @@ -105,7 +113,7 @@ namespace NMR { if (pModelPart == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); - m_pProgressMonitor->SetProgressIdentifier(PROGRESS_READTEXTURETACHMENTS); + monitor()->SetProgressIdentifier(PROGRESS_READTEXTURETACHMENTS); std::multimap& RelationShips = pModelPart->getRelationShips(); @@ -124,20 +132,20 @@ namespace NMR { if (!fnStartsWithPathDelimiter(sURI)) sURI = sTargetPartURIDir + sURI; - PModelAttachment pModelAttachment = m_pModel->findModelAttachment(sURI); + PModelAttachment pModelAttachment = model()->findModelAttachment(sURI); if (!pModelAttachment) { POpcPackagePart pTexturePart = m_pPackageReader->createPart(sURI); PImportStream pTextureAttachmentStream = pTexturePart->getImportStream(); PImportStream pMemoryStream = pTextureAttachmentStream->copyToMemory(); if (pMemoryStream->retrieveSize() == 0) - m_pWarnings->addException(CNMRException(NMR_ERROR_IMPORTSTREAMISEMPTY), mrwMissingMandatoryValue); + warnings()->addException(CNMRException(NMR_ERROR_IMPORTSTREAMISEMPTY), mrwMissingMandatoryValue); // Add Texture Attachment to Model addTextureAttachment(sURI, pMemoryStream); - m_pProgressMonitor->IncrementProgress((double)pMemoryStream->retrieveSize()); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->IncrementProgress((double)pMemoryStream->retrieveSize()); + monitor()->ReportProgressAndQueryCancelled(true); } } } @@ -149,7 +157,7 @@ namespace NMR { if (pModelPart == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); - m_pProgressMonitor->SetProgressIdentifier(PROGRESS_READCUSTOMATTACHMENTS); + monitor()->SetProgressIdentifier(PROGRESS_READCUSTOMATTACHMENTS); std::multimap& RelationShips = pModelPart->getRelationShips(); @@ -170,17 +178,17 @@ namespace NMR { PImportStream pMemoryStream = pAttachmentStream->copyToMemory(); if (pMemoryStream->retrieveSize() == 0) - m_pWarnings->addException(CNMRException(NMR_ERROR_IMPORTSTREAMISEMPTY), mrwMissingMandatoryValue); + warnings()->addException(CNMRException(NMR_ERROR_IMPORTSTREAMISEMPTY), mrwMissingMandatoryValue); // Add Attachment Stream to Model - m_pModel->addAttachment(sURI, sRelationShipType, pMemoryStream); + model()->addAttachment(sURI, sRelationShipType, pMemoryStream); - m_pProgressMonitor->IncrementProgress((double)pMemoryStream->retrieveSize()); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->IncrementProgress((double)pMemoryStream->retrieveSize()); + monitor()->ReportProgressAndQueryCancelled(true); } catch (CNMRException &e) { if (e.getErrorCode() == NMR_ERROR_INVALIDBUFFERSIZE) - m_pWarnings->addException(CNMRException(NMR_ERROR_ATTACHMENTTOOLARGE), mrwMissingMandatoryValue); + warnings()->addException(CNMRException(NMR_ERROR_ATTACHMENTTOOLARGE), mrwMissingMandatoryValue); else throw; } @@ -190,8 +198,8 @@ namespace NMR { && (sRelationShipType != PACKAGE_TEXTURE_RELATIONSHIP_TYPE) && (sRelationShipType != PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE) ) { - m_pProgressMonitor->DecreaseMaxProgress((double)m_pPackageReader->GetPartSize(sURI)); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->DecreaseMaxProgress((double)m_pPackageReader->getPartSize(sURI)); + monitor()->ReportProgressAndQueryCancelled(true); } } } @@ -217,18 +225,18 @@ namespace NMR { POpcPackagePart pPart = m_pPackageReader->createPart(sURI); // first, check if this attachment already is in model - PModelAttachment pModelAttachment = m_pModel->findProductionModelAttachment(sURI); + PModelAttachment pModelAttachment = model()->findProductionModelAttachment(sURI); if (pModelAttachment) { // this attachment is already read - m_pModel->addProductionAttachment(sURI, sRelationShipType, pModelAttachment->getStream(), false); + model()->addProductionAttachment(sURI, sRelationShipType, pModelAttachment->getStream(), false); } else { // this is the first time this attachment is read PImportStream pAttachmentStream = pPart->getImportStream(); PImportStream pMemoryStream = pAttachmentStream->copyToMemory(); if (pMemoryStream->retrieveSize() == 0) - m_pWarnings->addException(CNMRException(NMR_ERROR_IMPORTSTREAMISEMPTY), mrwMissingMandatoryValue); - m_pModel->addProductionAttachment(sURI, sRelationShipType, pMemoryStream, true); + warnings()->addException(CNMRException(NMR_ERROR_IMPORTSTREAMISEMPTY), mrwMissingMandatoryValue); + model()->addProductionAttachment(sURI, sRelationShipType, pMemoryStream, true); } } } diff --git a/Source/Model/Reader/NMR_ModelReader_InstructionElement.cpp b/Source/Model/Reader/NMR_ModelReader_InstructionElement.cpp index 187ee8752..4c3dbb745 100644 --- a/Source/Model/Reader/NMR_ModelReader_InstructionElement.cpp +++ b/Source/Model/Reader/NMR_ModelReader_InstructionElement.cpp @@ -40,7 +40,7 @@ NMR_ModelReader_InstructionElement.cpp implements a reader for an instruction el namespace NMR { - CModelReader_InstructionElement::CModelReader_InstructionElement(_In_ PModelReaderWarnings pWarnings) + CModelReader_InstructionElement::CModelReader_InstructionElement(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings), m_sName("") { } diff --git a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStore.cpp b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStore.cpp new file mode 100644 index 000000000..fa41c1bb0 --- /dev/null +++ b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStore.cpp @@ -0,0 +1,107 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStore.h defines the Model Reader Node class that is related to . + +--*/ + +// TODO: check if needs #include +// https://stackoverflow.com/questions/1646031/strtoull-and-long-long-arithmetic + +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStore.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreConsumer.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceDataGroup.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_StringUtils.h" + +namespace NMR { + + void CModelReaderNode_KeyStore::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + + // Set references + if (!m_UUID.get()) { + // We do not have to check for secure content spec, because it is the base spec of a keystore + m_pWarnings->addWarning(NMR_ERROR_MISSINGUUID, mrwMissingMandatoryValue); + m_UUID = std::make_shared(); + } + keystore()->setUUID(m_UUID); + } + + void CModelReaderNode_KeyStore::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + { + __NMRASSERT(pAttributeName); + __NMRASSERT(pAttributeValue); + + if (strcmp(XML_3MF_SECURE_CONTENT_UUID, pAttributeName) == 0) { + if (m_UUID.get()) + m_pWarnings->addWarning(NMR_ERROR_DUPLICATEUUID, eModelWarningLevel::mrwInvalidMandatoryValue); + // this can throw for invalid UUIDs and it's ok so according to other reader nodes + m_UUID = std::make_shared(pAttributeValue); + } + else if (strcmp(XML_3MF_ATTRIBUTE_XMLNS, pAttributeName) != 0) + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ATTRIBUTE, mrwInvalidOptionalValue); + } + + void CModelReaderNode_KeyStore::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) + { + __NMRASSERT(pChildName); + __NMRASSERT(pXMLReader); + __NMRASSERT(pNameSpace); + + if (strcmp(pNameSpace, XML_3MF_NAMESPACE_SECURECONTENTSPEC) == 0) { + // Read a consumer + if (strcmp(pChildName, XML_3MF_ELEMENT_CONSUMER) == 0) { + PModelReaderNode_KeyStoreConsumer pXMLNode = extractCopy(); + pXMLNode->parseXML(pXMLReader); + // consumer adds itself to m_pKeyStore, nothing else to do here + } + else if (strcmp(pChildName, XML_3MF_ELEMENT_RESOURCEDATAGROUP) == 0) { + PModelReaderNode_KeyStoreResourceDataGroup pXMLNode = extractCopy(); + pXMLNode->parseXML(pXMLReader); + // resource data adds itself to m_pKeyStore, nothing else to do here + } + else + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ELEMENT, mrwInvalidOptionalValue); + } + } + +} diff --git a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreAccessRight.cpp b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreAccessRight.cpp new file mode 100644 index 000000000..40220fd13 --- /dev/null +++ b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreAccessRight.cpp @@ -0,0 +1,121 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreAccessRight.h defines the Model Reader Node class that is related to . + +--*/ + +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreAccessRight.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreKEKParams.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_KeyStoreFactory.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_StringUtils.h" + +namespace NMR { + + PKeyStoreAccessRight CModelReaderNode_KeyStoreAccessRight::getAccessRight() + { + return CKeyStoreFactory::makeAccessRight( + m_pKeyStore->getConsumer(m_nConsumerIndex), + m_sParams.m_eAlgorithm, + m_sParams.m_eMgf, + m_sParams.m_eDigest, + m_rgCipherValue); + } + + void CModelReaderNode_KeyStoreAccessRight::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + + // this can throw for values that are not numbers and it's ok so according to other reader nodes + if (!m_bHasConsumerIndex) { + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREMISSINGCONSUMERINDEX, eModelWarningLevel::mrwMissingMandatoryValue); + m_nConsumerIndex = 0; + } + if (m_nConsumerIndex >= m_pKeyStore->getConsumerCount()) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREINVALIDCONSUMERINDEX, eModelWarningLevel::mrwFatal); + if (!m_bHasParams) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREMISSINGKEKPARAMS, eModelWarningLevel::mrwFatal); + if (!m_bHasCipherData) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREMISSINGCIPHERDATA, eModelWarningLevel::mrwFatal); + } + + void CModelReaderNode_KeyStoreAccessRight::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + { + __NMRASSERT(pAttributeName); + __NMRASSERT(pAttributeValue); + + if (strcmp(XML_3MF_SECURE_CONTENT_CONSUMER_INDEX, pAttributeName) == 0) { + if (m_bHasConsumerIndex) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREDUPLICATECONSUMERINDEX, eModelWarningLevel::mrwInvalidMandatoryValue); + m_bHasConsumerIndex = true; + m_nConsumerIndex = fnStringToUint32(pAttributeValue); + } + else + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ATTRIBUTE, mrwInvalidOptionalValue); + } + + void CModelReaderNode_KeyStoreAccessRight::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) + { + __NMRASSERT(pChildName); + __NMRASSERT(pXMLReader); + __NMRASSERT(pNameSpace); + if (strcmp(pNameSpace, XML_3MF_NAMESPACE_SECURECONTENTSPEC) == 0) { + if (strcmp(pChildName, XML_3MF_ELEMENT_KEKPARAMS) == 0) { + if (!m_bHasParams) { + m_bHasParams = true; + PModelReaderNode_KeyStoreKEKParams pXMLNode = extractCopy(); + pXMLNode->parseXML(pXMLReader); + m_sParams = pXMLNode->getKekParams(); + } + } else if (strcmp(pChildName, XML_3MF_ELEMENT_CIPHERDATA) == 0) { + if (!m_bHasCipherData) { + m_bHasCipherData = true; + PModelReaderNode_KeyStoreCipherValue pXMLNode = extractCopy(); + pXMLNode->parseXML(pXMLReader); + m_rgCipherValue = pXMLNode->getCipherValue(); + } + } else { + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ELEMENT, mrwInvalidOptionalValue); + } + } + } + +} diff --git a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.cpp b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.cpp new file mode 100644 index 000000000..c8d533f0d --- /dev/null +++ b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.cpp @@ -0,0 +1,128 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreCipherValue.h defines the Model Reader Node class that is related to . + +--*/ + +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.h" +#include "Model/Reader/NMR_ModelReaderNode_StringValue.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +#include "Model/Classes/NMR_KeyStoreFactory.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_StringUtils.h" + +#include "Libraries/cpp-base64/base64.h" + +namespace NMR { + namespace ParserUtils { + eKeyStoreEncryptAlgorithm parseEncryptionAlgorithm(std::string const & value) { + if (XML_3MF_SECURE_CONTENT_ENCRYPTION_AES256 == value) { + return eKeyStoreEncryptAlgorithm::AES256_GCM; + } + throw CNMRException(NMR_ERROR_KEYSTOREINVALIDALGORITHM); + } + } + + PKeyStoreCEKParams CModelReaderNode_KeyStoreCEKParams::getCEKParams() + { + return CKeyStoreFactory::makeCEKParams(m_bCompressed, m_eAlgorithm, m_aad, m_iv, m_tag); + } + + void CModelReaderNode_KeyStoreCEKParams::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + + if (!m_bHasAlgorithm) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREMISSINGALGORTHM, eModelWarningLevel::mrwMissingMandatoryValue); + } + + void CModelReaderNode_KeyStoreCEKParams::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + { + __NMRASSERT(pAttributeName); + __NMRASSERT(pAttributeValue); + + if (strcmp(XML_3MF_SECURE_CONTENT_ENCRYPTION_ALGORITHM, pAttributeName) == 0) { + try { + m_bHasAlgorithm = true; + m_eAlgorithm = ParserUtils::parseEncryptionAlgorithm(pAttributeValue); + } catch (CNMRException const &) { + m_eAlgorithm = eKeyStoreEncryptAlgorithm::AES256_GCM; + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREINVALIDALGORITHM, eModelWarningLevel::mrwInvalidMandatoryValue); + } + } + else if (strcmp(XML_3MF_SECURE_CONTENT_COMPRESSION, pAttributeName) == 0) { + if (strcmp(XML_3MF_SECURE_CONTENT_COMPRESSION_DEFLATE, pAttributeValue) == 0) { + m_bCompressed = true; + } else if (strcmp(XML_3MF_SECURE_CONTENT_COMPRESSION_NONE, pAttributeValue) == 0) { + m_bCompressed = false; + } else { + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREINVALIDCOMPRESSION, mrwInvalidOptionalValue); + } + } + else + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ATTRIBUTE, mrwInvalidOptionalValue); + } + + void CModelReaderNode_KeyStoreCEKParams::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) + { + __NMRASSERT(pChildName); + __NMRASSERT(pXMLReader); + __NMRASSERT(pNameSpace); + if (strcmp(pNameSpace, XML_3MF_NAMESPACE_SECURECONTENTSPEC) == 0) { + if (strcmp(pChildName, XML_3MF_SECURE_CONTENT_IV) == 0) { + PModelReaderNode_StringValue pXMLNode = std::make_shared(m_pWarnings); + pXMLNode->parseXML(pXMLReader); + m_iv = base64_decode(pXMLNode->getValue()); + } else if (strcmp(pChildName, XML_3MF_SECURE_CONTENT_TAG) == 0) { + PModelReaderNode_StringValue pXMLNode = std::make_shared(m_pWarnings); + pXMLNode->parseXML(pXMLReader); + m_tag = base64_decode(pXMLNode->getValue()); + } else if (strcmp(pChildName, XML_3MF_SECURE_CONTENT_AAD) == 0) { + PModelReaderNode_StringValue pXMLNode = std::make_shared(m_pWarnings); + pXMLNode->parseXML(pXMLReader); + m_aad = base64_decode(pXMLNode->getValue()); + } else { + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ELEMENT, mrwInvalidOptionalValue); + } + } + } +} diff --git a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.cpp b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.cpp new file mode 100644 index 000000000..d0a0420dc --- /dev/null +++ b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.cpp @@ -0,0 +1,78 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreCipherValue.h defines the Model Reader Node class that is related to . + +--*/ + +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCipherValue.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_StringUtils.h" + +#include "Model/Reader/NMR_ModelReaderNode_StringValue.h" +#include "Libraries/cpp-base64/base64.h" + +namespace NMR { + + std::vector const & CModelReaderNode_KeyStoreCipherValue::getCipherValue() const + { + return m_sCipherValue; + } + + void CModelReaderNode_KeyStoreCipherValue::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + + if (m_sCipherValue.empty()) { + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREINVALIDCIPHERVALUE, eModelWarningLevel::mrwMissingMandatoryValue); + } + } + + void CModelReaderNode_KeyStoreCipherValue::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) { + if (strcmp(pNameSpace, XML_3MF_NAMESPACE_CIPHERVALUESPEC) == 0 + && strcmp(pChildName, XML_3MF_ELEMENT_CIPHERVALUE) == 0) { + PModelReaderNode_StringValue pNode = std::make_shared(m_pWarnings); + pNode->parseXML(pXMLReader); + m_sCipherValue = base64_decode(pNode->getValue()); + } + } + +} diff --git a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreConsumer.cpp b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreConsumer.cpp new file mode 100644 index 000000000..6156c7ded --- /dev/null +++ b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreConsumer.cpp @@ -0,0 +1,103 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreConsumer.h defines the Model Reader Node class that is related to . + +--*/ + +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreConsumer.h" +#include "Model/Reader/NMR_ModelReaderNode_StringValue.h" +#include "Model/Classes/NMR_KeyStoreFactory.h" +#include "Model/Classes/NMR_ModelConstants.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_StringUtils.h" + +namespace NMR { + + void CModelReaderNode_KeyStoreConsumer::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + + // check consumer id + if (m_sConsumerID.empty()) { + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREMISSINGCONSUMERID, mrwMissingMandatoryValue); + //add some default value + m_sConsumerID = "ConsumerID" + fnInt32ToString(m_pWarnings->getWarningCount()); + } + + PKeyStoreConsumer c = CKeyStoreFactory::makeConsumer(m_sConsumerID, m_sKeyID, m_sKeyValue); + m_pKeyStore->addConsumer(c); + } + + void CModelReaderNode_KeyStoreConsumer::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + { + __NMRASSERT(pAttributeName); + __NMRASSERT(pAttributeValue); + + if (strcmp(XML_3MF_SECURE_CONTENT_CONSUMER_ID, pAttributeName) == 0) { + if (!m_sConsumerID.empty()) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREDUPLICATECONSUMERID, eModelWarningLevel::mrwInvalidMandatoryValue); + m_sConsumerID = pAttributeValue; + } + else if (strcmp(XML_3MF_SECURE_CONTENT_KEY_ID, pAttributeName) == 0) { + if (!m_sKeyID.empty()) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREDUPLICATECONSUMERKEYID, eModelWarningLevel::mrwInvalidOptionalValue); + m_sKeyID = pAttributeValue; + } + else + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ATTRIBUTE, mrwInvalidOptionalValue); + } + + void CModelReaderNode_KeyStoreConsumer::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) + { + __NMRASSERT(pChildName); + __NMRASSERT(pXMLReader); + __NMRASSERT(pNameSpace); + + + if (strcmp(pNameSpace, XML_3MF_NAMESPACE_SECURECONTENTSPEC) == 0) { + if (strcmp(pChildName, XML_3MF_ELEMENT_KEYVALUE) == 0) { + PModelReaderNode_StringValue pXMLNode = std::make_shared(m_pWarnings); + pXMLNode->parseXML(pXMLReader); + m_sKeyValue = pXMLNode->getValue(); + } + else + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ELEMENT, mrwInvalidOptionalValue); + } + } + +} diff --git a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreKEKParams.cpp b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreKEKParams.cpp new file mode 100644 index 000000000..b1ac663fe --- /dev/null +++ b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreKEKParams.cpp @@ -0,0 +1,129 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreCipherValue.h defines the Model Reader Node class that is related to . + +--*/ + +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreKEKParams.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_StringUtils.h" + +#include "Libraries/cpp-base64/base64.h" + +namespace NMR { + + namespace ParserUtils { + eKeyStoreWrapAlgorithm parseWrapAlgorithm(std::string const & value, bool & hasMgf1) { + if (XML_3MF_SECURE_CONTENT_KEYWRAPPING_RSA == value) { + hasMgf1 = true; + return eKeyStoreWrapAlgorithm::RSA_OAEP; + } else if (XML_3MF_SECURE_CONTENT_KEYWRAPPING_RSASHORT == value) { + return eKeyStoreWrapAlgorithm::RSA_OAEP; + } + throw CNMRException(NMR_ERROR_KEYSTOREINVALIDALGORITHM); + } + + eKeyStoreMaskGenerationFunction parseMgf(std::string const & value) { + if (XML_3MF_SECURE_CONTENT_MGF1_SHA1 == value) + return eKeyStoreMaskGenerationFunction::MGF1_SHA1; + else if (XML_3MF_SECURE_CONTENT_MGF1_SHA224 == value) + return eKeyStoreMaskGenerationFunction::MGF1_SHA224; + else if (XML_3MF_SECURE_CONTENT_MGF1_SHA256 == value) + return eKeyStoreMaskGenerationFunction::MGF1_SHA256; + else if (XML_3MF_SECURE_CONTENT_MGF1_SHA384 == value) + return eKeyStoreMaskGenerationFunction::MGF1_SHA384; + else if (XML_3MF_SECURE_CONTENT_MGF1_SHA512 == value) + return eKeyStoreMaskGenerationFunction::MGF1_SHA512; + throw CNMRException(NMR_ERROR_KEYSTOREINVALIDMGF); + } + + eKeyStoreMessageDigest parseMessageDigest(std::string const & value) { + if (XML_3MF_SECURE_CONTENT_MD_SHA1 == value) + return eKeyStoreMessageDigest::SHA1; + else if (XML_3MF_SECURE_CONTENT_MD_SHA256 == value) + return eKeyStoreMessageDigest::SHA256; + else if (XML_3MF_SECURE_CONTENT_MD_SHA384 == value) + return eKeyStoreMessageDigest::SHA384; + else if (XML_3MF_SECURE_CONTENT_MD_SHA512 == value) + return eKeyStoreMessageDigest::SHA512; + throw CNMRException(NMR_ERROR_KEYSTOREINVALIDDIGEST); + } + } + + KEKPARAMS CModelReaderNode_KeyStoreKEKParams::getKekParams() + { + return m_sKekParams; + } + + void CModelReaderNode_KeyStoreKEKParams::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + if (!m_bHasAlgorithm) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREMISSINGALGORTHM, eModelWarningLevel::mrwMissingMandatoryValue); + + if (m_bAlgHasMgf && m_sKekParams.m_eMgf != eKeyStoreMaskGenerationFunction::MGF1_SHA1) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREINCONSISTENTKEKPARAMS, eModelWarningLevel::mrwInvalidOptionalValue); + } + + void CModelReaderNode_KeyStoreKEKParams::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + { + __NMRASSERT(pAttributeName); + __NMRASSERT(pAttributeValue); + + try { + if (strcmp(XML_3MF_SECURE_CONTENT_WRAPPINGALGORITHM, pAttributeName) == 0) { + m_bHasAlgorithm = true; + m_sKekParams.m_eAlgorithm = ParserUtils::parseWrapAlgorithm(pAttributeValue, m_bAlgHasMgf); + } else if (strcmp(XML_3MF_SECURE_CONTENT_MGFALGORITHM, pAttributeName) == 0) { + m_sKekParams.m_eMgf = ParserUtils::parseMgf(pAttributeValue); + } else if (strcmp(XML_3MF_SECURE_CONTENT_DIGESTMETHOD, pAttributeName) == 0) { + m_sKekParams.m_eDigest = ParserUtils::parseMessageDigest(pAttributeValue); + } else { + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ATTRIBUTE, mrwInvalidOptionalValue); + } + } + catch (CNMRException const & e) { + m_pWarnings->addException(e, eModelWarningLevel::mrwInvalidMandatoryValue); + } + } + +} diff --git a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceData.cpp b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceData.cpp new file mode 100644 index 000000000..0be40da1f --- /dev/null +++ b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceData.cpp @@ -0,0 +1,102 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreResourceData.h defines the Model Reader Node class that is related to . + +--*/ + +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceData.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreCEKParams.h" +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreFactory.h" +#include "Model/Classes/NMR_PackageResourceID.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_StringUtils.h" + +namespace NMR { + + PKeyStoreResourceData CModelReaderNode_KeyStoreResourceData::getResourceData(PKeyStoreResourceDataGroup const & rdg) + { + PPackageModelPath p = model()->findOrCreateModelPath(m_sPath); + return CKeyStoreFactory::makeResourceData(rdg, p, m_pCekParams); + } + + void CModelReaderNode_KeyStoreResourceData::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + // Parse Content + parseContent(pXMLReader); + + if (m_sPath.empty()) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREMISSINGPATH, eModelWarningLevel::mrwFatal); + if (nullptr == m_pCekParams) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREMISSINGCEKPARAMS, eModelWarningLevel::mrwFatal); + } + + void CModelReaderNode_KeyStoreResourceData::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + { + __NMRASSERT(pAttributeName); + __NMRASSERT(pAttributeValue); + + if (strcmp(XML_3MF_SECURE_CONTENT_PATH, pAttributeName) == 0) { + if (!m_sPath.empty()) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATAPATH, eModelWarningLevel::mrwInvalidMandatoryValue); + m_sPath = pAttributeValue; + } + else + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ATTRIBUTE, mrwInvalidOptionalValue); + } + + void CModelReaderNode_KeyStoreResourceData::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) + { + __NMRASSERT(pChildName); + __NMRASSERT(pXMLReader); + __NMRASSERT(pNameSpace); + + if (strcmp(pNameSpace, XML_3MF_NAMESPACE_SECURECONTENTSPEC) == 0) { + if (strcmp(pChildName, XML_3MF_ELEMENT_CEKPARAMS) == 0) { + if (nullptr == m_pCekParams) { + PModelReaderNode_KeyStoreCEKParams pXMLNode = extractCopy(); + pXMLNode->parseXML(pXMLReader); + m_pCekParams = pXMLNode->getCEKParams(); + } + } + else + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ELEMENT, mrwInvalidOptionalValue); + } + } + +} diff --git a/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceDataGroup.cpp b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceDataGroup.cpp new file mode 100644 index 000000000..21518e9bd --- /dev/null +++ b/Source/Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceDataGroup.cpp @@ -0,0 +1,110 @@ + +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelReaderNode_KeyStoreResourceDataGroup.h defines the Model Reader Node class that is related to . + +--*/ + +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceDataGroup.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreAccessRight.h" +#include "Model/Reader/SecureContent101/NMR_ModelReaderNode_KeyStoreResourceData.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" + +#include "Model/Classes/NMR_KeyStoreFactory.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_StringUtils.h" + +namespace NMR { + + void CModelReaderNode_KeyStoreResourceDataGroup::parseXML(_In_ CXmlReader * pXMLReader) + { + // Parse name + parseName(pXMLReader); + + // Parse attribute + parseAttributes(pXMLReader); + + if (!m_pGroup) { + if (!m_bHasUuid) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREMISSINGKEYUUID, eModelWarningLevel::mrwInvalidMandatoryValue); + m_pGroup = CKeyStoreFactory::makeResourceDataGroup(); + } + + // Parse Content + parseContent(pXMLReader); + + keystore()->addResourceDataGroup(m_pGroup); + } + + void CModelReaderNode_KeyStoreResourceDataGroup::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + { + __NMRASSERT(pAttributeName); + __NMRASSERT(pAttributeValue); + + if (strcmp(XML_3MF_SECURE_CONTENT_KEY_UUID, pAttributeName) == 0) { + m_bHasUuid = true; + if (m_pGroup != nullptr) + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREDUPLICATERESOURCEDATAGROUP, eModelWarningLevel::mrwInvalidMandatoryValue); + try { + m_pGroup = CKeyStoreFactory::makeResourceDataGroup(std::make_shared(pAttributeValue)); + } catch (CNMRException const &) { + m_pWarnings->addWarning(NMR_ERROR_KEYSTOREINVALIDKEYUUID, eModelWarningLevel::mrwInvalidMandatoryValue); + } + } + else + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ATTRIBUTE, mrwInvalidOptionalValue); + } + + void CModelReaderNode_KeyStoreResourceDataGroup::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) + { + __NMRASSERT(pChildName); + __NMRASSERT(pXMLReader); + __NMRASSERT(pNameSpace); + + if (strcmp(pNameSpace, XML_3MF_NAMESPACE_SECURECONTENTSPEC) == 0) { + if (strcmp(pChildName, XML_3MF_ELEMENT_RESOURCEDATA) == 0) { + PModelReaderNode_KeyStoreResourceData pXMLNode = extractCopy(); + pXMLNode->parseXML(pXMLReader); + PKeyStoreResourceData rd = pXMLNode->getResourceData(m_pGroup); + m_pKeyStore->addResourceData(rd); + } else if (strcmp(pChildName, XML_3MF_ELEMENT_ACCESSRIGHT) == 0) { + PModelReaderNode_KeyStoreAccessRight pXMLNode = extractCopy(); + pXMLNode->parseXML(pXMLReader); + PKeyStoreAccessRight ar = pXMLNode->getAccessRight(); + m_pGroup->addAccessRight(ar); + } else + m_pWarnings->addWarning(NMR_ERROR_NAMESPACE_INVALID_ELEMENT, mrwInvalidOptionalValue); + } + } + +} diff --git a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Polygon.cpp b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Polygon.cpp index 0bb222130..a659c5a2f 100644 --- a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Polygon.cpp +++ b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Polygon.cpp @@ -57,7 +57,7 @@ namespace NMR { } } - CModelReaderNode_Slices1507_Polygon::CModelReaderNode_Slices1507_Polygon(_In_ CSlice *pSlice, _In_ PModelReaderWarnings pWarnings) : CModelReaderNode(pWarnings) { + CModelReaderNode_Slices1507_Polygon::CModelReaderNode_Slices1507_Polygon(_In_ CSlice *pSlice, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_pSlice = pSlice; } diff --git a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Segment.cpp b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Segment.cpp index d8ea567bb..dfb7678b6 100644 --- a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Segment.cpp +++ b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Segment.cpp @@ -43,7 +43,7 @@ namespace NMR { } - CModelReaderNode_Slices1507_Segment::CModelReaderNode_Slices1507_Segment(_In_ CSlice *pSlice, nfUint32 nPolygonIndex, _In_ PModelReaderWarnings pWarnings) : CModelReaderNode(pWarnings) { + CModelReaderNode_Slices1507_Segment::CModelReaderNode_Slices1507_Segment(_In_ CSlice *pSlice, nfUint32 nPolygonIndex, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_pSlice = pSlice; m_PolygonIndex = nPolygonIndex; } diff --git a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Slice.cpp b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Slice.cpp index 07c1b0738..21a5b2972 100644 --- a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Slice.cpp +++ b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Slice.cpp @@ -60,7 +60,7 @@ namespace NMR { } } - CModelReaderNode_Slices1507_Slice::CModelReaderNode_Slices1507_Slice(_In_ CModelSliceStack *pSliceStack, _In_ PModelReaderWarnings pWarnings) : CModelReaderNode(pWarnings) { + CModelReaderNode_Slices1507_Slice::CModelReaderNode_Slices1507_Slice(_In_ CModelSliceStack *pSliceStack, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_pSliceStack = pSliceStack; m_bHasZTop = false; } diff --git a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRef.cpp b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRef.cpp index 614a54647..ac99b7c16 100644 --- a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRef.cpp +++ b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRef.cpp @@ -57,7 +57,7 @@ namespace NMR { } - CModelReaderNode_Slice1507_SliceRef::CModelReaderNode_Slice1507_SliceRef(_In_ PModelReaderWarnings pWarnings) : CModelReaderNode(pWarnings) { + CModelReaderNode_Slice1507_SliceRef::CModelReaderNode_Slice1507_SliceRef(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_SliceStackId = -1; m_Path = ""; } diff --git a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefModel.cpp b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefModel.cpp index 85316ef52..0ec26dd3a 100644 --- a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefModel.cpp +++ b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefModel.cpp @@ -55,8 +55,8 @@ namespace NMR { } CModelReader_Slice1507_SliceRefModel::CModelReader_Slice1507_SliceRefModel( - _In_ CModel *pModel, _In_ PModelReaderWarnings pWarnings, _In_z_ std::string sSliceRefPath) - :CModelReaderNode_Model(pModel, pWarnings, sSliceRefPath.c_str(), nullptr) + _In_ CModel *pModel, _In_ PModelWarnings pWarnings, _In_z_ std::string sSliceRefPath) + : CModelReaderNode_ModelBase(pModel, pWarnings, sSliceRefPath.c_str(), nullptr) { m_sSliceRefPath = sSliceRefPath; } diff --git a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefResources.cpp b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefResources.cpp index 339276391..50b3f19c3 100644 --- a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefResources.cpp +++ b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceRefResources.cpp @@ -50,7 +50,7 @@ namespace NMR { } CModelReader_Slice1507_SliceRefResources::CModelReader_Slice1507_SliceRefResources( - _In_ CModel *pModel, _In_ PModelReaderWarnings pWarnings, _In_z_ const std::string sSliceRefPath) + _In_ CModel *pModel, _In_ PModelWarnings pWarnings, _In_z_ const std::string sSliceRefPath) : CModelReaderNode(pWarnings) { m_pModel = pModel; diff --git a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceStack.cpp b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceStack.cpp index eacbc2fb4..42b33cc71 100644 --- a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceStack.cpp +++ b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_SliceStack.cpp @@ -70,20 +70,20 @@ namespace NMR { std::string path = pXmlNode->Path(); if (path.empty()) { - path = m_pModel->curPath(); + path = m_pModel->currentPath(); } PModelResource pResource = m_pModel->findResource(path, pXmlNode->SliceStackId()); PModelSliceStack pSliceStackResource = std::dynamic_pointer_cast(pResource); if (!pSliceStackResource) throw CNMRException(NMR_ERROR_SLICESTACKRESOURCE_NOT_FOUND); - if (!m_pSliceStackResource->OwnPath().empty()) + if (m_pSliceStackResource->OwnPath() != m_pModel->rootPath() ) throw CNMRException(NMR_ERROR_SLICEREFSTOODEEP); m_pSliceStackResource->AddSliceRef(pSliceStackResource); } } CModelReaderNode_Slice1507_SliceStack::CModelReaderNode_Slice1507_SliceStack( - _In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings, + _In_ CModel * pModel, _In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor,_In_ const std::string sSlicePath) : CModelReaderNode(pWarnings, pProgressMonitor) { diff --git a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertex.cpp b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertex.cpp index aeb8ba028..407776117 100644 --- a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertex.cpp +++ b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertex.cpp @@ -48,7 +48,7 @@ namespace NMR { } - CModelReaderNode_Slices1507_Vertex::CModelReaderNode_Slices1507_Vertex(_In_ CSlice *pSlice, _In_ PModelReaderWarnings pWarnings) : CModelReaderNode(pWarnings) { + CModelReaderNode_Slices1507_Vertex::CModelReaderNode_Slices1507_Vertex(_In_ CSlice *pSlice, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_pSlice = pSlice; } diff --git a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertices.cpp b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertices.cpp index 8d77a9032..f7292d168 100644 --- a/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertices.cpp +++ b/Source/Model/Reader/Slice1507/NMR_ModelReader_Slice1507_Vertices.cpp @@ -48,7 +48,7 @@ namespace NMR { m_pWarnings->addException(CNMRException(NMR_ERROR_NAMESPACE_INVALID_ELEMENT), mrwInvalidOptionalValue); } - CModelReaderNode_Slices1507_Vertices::CModelReaderNode_Slices1507_Vertices(_In_ CSlice *pSlice, _In_ PModelReaderWarnings pWarnings) : CModelReaderNode(pWarnings) { + CModelReaderNode_Slices1507_Vertices::CModelReaderNode_Slices1507_Vertices(_In_ CSlice *pSlice, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_pSlice = pSlice; } diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Build.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Build.cpp index 6621decc2..740166b15 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Build.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Build.cpp @@ -41,7 +41,7 @@ A build reader model node is a parser for the build node of an XML Model Stream. namespace NMR { - CModelReaderNode093_Build::CModelReaderNode093_Build(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Build::CModelReaderNode093_Build(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pModel); diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_BuildItem.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_BuildItem.cpp index 169792eed..db3a75aab 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_BuildItem.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_BuildItem.cpp @@ -41,7 +41,7 @@ A builditem reader model node is a parser for the builditem node of an XML Model namespace NMR { - CModelReaderNode093_BuildItem::CModelReaderNode093_BuildItem(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_BuildItem::CModelReaderNode093_BuildItem(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pModel); @@ -66,7 +66,7 @@ namespace NMR { if (!m_bHasID) throw CNMRException(NMR_ERROR_MISSINGBUILDITEMOBJECTID); - PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->curPath(), m_ObjectID); + PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->currentPath(), m_ObjectID); if (!pID.get()) throw CNMRException(NMR_ERROR_COULDNOTFINDBUILDITEMOBJECT); CModelObject * pObject = m_pModel->findObject(pID->getUniqueID()); diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Color.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Color.cpp index 46d63997a..6758f8113 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Color.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Color.cpp @@ -41,7 +41,7 @@ A color reader model node is a parser for the color node of an XML Model Stream. namespace NMR { - CModelReaderNode093_Color::CModelReaderNode093_Color(_In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Color::CModelReaderNode093_Color(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_nResourceID = 0; @@ -130,7 +130,7 @@ namespace NMR { ModelResourceID CModelReaderNode093_Color::retrieveID() { try { - //if (m_nResourceID == 0) + //if (m_nUniqueResourceID == 0) //throw CNMRException(NMR_ERROR_MISSINGMODELCOLORID); } catch (CNMRException & Exception) { diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Component.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Component.cpp index 3ced0a9d9..e103340ef 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Component.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Component.cpp @@ -42,7 +42,7 @@ Node Class. namespace NMR { - CModelReaderNode093_Component::CModelReaderNode093_Component(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Component::CModelReaderNode093_Component(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pModel); @@ -88,7 +88,7 @@ namespace NMR { if (!m_bHasID) throw CNMRException(NMR_ERROR_MISSINGMODELOBJECTID); - PPackageResourceID pRID = m_pModel->findPackageResourceID(m_pModel->curPath(), m_ObjectID); + PPackageResourceID pRID = m_pModel->findPackageResourceID(m_pModel->currentPath(), m_ObjectID); if (pRID.get()) return m_pModel->findObject(pRID->getUniqueID()); return nullptr; diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Components.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Components.cpp index d26c94dd3..6a11a3795 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Components.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Components.cpp @@ -41,7 +41,7 @@ Node Class. namespace NMR { - CModelReaderNode093_Components::CModelReaderNode093_Components(_In_ CModelComponentsObject * pComponentsObject, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Components::CModelReaderNode093_Components(_In_ CModelComponentsObject * pComponentsObject, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pComponentsObject); diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Material.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Material.cpp index 6b4470e63..4cefc2b1d 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Material.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Material.cpp @@ -41,7 +41,7 @@ A material reader model node is a parser for the material node of an XML Model S namespace NMR { - CModelReaderNode093_Material::CModelReaderNode093_Material(_In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Material::CModelReaderNode093_Material(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_nResourceID = 0; diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Mesh.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Mesh.cpp index d39f42fb1..5c06ea689 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Mesh.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Mesh.cpp @@ -43,7 +43,7 @@ A mesh reader model node is a parser for the mesh node of an XML Model Stream. namespace NMR { - CModelReaderNode093_Mesh::CModelReaderNode093_Mesh(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelBaseMaterialResource pMaterialResource, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Mesh::CModelReaderNode093_Mesh(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelBaseMaterialResource pMaterialResource, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pMesh); diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Object.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Object.cpp index 3c2d2597a..14860a039 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Object.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Object.cpp @@ -47,7 +47,7 @@ Stream. namespace NMR { - CModelReaderNode093_Object::CModelReaderNode093_Object(_In_ CModel * pModel, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Object::CModelReaderNode093_Object(_In_ CModel * pModel, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pColorMapping.get() != nullptr); @@ -92,7 +92,7 @@ namespace NMR { // Set Object Type (might fail, if string is invalid) if (m_sType.length() > 0) { if (!m_pObject->setObjectTypeString(m_sType, false)) - m_pWarnings->addWarning(MODELREADERWARNING_INVALIDMODELOBJECTTYPE, NMR_ERROR_INVALIDMODELOBJECTTYPE, mrwInvalidOptionalValue); + m_pWarnings->addWarning(NMR_ERROR_INVALIDMODELOBJECTTYPE, mrwInvalidOptionalValue); } } @@ -164,7 +164,7 @@ namespace NMR { PModelBaseMaterialResource pBaseMaterialResource; if (m_nObjectLevelMaterialID > 0) { // every v93 material becomes its own v100 base material group resource - pBaseMaterialResource = std::dynamic_pointer_cast(m_pModel->findResource(m_pModel->curPath(), m_nObjectLevelMaterialID)); + pBaseMaterialResource = std::dynamic_pointer_cast(m_pModel->findResource(m_pModel->currentPath(), m_nObjectLevelMaterialID)); if (pBaseMaterialResource.get() == nullptr) { m_pWarnings->addException(CNMRException(NMR_ERROR_INVALIDMODELRESOURCE), mrwInvalidOptionalValue); } diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Resources.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Resources.cpp index c43b4f1e2..053721192 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Resources.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Resources.cpp @@ -52,7 +52,7 @@ XML Model Stream. namespace NMR { - CModelReaderNode093_Resources::CModelReaderNode093_Resources(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Resources::CModelReaderNode093_Resources(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pModel); diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Texture.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Texture.cpp index 64a913773..9ae017644 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Texture.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Texture.cpp @@ -44,7 +44,7 @@ NMR_ModelReaderNode093_Texture.cpp implements the Model Reader Texture Class. namespace NMR { - CModelReaderNode093_Texture::CModelReaderNode093_Texture(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Texture::CModelReaderNode093_Texture(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { // Initialize variables diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertex.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertex.cpp index 767d93e2e..3f79b9729 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertex.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertex.cpp @@ -42,7 +42,7 @@ A texture vertex reader model node is a parser for the vertex node of an XML Mod namespace NMR { - CModelReaderNode093_TextureVertex::CModelReaderNode093_TextureVertex(_In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_TextureVertex::CModelReaderNode093_TextureVertex(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_fU = 0.0f; diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertices.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertices.cpp index 9952686d0..32e922ab5 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertices.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_TextureVertices.cpp @@ -42,7 +42,7 @@ XML Model Stream. namespace NMR { - CModelReaderNode093_TextureVertices::CModelReaderNode093_TextureVertices(_In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings, _In_ PModelReader_TexCoordMapping pTexCoordMapping) + CModelReaderNode093_TextureVertices::CModelReaderNode093_TextureVertices(_In_ CMesh * pMesh, _In_ PModelWarnings pWarnings, _In_ PModelReader_TexCoordMapping pTexCoordMapping) : CModelReaderNode(pWarnings) { __NMRASSERT(pMesh); diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Triangle.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Triangle.cpp index 209752c71..a45d0d4ce 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Triangle.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Triangle.cpp @@ -44,7 +44,7 @@ XML Model Stream. namespace NMR { - CModelReaderNode093_Triangle::CModelReaderNode093_Triangle(_In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Triangle::CModelReaderNode093_Triangle(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { // Initialise default values diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Triangles.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Triangles.cpp index 4196bd84c..c498c5823 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Triangles.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Triangles.cpp @@ -44,7 +44,7 @@ XML Model Stream. namespace NMR { - CModelReaderNode093_Triangles::CModelReaderNode093_Triangles(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelReader_TexCoordMapping pTexCoordMapping, _In_ PModelBaseMaterialResource pMaterialResource, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Triangles::CModelReaderNode093_Triangles(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReader_ColorMapping pColorMapping, _In_ PModelReader_TexCoordMapping pTexCoordMapping, _In_ PModelBaseMaterialResource pMaterialResource, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pMesh); @@ -126,7 +126,7 @@ namespace NMR { PModelTexture2DResource pTexture2dResource; // Convert Texture Coordinates to in memory representation - PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->curPath(), nTextureID); + PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->currentPath(), nTextureID); if (pID.get()) { pTexture2dResource = std::dynamic_pointer_cast(m_pModel->findResource(pID->getUniqueID())); } @@ -152,7 +152,7 @@ namespace NMR { pTextureGroup = pSharedTextureGroup.get(); } - pFaceData->m_nResourceID = pTextureGroup->getResourceID()->getUniqueID(); + pFaceData->m_nUniqueResourceID = pTextureGroup->getPackageResourceID()->getUniqueID(); ModelResourceIndex nResourceIndex; MODELTEXTURE2DCOORDINATE sUV; nfFloat fU; @@ -180,7 +180,7 @@ namespace NMR { else { if (nMaterialID > 0) { // every v93 material becomes its own v100 base material group resource - PModelBaseMaterialResource pBaseMaterialResource = std::dynamic_pointer_cast(m_pModel->findResource(m_pModel->curPath(), nMaterialID)); + PModelBaseMaterialResource pBaseMaterialResource = std::dynamic_pointer_cast(m_pModel->findResource(m_pModel->currentPath(), nMaterialID)); if (pBaseMaterialResource.get() != nullptr) { if (!pBaseMaterialResource->hasResourceIndexMap()) pBaseMaterialResource->buildResourceIndexMap(); @@ -188,7 +188,7 @@ namespace NMR { CMeshInformation_Properties * pProperties = createPropertiesInformation(); MESHINFORMATION_PROPERTIES* pFaceData = (MESHINFORMATION_PROPERTIES*)pProperties->getFaceData(pFace->m_index); if (pFaceData) { - pFaceData->m_nResourceID = pBaseMaterialResource->getResourceID()->getUniqueID(); + pFaceData->m_nUniqueResourceID = pBaseMaterialResource->getPackageResourceID()->getUniqueID(); pFaceData->m_nPropertyIDs[0] = 1; pFaceData->m_nPropertyIDs[1] = 1; pFaceData->m_nPropertyIDs[2] = 1; @@ -198,14 +198,14 @@ namespace NMR { if (m_pDefaultMaterialResource != nullptr) { if (!pDefaultData) { pDefaultData = new MESHINFORMATION_PROPERTIES; - pDefaultData->m_nResourceID = 0; + pDefaultData->m_nUniqueResourceID = 0; pDefaultData->m_nPropertyIDs[0] = 1; pDefaultData->m_nPropertyIDs[1] = 1; pDefaultData->m_nPropertyIDs[2] = 1; pProperties->setDefaultData((MESHINFORMATIONFACEDATA*)pDefaultData); } - if (pDefaultData->m_nResourceID == 0) { - pDefaultData->m_nResourceID = m_pDefaultMaterialResource->getResourceID()->getUniqueID(); + if (pDefaultData->m_nUniqueResourceID == 0) { + pDefaultData->m_nUniqueResourceID = m_pDefaultMaterialResource->getPackageResourceID()->getUniqueID(); } } } diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Vertex.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Vertex.cpp index f0c19168f..a7502b5c2 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Vertex.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Vertex.cpp @@ -42,7 +42,7 @@ A vertex reader model node is a parser for the vertex node of an XML Model Strea namespace NMR { - CModelReaderNode093_Vertex::CModelReaderNode093_Vertex(_In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Vertex::CModelReaderNode093_Vertex(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_fX = 0.0f; diff --git a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Vertices.cpp b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Vertices.cpp index 85ce62665..1b5d98540 100644 --- a/Source/Model/Reader/v093/NMR_ModelReaderNode093_Vertices.cpp +++ b/Source/Model/Reader/v093/NMR_ModelReaderNode093_Vertices.cpp @@ -42,7 +42,7 @@ XML Model Stream. namespace NMR { - CModelReaderNode093_Vertices::CModelReaderNode093_Vertices(_In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode093_Vertices::CModelReaderNode093_Vertices(_In_ CMesh * pMesh, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pMesh); diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterial.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterial.cpp index 58bc02576..eb69cece8 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterial.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterial.cpp @@ -41,7 +41,7 @@ NMR_ModelReaderNode100_BaseMaterial.cpp implements the Model Reader Base Materia namespace NMR { - CModelReaderNode100_BaseMaterial::CModelReaderNode100_BaseMaterial(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_BaseMaterial::CModelReaderNode100_BaseMaterial(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterials.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterials.cpp index 69384e65a..3c904985d 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterials.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_BaseMaterials.cpp @@ -45,7 +45,7 @@ NMR_ModelReaderNode100_BaseMaterials.cpp implements the Model Reader Base Materi namespace NMR { - CModelReaderNode100_BaseMaterials::CModelReaderNode100_BaseMaterials(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_BaseMaterials::CModelReaderNode100_BaseMaterials(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { // Initialize variables diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Build.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Build.cpp index f9788a252..c7ae2de5b 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Build.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Build.cpp @@ -41,7 +41,7 @@ A build reader model node is a parser for the build node of an XML Model Stream. namespace NMR { - CModelReaderNode100_Build::CModelReaderNode100_Build(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Build::CModelReaderNode100_Build(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pModel); @@ -60,7 +60,7 @@ namespace NMR { parseContent(pXMLReader); if (!m_UUID.get()) { - if ( (m_pModel->rootPath() == m_pModel->curPath()) + if ( (m_pModel->rootPath() == m_pModel->currentPath()) && (pXMLReader->NamespaceRegistered(XML_3MF_NAMESPACE_PRODUCTIONSPEC)) ) { m_pWarnings->addException(CNMRException(NMR_ERROR_MISSINGUUID), mrwMissingMandatoryValue); diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_BuildItem.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_BuildItem.cpp index e5969503b..702d974d9 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_BuildItem.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_BuildItem.cpp @@ -42,7 +42,7 @@ A builditem reader model node is a parser for the builditem node of an XML Model namespace NMR { - CModelReaderNode100_BuildItem::CModelReaderNode100_BuildItem(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_BuildItem::CModelReaderNode100_BuildItem(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pModel); @@ -73,12 +73,12 @@ namespace NMR { CModelObject * pObject; PPackageResourceID pID; if (m_hasPath) { - if (m_pModel->curPath() != m_pModel->rootPath() ) + if (m_pModel->currentPath() != m_pModel->rootPath() ) throw CNMRException(NMR_ERROR_REFERENCESTOODEEP); pID = m_pModel->findPackageResourceID(m_sPath, m_ObjectID); } else - pID = m_pModel->findPackageResourceID(m_pModel->curPath(), m_ObjectID); + pID = m_pModel->findPackageResourceID(m_pModel->currentPath(), m_ObjectID); if (!pID) throw CNMRException(NMR_ERROR_COULDNOTFINDBUILDITEMOBJECT); @@ -154,6 +154,9 @@ namespace NMR { if (m_hasPath) throw CNMRException(NMR_ERROR_DUPLICATEPATH); m_sPath = std::string(pAttributeValue); + if (!fnStartsWithPathDelimiter(m_sPath)) { + m_pWarnings->addException(CNMRException(NMR_ERROR_PATH_NOT_ABSOLUTE), mrwInvalidOptionalValue); + } m_hasPath = true; } } diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Color.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Color.cpp index 5fb745b2a..e9c3c6ab7 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Color.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Color.cpp @@ -41,7 +41,7 @@ NMR_ModelReaderNode100_Color.cpp implements the Model Reader Color Node Class. namespace NMR { - CModelReaderNode100_Color::CModelReaderNode100_Color(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Color::CModelReaderNode100_Color(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_pModel = pModel; diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Colors.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Colors.cpp index 9716ab7dc..3207bfe20 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Colors.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Colors.cpp @@ -44,7 +44,7 @@ NMR_ModelReaderNode100_Colors.cpp implements the Model Reader Color Group Class. namespace NMR { - CModelReaderNode100_Colors::CModelReaderNode100_Colors(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Colors::CModelReaderNode100_Colors(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { // Initialize variables diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Component.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Component.cpp index 1f79a303c..e7c479ad9 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Component.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Component.cpp @@ -42,7 +42,7 @@ Node Class. namespace NMR { - CModelReaderNode100_Component::CModelReaderNode100_Component(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Component::CModelReaderNode100_Component(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pModel); @@ -78,6 +78,9 @@ namespace NMR { if (m_bHasPath) throw CNMRException(NMR_ERROR_DUPLICATEPATH); m_sPath = pAttributeValue; + if (!fnStartsWithPathDelimiter(m_sPath)) { + m_pWarnings->addException(CNMRException(NMR_ERROR_PATH_NOT_ABSOLUTE), mrwInvalidOptionalValue); + } m_bHasPath = true; } else if (strcmp(pAttributeName, XML_3MF_PRODUCTION_UUID) == 0) { @@ -119,12 +122,12 @@ namespace NMR { PPackageResourceID pRID; if (m_bHasPath) { - if (m_pModel->curPath() != m_pModel->rootPath()) + if (m_pModel->currentPath() != m_pModel->rootPath()) throw CNMRException(NMR_ERROR_REFERENCESTOODEEP); pRID = m_pModel->findPackageResourceID(m_sPath, m_ObjectID); } else { - pRID = m_pModel->findPackageResourceID(m_pModel->curPath(), m_ObjectID); + pRID = m_pModel->findPackageResourceID(m_pModel->currentPath(), m_ObjectID); } if (pRID.get()) return m_pModel->findObject(pRID->getUniqueID()); diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Components.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Components.cpp index a3031aaa3..9ea51779c 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Components.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Components.cpp @@ -41,7 +41,7 @@ Node Class. namespace NMR { - CModelReaderNode100_Components::CModelReaderNode100_Components(_In_ CModelComponentsObject * pComponentsObject, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Components::CModelReaderNode100_Components(_In_ CModelComponentsObject * pComponentsObject, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pComponentsObject); diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Composite.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Composite.cpp index 33aa54c35..a63e385a7 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Composite.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Composite.cpp @@ -41,7 +41,7 @@ NMR_ModelReaderNode100_Color.cpp implements the Model Reader Color Node Class. namespace NMR { - CModelReaderNode100_Composite::CModelReaderNode100_Composite(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings, + CModelReaderNode100_Composite::CModelReaderNode100_Composite(_In_ CModel * pModel, _In_ PModelWarnings pWarnings, _In_z_ const std::vector& baseMaterialPropertyIds) : CModelReaderNode(pWarnings), m_vctBaseMaterialPropertyIds(baseMaterialPropertyIds) { diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_CompositeMaterials.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_CompositeMaterials.cpp index f547e573d..774b250ac 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_CompositeMaterials.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_CompositeMaterials.cpp @@ -44,7 +44,7 @@ NMR_ModelReaderNode100_CompositeMaterials.cpp implements the Model Reader Compos namespace NMR { - CModelReaderNode100_CompositeMaterials::CModelReaderNode100_CompositeMaterials(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_CompositeMaterials::CModelReaderNode100_CompositeMaterials(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { // Initialize variables @@ -69,11 +69,11 @@ namespace NMR { if (m_nBaseMaterialID == 0) throw CNMRException(NMR_ERROR_MISSINGMODELRESOURCEID); - PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->curPath(), m_nBaseMaterialID); + PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->currentPath(), m_nBaseMaterialID); if (!pID) throw CNMRException(NMR_ERROR_INVALIDMODELRESOURCE); - PModelBaseMaterialResource pBaseMaterial = m_pModel->findBaseMaterial(pID->getUniqueID()); + PModelBaseMaterialResource pBaseMaterial = m_pModel->findBaseMaterial(pID); // Create Resource m_pCompositeMaterials = std::make_shared(m_nID, m_pModel, pBaseMaterial); diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.cpp index 3d5e6a3af..16d2fcc23 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.cpp @@ -43,13 +43,14 @@ A mesh reader model node is a parser for the mesh node of an XML Model Stream. namespace NMR { - CModelReaderNode100_Mesh::CModelReaderNode100_Mesh(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor, _In_ ModelResourceID nDefaultPropertyID, _In_ ModelResourceIndex nDefaultPropertyIndex) + CModelReaderNode100_Mesh::CModelReaderNode100_Mesh(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelWarnings pWarnings, + _In_ PProgressMonitor pProgressMonitor, _In_ PPackageResourceID pObjectLevelPropertyID, _In_ ModelResourceIndex nDefaultPropertyIndex) : CModelReaderNode(pWarnings, pProgressMonitor) { __NMRASSERT(pMesh); __NMRASSERT(pModel); - m_nObjectLevelPropertyID = nDefaultPropertyID; + m_pObjectLevelPropertyID = pObjectLevelPropertyID; m_nObjectLevelPropertyIndex = nDefaultPropertyIndex; m_pMesh = pMesh; @@ -116,15 +117,17 @@ namespace NMR { m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_READMESH); m_pProgressMonitor->ReportProgressAndQueryCancelled(true); } - PModelReaderNode100_Triangles pXMLNode = std::make_shared(m_pModel, m_pMesh, m_pWarnings, m_nObjectLevelPropertyID, m_nObjectLevelPropertyIndex); + PModelReaderNode100_Triangles pXMLNode = std::make_shared(m_pModel, m_pMesh, m_pWarnings, + m_pObjectLevelPropertyID, m_nObjectLevelPropertyIndex); pXMLNode->parseXML(pXMLReader); - if (m_nObjectLevelPropertyID == 0) { + if (m_pObjectLevelPropertyID && m_pObjectLevelPropertyID->getPackageModelPath() == 0) { // warn, if object does not have an object-level property, but a triangle has one if (pXMLNode->getUsedPropertyID() != 0) { m_pWarnings->addException(CNMRException(NMR_ERROR_MISSINGOBJECTLEVELPID), mrwMissingMandatoryValue); } // Try and define an object-level property as some PropertyID used by a triangle in the meshobject - m_nObjectLevelPropertyID = pXMLNode->getUsedPropertyID(); + ModelResourceID nObjectLevelPropertyID = pXMLNode->getUsedPropertyID(); + m_pObjectLevelPropertyID = m_pModel->findPackageResourceID(m_pModel->currentPath(), nObjectLevelPropertyID); m_nObjectLevelPropertyIndex = 0; } } @@ -141,6 +144,7 @@ namespace NMR { pXMLNode->retrieveClippingInfo(m_eClipMode, m_bHasClippingMeshID, m_nClippingMeshID); pXMLNode->retrieveRepresentationInfo(m_bHasRepresentationMeshID, m_nRepresentationMeshID); + pXMLNode->validateBallOptions(m_pWarnings); } else m_pWarnings->addException(CNMRException(NMR_ERROR_NAMESPACE_INVALID_ELEMENT), mrwInvalidOptionalValue); diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_MetaData.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_MetaData.cpp index 875bab38e..8916afb98 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_MetaData.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_MetaData.cpp @@ -41,7 +41,7 @@ of an XML Model Stream. namespace NMR { - CModelReaderNode100_MetaData::CModelReaderNode100_MetaData(_In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_MetaData::CModelReaderNode100_MetaData(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_sKey = ""; diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_MetaDataGroup.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_MetaDataGroup.cpp index 128b1ddcd..4f26023d6 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_MetaDataGroup.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_MetaDataGroup.cpp @@ -41,7 +41,7 @@ of an XML Model Stream. namespace NMR { - CModelReaderNode100_MetaDataGroup::CModelReaderNode100_MetaDataGroup(_In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_MetaDataGroup::CModelReaderNode100_MetaDataGroup(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_MetaDataGroup = std::make_shared(); @@ -74,29 +74,31 @@ namespace NMR { if (!sKey.empty()) { if (m_MetaDataGroup->hasMetaData(sKey)) { - m_pWarnings->addWarning(MODELREADERWARNING_DUPLICATEMETADATA, NMR_ERROR_DUPLICATEMETADATA, mrwInvalidOptionalValue); - } - std::string sNameSpace, sName; - CModelMetaData::decomposeKeyIntoNamespaceAndName(sKey, sNameSpace, sName); - if (!sNameSpace.empty()) { - std::string sNameSpaceURI; - if (!pXMLReader->GetNamespaceURI(sNameSpace, sNameSpaceURI)) { - m_pWarnings->addException(CNMRException(NMR_ERROR_METADATA_COULDNOTGETNAMESPACE), mrwInvalidOptionalValue); - sNameSpaceURI = sNameSpace; - } - m_MetaDataGroup->addMetaData(sNameSpaceURI, sName, sValue, sType, bPreserve); + m_pWarnings->addWarning(NMR_ERROR_DUPLICATEMETADATA, mrwInvalidOptionalValue); } else { - // default namespace - if (CModelMetaData::isValidNamespaceAndName("", sName)) { - m_MetaDataGroup->addMetaData("", sName, sValue, sType, bPreserve); + std::string sNameSpace, sName; + decomposeKeyIntoNamespaceAndName(sKey, sNameSpace, sName); + if (!sNameSpace.empty()) { + std::string sNameSpaceURI; + if (!pXMLReader->GetNamespaceURI(sNameSpace, sNameSpaceURI)) { + m_pWarnings->addException(CNMRException(NMR_ERROR_METADATA_COULDNOTGETNAMESPACE), mrwInvalidOptionalValue); + sNameSpaceURI = sNameSpace; + } + m_MetaDataGroup->addMetaData(sNameSpaceURI, sName, sValue, sType, bPreserve); + } + else { + // default namespace + if (CModelMetaData::isValidNamespaceAndName("", sName)) { + m_MetaDataGroup->addMetaData("", sName, sValue, sType, bPreserve); + } + else + m_pWarnings->addException(CNMRException(NMR_ERROR_UNKNOWNMETADATA), mrwInvalidOptionalValue); } - else - m_pWarnings->addException(CNMRException(NMR_ERROR_UNKNOWNMETADATA), mrwInvalidOptionalValue); } } else { - m_pWarnings->addWarning(MODELREADERWARNING_INVALIDMETADATA, NMR_ERROR_INVALIDMETADATA, mrwInvalidOptionalValue); + m_pWarnings->addWarning(NMR_ERROR_INVALIDMETADATA, mrwInvalidOptionalValue); } } } diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Multi.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Multi.cpp index d18637ebb..a70898639 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Multi.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Multi.cpp @@ -41,7 +41,7 @@ NMR_ModelReaderNode100_Multi.cpp implements the Model Reader Multi Node Class. namespace NMR { - CModelReaderNode100_Multi::CModelReaderNode100_Multi(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Multi::CModelReaderNode100_Multi(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_pModel = pModel; diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_MultiProperties.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_MultiProperties.cpp index 659fd79f1..3d24fdbcb 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_MultiProperties.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_MultiProperties.cpp @@ -43,7 +43,7 @@ NMR_ModelReaderNode100_MultiProperties.cpp implements the Model Reader MultiProp namespace NMR { - CModelReaderNode100_MultiProperties::CModelReaderNode100_MultiProperties(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_MultiProperties::CModelReaderNode100_MultiProperties(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { // Initialize variables @@ -80,7 +80,7 @@ namespace NMR { } for (int i = 0; i < m_pPIDs->size(); i++) { - PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->curPath(), (*m_pPIDs)[i]); + PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->currentPath(), (*m_pPIDs)[i]); if (!pID) throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); @@ -101,7 +101,7 @@ namespace NMR { m_pModel->addResource(m_pMultiPropertyGroup); for (auto layer : vctLayers) { - PModelResource pResource = m_pModel->findResource(layer.m_nResourceID); + PModelResource pResource = m_pModel->findResource(layer.m_nUniqueResourceID); if (!pResource) { throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); } @@ -172,7 +172,7 @@ namespace NMR { PModelMultiProperty pMultiProperty = std::make_shared(nLayers); for (nfUint32 iLayer=0; iLayer < nLayers; iLayer++) { - PModelResource pResource = m_pModel->findResource(m_pMultiPropertyGroup->getLayer(iLayer).m_nResourceID); + PModelResource pResource = m_pModel->findResource(m_pMultiPropertyGroup->getLayer(iLayer).m_nUniqueResourceID); if (!pResource) { throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); } diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Object.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Object.cpp index 763a014f3..ec7808c5d 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Object.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Object.cpp @@ -48,7 +48,7 @@ Stream. namespace NMR { - CModelReaderNode100_Object::CModelReaderNode100_Object(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor) + CModelReaderNode100_Object::CModelReaderNode100_Object(_In_ CModel * pModel, _In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor) : CModelReaderNode(pWarnings, pProgressMonitor) { // Initialize variables @@ -65,7 +65,7 @@ namespace NMR { m_bHasThumbnail = false; m_bHasDefaultPropertyID = false; m_bHasDefaultPropertyIndex = false; - m_nObjectLevelPropertyID = 0; + m_nObjectLevelPropertyModelID = 0; m_nObjectLevelPropertyIndex = 0; m_nSliceStackId = 0; @@ -85,6 +85,10 @@ namespace NMR { if (m_nID == 0) throw CNMRException(NMR_ERROR_MISSINGMODELOBJECTID); + if (m_nObjectLevelPropertyModelID != 0) { + m_pObjectLevelPropertyID = m_pModel->findPackageResourceID(m_pModel->currentPath(), m_nObjectLevelPropertyModelID); + } + // Parse Content parseContent(pXMLReader); @@ -164,7 +168,7 @@ namespace NMR { if (m_bHasDefaultPropertyID) throw CNMRException(NMR_ERROR_DUPLICATEPID); m_bHasDefaultPropertyID = true; - m_nObjectLevelPropertyID = fnStringToUint32(pAttributeValue); + m_nObjectLevelPropertyModelID = fnStringToUint32(pAttributeValue); } if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_OBJECT_PINDEX) == 0) { @@ -184,12 +188,12 @@ namespace NMR { if (strcmp(XML_3MF_NAMESPACE_SLICESPEC, pNameSpace) == 0) { if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_OBJECT_SLICESTACKID) == 0) { if (m_nSliceStackId != 0) - m_pWarnings->addException(CNMRException(NMR_ERROR_DUPLICATE_SLICESTACKID), eModelReaderWarningLevel::mrwInvalidOptionalValue); + m_pWarnings->addException(CNMRException(NMR_ERROR_DUPLICATE_SLICESTACKID), eModelWarningLevel::mrwInvalidOptionalValue); m_nSliceStackId = fnStringToUint32(pAttributeValue); } else if (strcmp(pAttributeName, XML_3MF_ATTRIBUTE_OBJECT_MESHRESOLUTION) == 0) { if (m_bHasMeshResolution) - m_pWarnings->addException(CNMRException(NMR_ERROR_DUPLICATE_MESHRESOLUTION), eModelReaderWarningLevel::mrwInvalidOptionalValue); + m_pWarnings->addException(CNMRException(NMR_ERROR_DUPLICATE_MESHRESOLUTION), eModelWarningLevel::mrwInvalidOptionalValue); m_bHasMeshResolution = true; if (strcmp(pAttributeValue, XML_3MF_VALUE_OBJECT_MESHRESOLUTION_FULL)==0) { m_eSlicesMeshResolution = MODELSLICESMESHRESOLUTION_FULL; @@ -198,7 +202,7 @@ namespace NMR { m_eSlicesMeshResolution = MODELSLICESMESHRESOLUTION_LOW; } else - m_pWarnings->addException(CNMRException(NMR_ERROR_INVALID_MESHRESOLUTION), eModelReaderWarningLevel::mrwInvalidOptionalValue); + m_pWarnings->addException(CNMRException(NMR_ERROR_INVALID_MESHRESOLUTION), eModelWarningLevel::mrwInvalidOptionalValue); } else m_pWarnings->addException(CNMRException(NMR_ERROR_NAMESPACE_INVALID_ATTRIBUTE), mrwInvalidOptionalValue); @@ -208,7 +212,7 @@ namespace NMR { if (strcmp(XML_3MF_NAMESPACE_PRODUCTIONSPEC, pNameSpace) == 0) { if (strcmp(XML_3MF_PRODUCTION_UUID, pAttributeName) == 0) { if (m_UUID.get()) - m_pWarnings->addException(CNMRException(NMR_ERROR_DUPLICATEUUID), eModelReaderWarningLevel::mrwInvalidMandatoryValue); + m_pWarnings->addException(CNMRException(NMR_ERROR_DUPLICATEUUID), eModelWarningLevel::mrwInvalidMandatoryValue); m_UUID = std::make_shared(pAttributeValue); } else @@ -236,11 +240,12 @@ namespace NMR { // Set Object Type (might fail, if string is invalid) if (m_bHasType) { if (!m_pObject->setObjectTypeString(m_sType, false)) - m_pWarnings->addWarning(MODELREADERWARNING_INVALIDMODELOBJECTTYPE, NMR_ERROR_INVALIDMODELOBJECTTYPE, mrwInvalidOptionalValue); + m_pWarnings->addWarning(NMR_ERROR_INVALIDMODELOBJECTTYPE, mrwInvalidOptionalValue); } // Read Mesh - PModelReaderNode100_Mesh pXMLNode = std::make_shared(m_pModel, pMesh.get(), m_pWarnings, m_pProgressMonitor, m_nObjectLevelPropertyID, m_nObjectLevelPropertyIndex); + PModelReaderNode100_Mesh pXMLNode = std::make_shared(m_pModel, pMesh.get(), + m_pWarnings, m_pProgressMonitor, m_pObjectLevelPropertyID, m_nObjectLevelPropertyIndex); pXMLNode->parseXML(pXMLReader); // Add Object to Parent @@ -264,7 +269,7 @@ namespace NMR { // Set Object Type (might fail, if string is invalid) if (m_bHasType) { if (!m_pObject->setObjectTypeString(m_sType, false)) - m_pWarnings->addWarning(MODELREADERWARNING_INVALIDMODELOBJECTTYPE, NMR_ERROR_INVALIDMODELOBJECTTYPE, mrwInvalidOptionalValue); + m_pWarnings->addWarning(NMR_ERROR_INVALIDMODELOBJECTTYPE, mrwInvalidOptionalValue); } // Read Components @@ -274,7 +279,7 @@ namespace NMR { // Add Object to Parent m_pModel->addResource(m_pObject); - if (m_nObjectLevelPropertyID != 0) + if (m_nObjectLevelPropertyIndex != 0) m_pWarnings->addException(CNMRException(NMR_ERROR_OBJECTLEVELPID_ON_COMPONENTSOBJECT), mrwInvalidOptionalValue); } else if (strcmp(pChildName, XML_3MF_ELEMENT_METADATAGROUP) == 0) { @@ -291,10 +296,10 @@ namespace NMR { // In any case (component object or mesh object) if ( (m_pObject) && (m_nSliceStackId > 0) ) { - PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->curPath(), m_nSliceStackId); + PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->currentPath(), m_nSliceStackId); if (!pID.get()) throw CNMRException(NMR_ERROR_SLICESTACKRESOURCE_NOT_FOUND); - PModelSliceStack pSliceStackResource = std::dynamic_pointer_cast(m_pModel->findResource(pID->getUniqueID()) ); + PModelSliceStack pSliceStackResource = std::dynamic_pointer_cast(m_pModel->findResource(pID) ); if (pSliceStackResource) { if ((m_pObject->getObjectType() == MODELOBJECTTYPE_MODEL) || (MODELOBJECTTYPE_SOLIDSUPPORT)) { if (!pSliceStackResource->areAllPolygonsClosed()) { @@ -319,14 +324,14 @@ namespace NMR { if (m_pObject.get() == nullptr) return; - if (m_nObjectLevelPropertyID != 0) { + if (m_bHasDefaultPropertyIndex && m_bHasDefaultPropertyID) { CModelMeshObject* pMeshObject = dynamic_cast(m_pObject.get()); if (pMeshObject) { CMesh * pMesh = pMeshObject->getMesh(); if (pMesh) { // Assign Default Resource Property - PModelResource pResource = m_pModel->findResource(m_pModel->curPath(), m_nObjectLevelPropertyID); + PModelResource pResource = m_pModel->findResource(m_pModel->currentPath(), m_nObjectLevelPropertyModelID); if (pResource.get() == nullptr) { throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); } @@ -345,7 +350,7 @@ namespace NMR { ModelResourceID pPropertyID; if (pResource->mapResourceIndexToPropertyID(m_nObjectLevelPropertyIndex, pPropertyID)) { NMR::MESHINFORMATION_PROPERTIES * pDefaultData = new NMR::MESHINFORMATION_PROPERTIES; - pDefaultData->m_nResourceID = pResource->getResourceID()->getUniqueID(); + pDefaultData->m_nUniqueResourceID = pResource->getPackageResourceID()->getUniqueID(); pDefaultData->m_nPropertyIDs[0] = pPropertyID; pDefaultData->m_nPropertyIDs[1] = pPropertyID; pDefaultData->m_nPropertyIDs[2] = pPropertyID; @@ -378,20 +383,20 @@ namespace NMR { pXMLNode->retrieveClippingInfo(eClipMode, bHasClippingMeshID, nClippingMeshID); if (bHasClippingMeshID) { - PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->curPath(), nClippingMeshID); + PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->currentPath(), nClippingMeshID); if (!pID.get()) { - m_pWarnings->addWarning(MODELREADERWARNING_BEAMLATTICECLIPPINGRESOURCENOTDEFINED, NMR_ERROR_BEAMLATTICECLIPPINGRESOURCENOTDEFINED, mrwInvalidMandatoryValue); + m_pWarnings->addWarning(NMR_ERROR_BEAMLATTICECLIPPINGRESOURCENOTDEFINED, mrwInvalidMandatoryValue); } else { CModelObject * pModelObject = m_pModel->findObject(pID->getUniqueID()); if (pModelObject) { pMeshObject->getBeamLatticeAttributes()->m_bHasClippingMeshID = bHasClippingMeshID; - pMeshObject->getBeamLatticeAttributes()->m_nClippingMeshID = pID; + pMeshObject->getBeamLatticeAttributes()->m_pClippingMeshUniqueID = pID; pMeshObject->getBeamLatticeAttributes()->m_eClipMode = eClipMode; } else { pMeshObject->getBeamLatticeAttributes()->m_bHasClippingMeshID = false; - m_pWarnings->addWarning(MODELREADERWARNING_BEAMLATTICECLIPPINGRESOURCENOTDEFINED, NMR_ERROR_BEAMLATTICECLIPPINGRESOURCENOTDEFINED, mrwInvalidMandatoryValue); + m_pWarnings->addWarning(NMR_ERROR_BEAMLATTICECLIPPINGRESOURCENOTDEFINED, mrwInvalidMandatoryValue); } } } @@ -400,19 +405,19 @@ namespace NMR { ModelResourceID nRepresentationMeshID; pXMLNode->retrieveRepresentationInfo(bHasRepresentationMeshID, nRepresentationMeshID); if (nRepresentationMeshID) { - PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->curPath(), nRepresentationMeshID); + PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->currentPath(), nRepresentationMeshID); if (!pID.get()) { - m_pWarnings->addWarning(MODELREADERWARNING_BEAMLATTICEREPRESENTATIONRESOURCENOTDEFINED, NMR_ERROR_BEAMLATTICE_INVALID_REPRESENTATIONRESOURCE, mrwInvalidMandatoryValue); + m_pWarnings->addWarning(NMR_ERROR_BEAMLATTICE_INVALID_REPRESENTATIONRESOURCE, mrwInvalidMandatoryValue); } else { CModelObject * pModelObject = m_pModel->findObject(pID->getUniqueID()); if (pModelObject) { pMeshObject->getBeamLatticeAttributes()->m_bHasRepresentationMeshID = bHasRepresentationMeshID; - pMeshObject->getBeamLatticeAttributes()->m_nRepresentationID = pID; + pMeshObject->getBeamLatticeAttributes()->m_pRepresentationUniqueID = pID; } else { pMeshObject->getBeamLatticeAttributes()->m_bHasRepresentationMeshID = false; - m_pWarnings->addWarning(MODELREADERWARNING_BEAMLATTICEREPRESENTATIONRESOURCENOTDEFINED, NMR_ERROR_BEAMLATTICE_INVALID_REPRESENTATIONRESOURCE, mrwInvalidMandatoryValue); + m_pWarnings->addWarning(NMR_ERROR_BEAMLATTICE_INVALID_REPRESENTATIONRESOURCE, mrwInvalidMandatoryValue); } } } diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Resources.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Resources.cpp index 32969eb8a..fa23352de 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Resources.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Resources.cpp @@ -49,7 +49,7 @@ XML Model Stream. namespace NMR { - CModelReaderNode100_Resources::CModelReaderNode100_Resources(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings, _In_z_ const std::string sPath, + CModelReaderNode100_Resources::CModelReaderNode100_Resources(_In_ CModel * pModel, _In_ PModelWarnings pWarnings, _In_z_ const std::string sPath, _In_ PProgressMonitor pProgressMonitor) : CModelReaderNode(pWarnings, pProgressMonitor) { diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Tex2Coord.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Tex2Coord.cpp index d78a2c6ec..caf12c0bf 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Tex2Coord.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Tex2Coord.cpp @@ -41,7 +41,7 @@ NMR_ModelReaderNode100_Tex2Coord.cpp implements the Model Reader Tex2Coord Node namespace NMR { - CModelReaderNode100_Tex2Coord::CModelReaderNode100_Tex2Coord(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Tex2Coord::CModelReaderNode100_Tex2Coord(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Tex2DGroup.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Tex2DGroup.cpp index 1a1b44e25..c61f0da91 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Tex2DGroup.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Tex2DGroup.cpp @@ -44,7 +44,7 @@ NMR_ModelReaderNode100_Colors.cpp implements the Model Reader Color Group Class. namespace NMR { - CModelReaderNode100_Tex2DGroup::CModelReaderNode100_Tex2DGroup(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Tex2DGroup::CModelReaderNode100_Tex2DGroup(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { // Initialize variables @@ -69,7 +69,7 @@ namespace NMR { if (m_nTextureID == 0) throw CNMRException(NMR_ERROR_MISSINGMODELRESOURCEID); - PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->curPath(), m_nTextureID); + PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->currentPath(), m_nTextureID); if (!pID) throw CNMRException(NMR_ERROR_INVALIDMODELRESOURCE); diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Texture2D.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Texture2D.cpp index 735f932da..672785e88 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Texture2D.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Texture2D.cpp @@ -44,7 +44,7 @@ NMR_ModelReaderNode100_Texture2D.cpp implements the Model Reader Texture2D Class namespace NMR { - CModelReaderNode100_Texture2D::CModelReaderNode100_Texture2D(_In_ CModel * pModel, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Texture2D::CModelReaderNode100_Texture2D(_In_ CModel * pModel, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { // Initialize variables diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Triangle.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Triangle.cpp index 80ab22d8d..eeb5c61e0 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Triangle.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Triangle.cpp @@ -43,7 +43,7 @@ XML Model Stream. namespace NMR { - CModelReaderNode100_Triangle::CModelReaderNode100_Triangle(_In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Triangle::CModelReaderNode100_Triangle(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { // Initialise default values diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Triangles.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Triangles.cpp index b9937a24c..85cea0e19 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Triangles.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Triangles.cpp @@ -43,13 +43,14 @@ XML Model Stream. namespace NMR { - CModelReaderNode100_Triangles::CModelReaderNode100_Triangles(_In_ CModel * pModel, _In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings, _In_ ModelResourceID nDefaultPropertyID, _In_ ModelResourceIndex nDefaultPropertyIndex) + CModelReaderNode100_Triangles::CModelReaderNode100_Triangles(_In_ CModel * pModel, _In_ CMesh * pMesh, + _In_ PModelWarnings pWarnings, _In_ PPackageResourceID pObjectLevelPropertyID, _In_ ModelResourceIndex nDefaultPropertyIndex) : CModelReaderNode(pWarnings) { __NMRASSERT(pMesh); __NMRASSERT(pModel); - m_nDefaultResourceID = nDefaultPropertyID; + m_pObjectLevelPropertyID = pObjectLevelPropertyID; m_nDefaultResourceIndex = nDefaultPropertyIndex; m_nUsedResourceID = 0; @@ -121,16 +122,18 @@ namespace NMR { MESHNODE * pNode3 = m_pMesh->getNode(nIndex3); MESHFACE * pFace = m_pMesh->addFace(pNode1, pNode2, pNode3); - ModelResourceID nResourceID = m_nDefaultResourceID; + ModelResourceID nModelResourceID = 0; + if (m_pObjectLevelPropertyID) + nModelResourceID = m_pObjectLevelPropertyID->getModelResourceID(); ModelResourceIndex nResourceIndex1 = m_nDefaultResourceIndex; ModelResourceIndex nResourceIndex2 = m_nDefaultResourceIndex; ModelResourceIndex nResourceIndex3 = m_nDefaultResourceIndex; - if (pXMLNode->retrieveProperties(nResourceID, nResourceIndex1, nResourceIndex2, nResourceIndex3) || (nResourceID != 0)) { + if (pXMLNode->retrieveProperties(nModelResourceID, nResourceIndex1, nResourceIndex2, nResourceIndex3) || (nModelResourceID != 0)) { // set potential default properties (i.e. used pid) - m_nUsedResourceID = nResourceID; + m_nUsedResourceID = nModelResourceID; - PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->curPath(), nResourceID); + PPackageResourceID pID = m_pModel->findPackageResourceID(m_pModel->currentPath(), nModelResourceID); if (pID.get()) { // Find and Assign Resource of this Property PModelResource pResource = m_pModel->findResource(pID->getUniqueID()); @@ -138,17 +141,17 @@ namespace NMR { if (!pResource->hasResourceIndexMap()) pResource->buildResourceIndexMap(); - ModelResourceID pPropertyID1; - ModelResourceID pPropertyID2; - ModelResourceID pPropertyID3; - if (pResource->mapResourceIndexToPropertyID (nResourceIndex1, pPropertyID1) + ModelPropertyID pPropertyID1; + ModelPropertyID pPropertyID2; + ModelPropertyID pPropertyID3; + if (pResource->mapResourceIndexToPropertyID(nResourceIndex1, pPropertyID1) && pResource->mapResourceIndexToPropertyID(nResourceIndex2, pPropertyID2) && pResource->mapResourceIndexToPropertyID(nResourceIndex3, pPropertyID3)) { CMeshInformation_Properties * pProperties = createPropertiesInformation(); MESHINFORMATION_PROPERTIES* pFaceData = (MESHINFORMATION_PROPERTIES*)pProperties->getFaceData(pFace->m_index); if (pFaceData) { - pFaceData->m_nResourceID = pID->getUniqueID(); + pFaceData->m_nUniqueResourceID = pID->getUniqueID(); pFaceData->m_nPropertyIDs[0] = pPropertyID1; pFaceData->m_nPropertyIDs[1] = pPropertyID2; pFaceData->m_nPropertyIDs[2] = pPropertyID3; diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Vertex.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Vertex.cpp index 69ad14f97..797e782e6 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Vertex.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Vertex.cpp @@ -42,7 +42,7 @@ A vertex reader model node is a parser for the vertex node of an XML Model Strea namespace NMR { - CModelReaderNode100_Vertex::CModelReaderNode100_Vertex(_In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Vertex::CModelReaderNode100_Vertex(_In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { m_fX = 0.0f; diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Vertices.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Vertices.cpp index d721b7e89..b3a020152 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Vertices.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Vertices.cpp @@ -42,7 +42,7 @@ XML Model Stream. namespace NMR { - CModelReaderNode100_Vertices::CModelReaderNode100_Vertices(_In_ CMesh * pMesh, _In_ PModelReaderWarnings pWarnings) + CModelReaderNode100_Vertices::CModelReaderNode100_Vertices(_In_ CMesh * pMesh, _In_ PModelWarnings pWarnings) : CModelReaderNode(pWarnings) { __NMRASSERT(pMesh); diff --git a/Source/Model/Writer/NMR_KeyStoreOpcPackageWriter.cpp b/Source/Model/Writer/NMR_KeyStoreOpcPackageWriter.cpp new file mode 100644 index 000000000..a61a9d7bd --- /dev/null +++ b/Source/Model/Writer/NMR_KeyStoreOpcPackageWriter.cpp @@ -0,0 +1,234 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_OpcPackageWriter.cpp defines an OPC Package writer in a portable way. + +--*/ + +#include "Common/NMR_Exception.h" +#include "Common/NMR_StringUtils.h" + +#include "Model/Classes/NMR_ModelConstants.h" +#include "Common/NMR_ErrorConst.h" +#include "Model/Writer/NMR_KeyStoreOpcPackageWriter.h" +#include "Model/Writer/SecureContent101/NMR_ModelWriterNode_KeyStore.h" +#include "Common/Platform/NMR_ExportStream_Compressed.h" +#include "Common/Platform/NMR_XmlWriter_Native.h" +#include "Common/OPC/NMR_OpcPackageWriter.h" +#include "Model/Classes/NMR_Model.h" +#include "Model/Classes/NMR_ModelContext.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreAccessRight.h" +#include "Model/Classes/NMR_KeyStoreResourceDataGroup.h" +#include "Common/NMR_SecureContext.h" +#include "Common/NMR_SecureContentTypes.h" +#include "Common/Platform/NMR_ExportStream_Encrypted.h" +#include "Common/Platform/NMR_ImportStream_Encrypted.h" +#include "Common/Platform/NMR_ExportStream.h" +#include "Common/NMR_ModelWarnings.h" +#include "Model/Classes/NMR_KeyStoreFactory.h" + +namespace NMR { + + + CKeyStoreOpcPackageWriter::CKeyStoreOpcPackageWriter(_In_ PExportStream pImportStream, _In_ CModelContext const & context) + :m_pContext(context) + { + if (!context.isComplete()) + throw CNMRException(NMR_ERROR_INVALIDPOINTER); + + m_pPackageWriter = std::make_shared(pImportStream); + refreshAllResourceDataGroups(); + } + + void CKeyStoreOpcPackageWriter::refreshAllResourceDataGroups() { + PKeyStore const & keyStore = m_pContext.keyStore(); + for (nfUint64 i = 0; i < keyStore->getResourceDataGroupCount(); ++i) { + PKeyStoreResourceDataGroup rdg = keyStore->getResourceDataGroup(i); + if (rdg->isOpen()) { + for (nfUint64 j = 0; j < rdg->getAccessRightCount(); ++j) { + PKeyStoreAccessRight ar = rdg->getAccessRight(j); + refreshAccessRight(ar, rdg->getKey()); + } + } + } + + PModel const & model = m_pContext.model(); + if (!model->hasCryptoRandCallbak()) + m_pContext.warnings()->addWarning(NMR_ERROR_RNGCALLBACKNOTCRYPTOSTRONG, eModelWarningLevel::mrwInvalidOptionalValue); + for (nfUint64 i = 0; i < keyStore->getResourceDataCount(); ++i) { + PKeyStoreResourceData rd = keyStore->getResourceData(i); + if (rd->getGroup()->isOpen()) { + std::vector newIv(fnGetAlgorithmInitVectorSize(rd->getEncryptionAlgorithm()), 0); + model->generateRandomBytes(newIv.data(), newIv.size()); + rd->setInitVector(newIv); + } + } + } + + bool CKeyStoreOpcPackageWriter::pathIsEncrypted(_In_ std::string sPath) + { + PSecureContext const& secureContext = m_pContext.secureContext(); + PKeyStore const& keyStore = m_pContext.keyStore(); + + NMR::PKeyStoreResourceData rd = keyStore->findResourceData(sPath); + if (nullptr != rd) { + if (secureContext->hasDekCtx()) { + return true; + } + else { + m_pContext.warnings()->addWarning(NMR_ERROR_DEKDESCRIPTORNOTFOUND, eModelWarningLevel::mrwMissingMandatoryValue); + } + } + return false; + } + + POpcPackagePart CKeyStoreOpcPackageWriter::wrapPartStream(PKeyStoreResourceData rd, POpcPackagePart part) { + PSecureContext const & secureContext = m_pContext.secureContext(); + ContentEncryptionDescriptor p = secureContext->getDekCtx(); + PKeyStoreResourceDataGroup rdg = m_pContext.keyStore()->findResourceDataGroupByResourceDataPath(rd->packagePath()); + p.m_sDekDecryptData.m_sParams = CKeyStoreFactory::makeContentEncryptionParams(rd, rdg); + + PExportStream stream; + PExportStream encryptStream = std::make_shared(part->getExportStream(), p); + if (rd->isCompressed()) { + PExportStream compressStream = std::make_shared(encryptStream); + stream = compressStream; + } else { + stream = encryptStream; + } + return std::make_shared(*part, stream); + } + + void CKeyStoreOpcPackageWriter::refreshResourceDataTag(PKeyStoreResourceData rd) { + ContentEncryptionDescriptor dekCtx = m_pContext.secureContext()->getDekCtx(); + PKeyStoreResourceDataGroup rdg = m_pContext.keyStore()->findResourceDataGroupByResourceDataPath(rd->packagePath()); + dekCtx.m_sDekDecryptData.m_sParams = CKeyStoreFactory::makeContentEncryptionParams(rd, rdg); + dekCtx.m_fnCrypt(0, nullptr, nullptr, dekCtx.m_sDekDecryptData); + rd->setAuthTag(dekCtx.m_sDekDecryptData.m_sParams->getAuthTag()); + } + + void CKeyStoreOpcPackageWriter::refreshAccessRight(PKeyStoreAccessRight ar, std::vector const & key) { + try { + KeyWrappingDescriptor ctx = m_pContext.secureContext()->getKekCtx(ar->getConsumer()->getConsumerID()); + ctx.m_sKekDecryptData.m_pAccessRight = ar; + std::vector closedKey; + //give consumer a chance to (re)encrypt this key + nfUint64 wrapped = ctx.m_fnWrap(key, closedKey, ctx.m_sKekDecryptData); + ar->setCipherValue(closedKey); + } catch (CNMRException const & e) { + if (ar->isNew()) { + m_pContext.warnings()->addException(e, eModelWarningLevel::mrwFatal); + } + //here, either there is no registered consumer client or client decided not to refresh the value + } + } + + POpcPackagePart CKeyStoreOpcPackageWriter::addPart(_In_ std::string sPath) + { + PSecureContext const & secureContext = m_pContext.secureContext(); + PKeyStore const & keyStore = m_pContext.keyStore(); + + auto pPart = m_pPackageWriter->addPart(sPath); + NMR::PKeyStoreResourceData rd = keyStore->findResourceData(sPath); + if (nullptr != rd) { + if (secureContext->hasDekCtx()) { + return wrapPartStream(rd, pPart); + } else { + m_pContext.warnings()->addWarning(NMR_ERROR_DEKDESCRIPTORNOTFOUND, eModelWarningLevel::mrwFatal); + } + } + return pPart; + } + + void CKeyStoreOpcPackageWriter::close() { + PSecureContext const & secureContext = m_pContext.secureContext(); + PKeyStore const & keyStore = m_pContext.keyStore(); + + for (nfUint32 i = 0; i < keyStore->getResourceDataCount(); i++) { + PKeyStoreResourceData rd = keyStore->getResourceData(i); + if(secureContext->hasDekCtx()){ + refreshResourceDataTag(rd); + } + } + + if (!keyStore->empty()) { + POpcPackagePart pKeyStorePart = m_pPackageWriter->addPart(PACKAGE_3D_KEYSTORE_URI); + m_pPackageWriter->addContentType(pKeyStorePart, PACKAGE_KEYSTORE_CONTENT_TYPE); + m_pPackageWriter->addRootRelationship(PACKAGE_KEYSTORE_RELATIONSHIP_TYPE, pKeyStorePart.get()); + m_pPackageWriter->addRootRelationship(PACKAGE_MUST_PRESERVE_RELATIONSHIP_TYPE, pKeyStorePart.get()); + PXmlWriter_Native pXMLWriter4KeyStore = std::make_shared(pKeyStorePart->getExportStream()); + writeKeyStoreStream(pXMLWriter4KeyStore.get()); + } + } + + void CKeyStoreOpcPackageWriter::addContentType(std::string sExtension, std::string sContentType) + { + m_pPackageWriter->addContentType(sExtension, sContentType); + } + + void CKeyStoreOpcPackageWriter::addContentType(POpcPackagePart pOpcPackagePart, std::string sContentType) + { + m_pPackageWriter->addContentType(pOpcPackagePart, sContentType); + } + + POpcPackageRelationship CKeyStoreOpcPackageWriter::addRootRelationship(std::string sType, COpcPackagePart * pTargetPart) + { + return m_pPackageWriter->addRootRelationship(sType, pTargetPart); + } + + POpcPackageRelationship CKeyStoreOpcPackageWriter::addPartRelationship(POpcPackagePart pOpcPackagePart, std::string sType, COpcPackagePart * pTargetPart) + { + return m_pPackageWriter->addPartRelationship(pOpcPackagePart, sType, pTargetPart); + } + + std::list CKeyStoreOpcPackageWriter::addWriterSpecificRelationships(_In_ POpcPackagePart pOpcPackagePart, _In_ COpcPackagePart* pTargetPart) + { + std::list list; + std::string sPath = fnIncludeLeadingPathDelimiter(pTargetPart->getURI()); + if (pathIsEncrypted(sPath)) + { + list.push_back(addPartRelationship(pOpcPackagePart, PACKAGE_ENCRYPTED_FILE_RELATIONSHIP, pTargetPart)); + } + + list.merge(m_pPackageWriter->addWriterSpecificRelationships(pOpcPackagePart, pTargetPart)); + return list; + } + + void CKeyStoreOpcPackageWriter::writeKeyStoreStream(_In_ CXmlWriter * pXMLWriter) { + pXMLWriter->WriteStartDocument(); + + CModelWriterNode_KeyStore XMLNode4KeyStore(pXMLWriter, m_pContext.monitor(), m_pContext.keyStore()); + XMLNode4KeyStore.writeToXML(); + + pXMLWriter->WriteEndDocument(); + + pXMLWriter->Flush(); + } + +} diff --git a/Source/Model/Writer/NMR_ModelWriter.cpp b/Source/Model/Writer/NMR_ModelWriter.cpp index 2425c7d5d..1a55eace3 100644 --- a/Source/Model/Writer/NMR_ModelWriter.cpp +++ b/Source/Model/Writer/NMR_ModelWriter.cpp @@ -37,6 +37,8 @@ A model writer exports the in memory represenation into a model file. #include "Common/Platform/NMR_XmlWriter.h" #include "Common/NMR_Exception.h" #include "Common/NMR_Exception_Windows.h" +#include "Common/NMR_SecureContext.h" + #include @@ -46,18 +48,9 @@ namespace NMR { const int MAX_DECIMAL_PRECISION = 16; CModelWriter::CModelWriter(_In_ PModel pModel): + CModelContext(pModel), m_nDecimalPrecision(6) { - if (!pModel.get()) - throw CNMRException(NMR_ERROR_INVALIDPARAM); - - m_pModel = pModel; - m_pProgressMonitor = std::make_shared(); - } - - void CModelWriter::SetProgressCallback(Lib3MFProgressCallback callback, void* userData) - { - m_pProgressMonitor->SetProgressCallback(callback, userData); } void CModelWriter::SetDecimalPrecision(nfUint32 nDecimalPrecision) diff --git a/Source/Model/Writer/NMR_ModelWriterNode.cpp b/Source/Model/Writer/NMR_ModelWriterNode.cpp index c11895226..03ec812a4 100644 --- a/Source/Model/Writer/NMR_ModelWriterNode.cpp +++ b/Source/Model/Writer/NMR_ModelWriterNode.cpp @@ -39,12 +39,10 @@ This is the abstract base class for all 3MF model stream exporters. namespace NMR { - CModelWriterNode::CModelWriterNode(_In_ CModel * pModel, _In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor) + CModelWriterNode::CModelWriterNode(_In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor) { - __NMRASSERT(pModel); __NMRASSERT(pXMLWriter); __NMRASSERT(pProgressMonitor); - m_pModel = pModel; m_pXMLWriter = pXMLWriter; m_pProgressMonitor = pProgressMonitor; } @@ -128,6 +126,4 @@ namespace NMR { { m_pXMLWriter->WriteText(pwszText, cbLength); } - - } diff --git a/Source/Model/Writer/NMR_ModelWriterNode_KeyStoreBase.cpp b/Source/Model/Writer/NMR_ModelWriterNode_KeyStoreBase.cpp new file mode 100644 index 000000000..083fe8502 --- /dev/null +++ b/Source/Model/Writer/NMR_ModelWriterNode_KeyStoreBase.cpp @@ -0,0 +1,41 @@ +#include "Model/Writer/NMR_ModelWriterNode_KeyStoreBase.h" +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelWriterNode_KeyStoreBase.cpp implements the base class for all Model Writer Node classes that are related to . + +--*/ +#include "Common/NMR_Exception.h" + + +NMR::CModelWriterNode_KeyStoreBase::CModelWriterNode_KeyStoreBase(CXmlWriter * pXMLWriter, PProgressMonitor pProgressMonitor, PKeyStore pKeyStore) +: CModelWriterNode(pXMLWriter, pProgressMonitor), m_pKeyStore(pKeyStore) +{ + if (!pKeyStore) + throw CNMRException(NMR_ERROR_INVALIDPOINTER); +} diff --git a/Source/Model/Writer/NMR_ModelWriterNode_ModelBase.cpp b/Source/Model/Writer/NMR_ModelWriterNode_ModelBase.cpp new file mode 100644 index 000000000..1ebc7111c --- /dev/null +++ b/Source/Model/Writer/NMR_ModelWriterNode_ModelBase.cpp @@ -0,0 +1,50 @@ +#include "Model/Writer/NMR_ModelWriterNode_ModelBase.h" +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelWriterNode_ModelBase.h defines the Base class for all Model Writer Node classes that are related to . +This is the abstract base class for all 3MF model stream exporters. + +--*/ + +#include "Model/Writer/NMR_ModelWriterNode_ModelBase.h" + +namespace NMR { + + CModelWriterNode_ModelBase::CModelWriterNode_ModelBase(CModel * pModel, CXmlWriter * pXMLWriter, PProgressMonitor pProgressMonitor) + :CModelWriterNode(pXMLWriter, pProgressMonitor) { + __NMRASSERT(pModel); + m_pModel = pModel; + } + + void CModelWriterNode_ModelBase::assertResourceIsInCurrentPath(PPackageResourceID pID) { + if (pID->getPath() != m_pModel->currentPath()) + throw CNMRException(NMR_ERROR_MODELRESOURCE_IN_DIFFERENT_MODEL); + } +} + diff --git a/Source/Model/Writer/NMR_ModelWriter_3MF.cpp b/Source/Model/Writer/NMR_ModelWriter_3MF.cpp index d4632e03a..89572ee51 100644 --- a/Source/Model/Writer/NMR_ModelWriter_3MF.cpp +++ b/Source/Model/Writer/NMR_ModelWriter_3MF.cpp @@ -31,6 +31,7 @@ A model writer exports the in memory represenation into a 3MF file. --*/ +#include "Model/Writer/SecureContent101/NMR_ModelWriterNode_KeyStore.h" #include "Model/Writer/NMR_ModelWriter_3MF.h" #include "Model/Writer/v100/NMR_ModelWriterNode100_Model.h" #include "Model/Classes/NMR_ModelConstants.h" @@ -54,38 +55,37 @@ namespace NMR { if (pStream == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_CREATEOPCPACKAGE); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_CREATEOPCPACKAGE); + monitor()->ReportProgressAndQueryCancelled(true); // Create new OPC Package - createPackage(m_pModel.get()); + createPackage(model().get()); - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITEMODELSTOSTREAM); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITEMODELSTOSTREAM); + monitor()->ReportProgressAndQueryCancelled(true); // Write Package to Stream writePackageToStream(pStream); - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_CLEANUP); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_CLEANUP); + monitor()->ReportProgressAndQueryCancelled(true); // Release Memory releasePackage(); - m_pProgressMonitor->IncrementProgress(1); + monitor()->IncrementProgress(1); - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_DONE); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_DONE); + monitor()->ReportProgressAndQueryCancelled(true); } - void CModelWriter_3MF::writeSliceStackStream(_In_ CXmlWriter *pXMLWriter) + void CModelWriter_3MF::writeNonRootModelStream(_In_ CXmlWriter *pXMLWriter) { - __NMRASSERT(pSliceStackResource != nullptr); if (pXMLWriter == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); pXMLWriter->WriteStartDocument(); - CModelWriterNode100_Model ModelNode(m_pModel.get(), pXMLWriter, m_pProgressMonitor, GetDecimalPrecision(), false); + CModelWriterNode100_Model ModelNode(model().get(), pXMLWriter, monitor(), GetDecimalPrecision(), false); ModelNode.writeToXML(); pXMLWriter->WriteEndDocument(); @@ -98,14 +98,15 @@ namespace NMR { if (pXMLWriter == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); + model()->setCurrentPath(model()->rootPath()); + pXMLWriter->WriteStartDocument(); - CModelWriterNode100_Model ModelNode(pModel, pXMLWriter, m_pProgressMonitor, GetDecimalPrecision()); + CModelWriterNode100_Model ModelNode(pModel, pXMLWriter, monitor(), GetDecimalPrecision(), true); ModelNode.writeToXML(); pXMLWriter->WriteEndDocument(); pXMLWriter->Flush(); } - } diff --git a/Source/Model/Writer/NMR_ModelWriter_3MF_Native.cpp b/Source/Model/Writer/NMR_ModelWriter_3MF_Native.cpp index f3e902720..7aea896d3 100644 --- a/Source/Model/Writer/NMR_ModelWriter_3MF_Native.cpp +++ b/Source/Model/Writer/NMR_ModelWriter_3MF_Native.cpp @@ -33,11 +33,11 @@ using LibZ and a native XML writer implementation. --*/ +#include "Model/Classes/NMR_KeyStoreResourceData.h" #include "Model/Writer/NMR_ModelWriter_3MF_Native.h" #include "Model/Classes/NMR_ModelConstants.h" #include "Model/Classes/NMR_ModelAttachment.h" #include "Model/Classes/NMR_ModelTextureAttachment.h" -#include "Model/Classes/NMR_ModelSliceStack.h" #include "Common/Platform/NMR_ImportStream.h" #include "Common/NMR_Exception.h" #include "Common/Platform/NMR_XmlWriter.h" @@ -46,6 +46,7 @@ using LibZ and a native XML writer implementation. #include "Common/Platform/NMR_ExportStream_Memory.h" #include "Common/NMR_StringUtils.h" #include "Common/3MF_ProgressMonitor.h" +#include "Common/NMR_ModelWarnings.h" #include #include @@ -53,147 +54,129 @@ namespace NMR { CModelWriter_3MF_Native::CModelWriter_3MF_Native(_In_ PModel pModel) : CModelWriter_3MF(pModel) { - m_nRelationIDCounter = 0; - m_pModel = nullptr; + m_pOtherModel = nullptr; } // These are OPC dependent functions void CModelWriter_3MF_Native::createPackage(_In_ CModel * pModel) { __NMRASSERT(pModel != nullptr); - m_pModel = pModel; - - m_nRelationIDCounter = 0; + m_pOtherModel = pModel; } void CModelWriter_3MF_Native::releasePackage() { - m_pModel = nullptr; + m_pPackageWriter->close(); + m_pPackageWriter = nullptr; + m_pOtherModel = nullptr; } void CModelWriter_3MF_Native::writePackageToStream(_In_ PExportStream pStream) { if (pStream.get() == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); - if (m_pModel == nullptr) + if (m_pOtherModel == nullptr) throw CNMRException(NMR_ERROR_NOMODELTOWRITE); // Maximal progress = NrResources + NrAttachments + Build + Cleanup - m_pProgressMonitor->SetMaxProgress(m_pModel->getResourceCount() + m_pModel->getAttachmentCount() + 1 + 1); + monitor()->SetMaxProgress(m_pOtherModel->getResourceCount() + m_pOtherModel->getAttachmentCount() + 1 + 1); // Write Model Stream - POpcPackageWriter pPackageWriter = std::make_shared(pStream); - POpcPackagePart pModelPart = pPackageWriter->addPart(PACKAGE_3D_MODEL_URI); + m_pPackageWriter = std::make_shared(pStream, *this); + POpcPackagePart pModelPart = m_pPackageWriter->addPart(m_pOtherModel->rootPath()); PXmlWriter_Native pXMLWriter = std::make_shared(pModelPart->getExportStream()); - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITEROOTMODEL); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITEROOTMODEL); + monitor()->ReportProgressAndQueryCancelled(true); - writeModelStream(pXMLWriter.get(), m_pModel); + writeModelStream(pXMLWriter.get(), m_pOtherModel); // add Root relationships - pPackageWriter->addRootRelationship(generateRelationShipID(), PACKAGE_START_PART_RELATIONSHIP_TYPE, pModelPart.get()); + m_pPackageWriter->addRootRelationship(PACKAGE_START_PART_RELATIONSHIP_TYPE, pModelPart.get()); - PModelAttachment pPackageThumbnail = m_pModel->getPackageThumbnail(); + PModelAttachment pPackageThumbnail = m_pOtherModel->getPackageThumbnail(); if (pPackageThumbnail.get() != nullptr) { // create Package Thumbnail Part - POpcPackagePart pThumbnailPart = pPackageWriter->addPart(pPackageThumbnail->getPathURI()); + POpcPackagePart pThumbnailPart = m_pPackageWriter->addPart(pPackageThumbnail->getPathURI()); PExportStream pExportStream = pThumbnailPart->getExportStream(); // Copy data PImportStream pPackageThumbnailStream = pPackageThumbnail->getStream(); pPackageThumbnailStream->seekPosition(0, true); pExportStream->copyFrom(pPackageThumbnailStream.get(), pPackageThumbnailStream->retrieveSize(), MODELWRITER_NATIVE_BUFFERSIZE); // add root relationship - pPackageWriter->addRootRelationship(generateRelationShipID(), pPackageThumbnail->getRelationShipType(), pThumbnailPart.get()); + m_pPackageWriter->addRootRelationship(pPackageThumbnail->getRelationShipType(), pThumbnailPart.get()); } - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITENONROOTMODELS); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITENONROOTMODELS); + monitor()->ReportProgressAndQueryCancelled(true); - // add slicestacks that reference other files - addSlicerefAttachments(); + addNonRootModels(); // add Attachments - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITEATTACHMENTS); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITEATTACHMENTS); + monitor()->ReportProgressAndQueryCancelled(true); - addAttachments(m_pModel, pPackageWriter, pModelPart); + addAttachments(m_pOtherModel, pModelPart); - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITECONTENTTYPES); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITECONTENTTYPES); + monitor()->ReportProgressAndQueryCancelled(true); // add Content Types - pPackageWriter->addContentType(PACKAGE_3D_RELS_EXTENSION, PACKAGE_3D_RELS_CONTENT_TYPE); - pPackageWriter->addContentType(PACKAGE_3D_MODEL_EXTENSION, PACKAGE_3D_MODEL_CONTENT_TYPE); - pPackageWriter->addContentType(PACKAGE_3D_TEXTURE_EXTENSION, PACKAGE_TEXTURE_CONTENT_TYPE); - pPackageWriter->addContentType(PACKAGE_3D_PNG_EXTENSION, PACKAGE_PNG_CONTENT_TYPE); - pPackageWriter->addContentType(PACKAGE_3D_JPEG_EXTENSION, PACKAGE_JPG_CONTENT_TYPE); - pPackageWriter->addContentType(PACKAGE_3D_JPG_EXTENSION, PACKAGE_JPG_CONTENT_TYPE); - - std::map CustomContentTypes = m_pModel->getCustomContentTypes(); + m_pPackageWriter->addContentType(PACKAGE_3D_RELS_EXTENSION, PACKAGE_3D_RELS_CONTENT_TYPE); + m_pPackageWriter->addContentType(PACKAGE_3D_MODEL_EXTENSION, PACKAGE_3D_MODEL_CONTENT_TYPE); + m_pPackageWriter->addContentType(PACKAGE_3D_TEXTURE_EXTENSION, PACKAGE_TEXTURE_CONTENT_TYPE); + m_pPackageWriter->addContentType(PACKAGE_3D_PNG_EXTENSION, PACKAGE_PNG_CONTENT_TYPE); + m_pPackageWriter->addContentType(PACKAGE_3D_JPEG_EXTENSION, PACKAGE_JPG_CONTENT_TYPE); + m_pPackageWriter->addContentType(PACKAGE_3D_JPG_EXTENSION, PACKAGE_JPG_CONTENT_TYPE); + + std::map CustomContentTypes = m_pOtherModel->getCustomContentTypes(); std::map::iterator iContentTypeIterator; for (iContentTypeIterator = CustomContentTypes.begin(); iContentTypeIterator != CustomContentTypes.end(); iContentTypeIterator++) { - if (!m_pModel->contentTypeIsDefault(iContentTypeIterator->first)) { - pPackageWriter->addContentType(iContentTypeIterator->first, iContentTypeIterator->second); + if (!m_pOtherModel->contentTypeIsDefault(iContentTypeIterator->first)) { + m_pPackageWriter->addContentType(iContentTypeIterator->first, iContentTypeIterator->second); } } - } + void CModelWriter_3MF_Native::addNonRootModels() { - std::string CModelWriter_3MF_Native::generateRelationShipID() - { - // Create Unique ID String - std::stringstream sStream; - sStream << "rel" << m_nRelationIDCounter; - m_nRelationIDCounter++; - return sStream.str(); - } + // do this based on resource-paths + std::vector vctPPaths = m_pOtherModel->retrieveAllModelPaths(); + nfUint64 nCount = vctPPaths.size(); - void CModelWriter_3MF_Native::addSlicerefAttachments() { - __NMRASSERT(pModel != nullptr); - - std::vector slicePaths; - for (nfUint32 nIndex = 0; nIndex < m_pModel->getSliceStackCount(); nIndex++) { - CModelSliceStack* pSliceStackResource = dynamic_cast(m_pModel->getSliceStackResource(nIndex).get()); - if (pSliceStackResource->OwnPath().empty() || pSliceStackResource->OwnPath() == m_pModel->rootPath()) - continue; - slicePaths.push_back(pSliceStackResource->OwnPath()); - } - - nfUint64 nCount = slicePaths.size(); for (nfUint32 nIndex = 0; nIndex < nCount; nIndex++) { + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITENONROOTMODELS); + monitor()->ReportProgressAndQueryCancelled(true); - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITENONROOTMODELS); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); - - std::string slicePath = slicePaths[nIndex]; + std::string sNonRootModelPath = vctPPaths[nIndex]->getPath(); + if (sNonRootModelPath == m_pOtherModel->rootPath()) + continue; - m_pModel->setCurPath(slicePath); + m_pOtherModel->setCurrentPath(sNonRootModelPath); PImportStream pStream; { PExportStreamMemory pExportStream = std::make_shared(); PXmlWriter_Native pXMLWriter = std::make_shared(pExportStream); - writeSliceStackStream(pXMLWriter.get()); + writeNonRootModelStream(pXMLWriter.get()); pStream = std::make_shared(pExportStream->getData(), pExportStream->getDataSize()); } - // check, whether that's already in here - PModelAttachment pSliceRefAttachment = m_pModel->findModelAttachment(slicePath); - if (pSliceRefAttachment.get() != nullptr) { - if (pSliceRefAttachment->getRelationShipType() != PACKAGE_START_PART_RELATIONSHIP_TYPE) - throw CNMRException(NMR_ERROR_DUPLICATEATTACHMENTPATH); - pSliceRefAttachment->setStream(pStream); + // check, whether this non-root model is already in here + PModelAttachment pNonRootModelAttachment = m_pOtherModel->findModelAttachment(sNonRootModelPath); + if (pNonRootModelAttachment.get() != nullptr) { + if (pNonRootModelAttachment->getRelationShipType() != PACKAGE_START_PART_RELATIONSHIP_TYPE) + warnings()->addWarning(NMR_ERROR_DUPLICATEATTACHMENTPATH, eModelWarningLevel::mrwFatal); + pNonRootModelAttachment->setStream(pStream); } else - pSliceRefAttachment = m_pModel->addAttachment(slicePath, PACKAGE_START_PART_RELATIONSHIP_TYPE, pStream); + pNonRootModelAttachment = m_pOtherModel->addAttachment(sNonRootModelPath, PACKAGE_START_PART_RELATIONSHIP_TYPE, pStream); } } - void CModelWriter_3MF_Native::addAttachments(_In_ CModel * pModel, _In_ POpcPackageWriter pPackageWriter, _In_ POpcPackagePart pModelPart) + void CModelWriter_3MF_Native::addAttachments(_In_ CModel * pModel, _In_ POpcPackagePart pModelPart) { __NMRASSERT(pModel != nullptr); __NMRASSERT(pModelPart.get() != nullptr); @@ -205,8 +188,8 @@ namespace NMR { if (nCount > 0) { for (nIndex = 0; nIndex < nCount; nIndex++) { - m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITEATTACHMENTS); - m_pProgressMonitor->ReportProgressAndQueryCancelled(true); + monitor()->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITEATTACHMENTS); + monitor()->ReportProgressAndQueryCancelled(true); PModelAttachment pAttachment = pModel->getModelAttachment(nIndex); PImportStream pStream = pAttachment->getStream(); @@ -217,8 +200,8 @@ namespace NMR { if (pStream.get() == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); - // create Texture Part - POpcPackagePart pAttachmentPart = pPackageWriter->addPart(sPath); + // create Attachment Part + POpcPackagePart pAttachmentPart = m_pPackageWriter->addPart(sPath); PExportStream pExportStream = pAttachmentPart->getExportStream(); // Copy data @@ -226,12 +209,12 @@ namespace NMR { pExportStream->copyFrom(pStream.get(), pStream->retrieveSize(), MODELWRITER_NATIVE_BUFFERSIZE); // add relationships - pModelPart->addRelationship(generateRelationShipID(), sRelationShipType.c_str(), pAttachmentPart->getURI()); + m_pPackageWriter->addPartRelationship(pModelPart, sRelationShipType.c_str(), pAttachmentPart.get()); - m_pProgressMonitor->IncrementProgress(1); + m_pPackageWriter->addWriterSpecificRelationships(pModelPart, pAttachmentPart.get()); + + monitor()->IncrementProgress(1); } } } - - } diff --git a/Source/Model/Writer/NMR_ModelWriter_STL.cpp b/Source/Model/Writer/NMR_ModelWriter_STL.cpp index 367368d40..ddabdb87e 100644 --- a/Source/Model/Writer/NMR_ModelWriter_STL.cpp +++ b/Source/Model/Writer/NMR_ModelWriter_STL.cpp @@ -52,7 +52,7 @@ namespace NMR { // Create Merged Mesh PMesh pMesh = std::make_shared(); - m_pModel->mergeToMesh(pMesh.get()); + model()->mergeToMesh(pMesh.get()); // Export Merged Mesh to STL PMeshExporter pExporter = std::make_shared(pStream); diff --git a/Source/Model/Writer/SecureContent101/NMR_ModelWriterNode_KeyStore.cpp b/Source/Model/Writer/SecureContent101/NMR_ModelWriterNode_KeyStore.cpp new file mode 100644 index 000000000..7bf7565bb --- /dev/null +++ b/Source/Model/Writer/SecureContent101/NMR_ModelWriterNode_KeyStore.cpp @@ -0,0 +1,246 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +NMR_ModelWriterNode_KeyStore.cpp implements the Model Writer KeyStore Node Class. +This is the class for exporting the 3mf keystore stream root node. + +--*/ + +#include "Model/Writer/SecureContent101/NMR_ModelWriterNode_KeyStore.h" +#include "Model/Classes/NMR_KeyStoreConsumer.h" +#include "Model/Classes/NMR_KeyStoreResourceData.h" +#include "Model/Classes/NMR_KeyStoreResourceDataGroup.h" +#include "Model/Classes/NMR_KeyStoreCEKParams.h" +#include "Common/NMR_Exception.h" +#include "Common/NMR_StringUtils.h" +#include "Common/NMR_UUID.h" +#include "Libraries/cpp-base64/base64.h" +#include +#include + + +void NMR::CModelWriterNode_KeyStore::writeConsumers() { + nfUint64 count = m_pKeyStore->getConsumerCount(); + for (nfUint64 nIndex = 0; nIndex < count; ++nIndex) { + PKeyStoreConsumer consumer = m_pKeyStore->getConsumer(nIndex); + m_consumerIndexes[consumer] = nIndex; + // + writeStartElement(XML_3MF_ELEMENT_CONSUMER); + //@consumerid + std::string consumerId = consumer->getConsumerID(); + if (consumerId.empty()) { + throw CNMRException(NMR_ERROR_KEYSTOREMISSINGCONSUMERID); + } + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_CONSUMER_ID, consumerId.c_str()); + //@keyid + std::string keyId = consumer->getKeyID(); + if (!keyId.empty()) { + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_KEY_ID, keyId.c_str()); + } + + std::string kvStr = consumer->getKeyValue(); + if (!kvStr.empty()) { + // + writeStartElement(XML_3MF_ELEMENT_KEYVALUE); + writeText(kvStr.c_str(), (nfUint32)kvStr.length()); + // + writeFullEndElement(); + } + + // + writeFullEndElement(); + } +} + +void NMR::CModelWriterNode_KeyStore::writeEncryptionAlgorithmAttribute(eKeyStoreEncryptAlgorithm ea) { + if (ea == eKeyStoreEncryptAlgorithm::AES256_GCM) { + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_ENCRYPTION_ALGORITHM, XML_3MF_SECURE_CONTENT_ENCRYPTION_AES256); + } +} + +void NMR::CModelWriterNode_KeyStore::writeWrapAlgorithmAttribute(eKeyStoreWrapAlgorithm ea) { + if (ea == eKeyStoreWrapAlgorithm::RSA_OAEP) { + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_WRAPPINGALGORITHM, XML_3MF_SECURE_CONTENT_KEYWRAPPING_RSASHORT); + } +} + +void NMR::CModelWriterNode_KeyStore::writeMgf(eKeyStoreMaskGenerationFunction mgf) { + std::string value; + switch (mgf) { + default: + case MGF1_SHA1: + value = XML_3MF_SECURE_CONTENT_MGF1_SHA1; + break; + case MGF1_SHA224: + value = XML_3MF_SECURE_CONTENT_MGF1_SHA224; + break; + case MGF1_SHA256: + value = XML_3MF_SECURE_CONTENT_MGF1_SHA256; + break; + case MGF1_SHA384: + value = XML_3MF_SECURE_CONTENT_MGF1_SHA384; + break; + case MGF1_SHA512: + value = XML_3MF_SECURE_CONTENT_MGF1_SHA512; + break; + } + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_MGFALGORITHM, value.c_str()); +} + +void NMR::CModelWriterNode_KeyStore::writeDigest(eKeyStoreMessageDigest md) { + std::string value; + switch (md) { + default: + case SHA1: + value = XML_3MF_SECURE_CONTENT_MD_SHA1; + break; + case SHA256: + value = XML_3MF_SECURE_CONTENT_MD_SHA256; + break; + case SHA384: + value = XML_3MF_SECURE_CONTENT_MD_SHA384; + break; + case SHA512: + value = XML_3MF_SECURE_CONTENT_MD_SHA512; + break; + } + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_DIGESTMETHOD, value.c_str()); +} + +void NMR::CModelWriterNode_KeyStore::writeResourceDatagroup() { + nfUint64 const count = m_pKeyStore->getResourceDataGroupCount(); + for (nfUint32 resourceIndex = 0; resourceIndex < count; ++resourceIndex) { + PKeyStoreResourceDataGroup resourcedatagroup = m_pKeyStore->getResourceDataGroup(resourceIndex); + // + writeStartElement(XML_3MF_ELEMENT_RESOURCEDATAGROUP); + // keyuuid - attribute + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_KEY_UUID, resourcedatagroup->getKeyUUID()->toString().c_str()); + + nfUint64 const accessCount = resourcedatagroup->getAccessRightCount(); + for (nfUint64 accessIndex = 0; accessIndex < accessCount; ++accessIndex) { + PKeyStoreAccessRight ar = resourcedatagroup->getAccessRight(accessIndex); + writeAccessRight(ar); + } + + nfUint64 const resourceDataCount = m_pKeyStore->getResourceDataCount(); + for (nfUint32 rdIndex = 0; rdIndex < resourceDataCount; ++rdIndex) + { + PKeyStoreResourceData rd = m_pKeyStore->getResourceData(rdIndex); + if (rd->getGroup() == resourcedatagroup) { + writeResourceData(rd); + } + } + // + writeFullEndElement(); + } +} + +void NMR::CModelWriterNode_KeyStore::writeAccessRight(PKeyStoreAccessRight const & ar) { + // + writeStartElement(XML_3MF_ELEMENT_ACCESSRIGHT); + nfUint64 nIndex = m_consumerIndexes[ar->getConsumer()]; + // consumerindex - attribute + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_CONSUMER_INDEX, fnUint32ToString((NMR::nfUint32)nIndex).c_str()); + + // + writeStartElement(XML_3MF_ELEMENT_KEKPARAMS); + // wrappingalgorithm - attribute + writeWrapAlgorithmAttribute(ar->getAlgorithm()); + // mgfalgorithm - attribute + writeMgf(ar->getMgf()); + // digestmethod - attribute + writeDigest(ar->getDigest()); + // + writeEndElement(); + + // + writeStartElement(XML_3MF_ELEMENT_CIPHERDATA); + // + writeStartElementWithPrefix(XML_3MF_ELEMENT_CIPHERVALUE, XML_3MF_NAMESPACEPREFIX_XENC); + std::string encodedCv = base64_encode(ar->getCipherValue()); + writeText(encodedCv.c_str(), (nfUint32)encodedCv.length()); + // + writeFullEndElement(); + // + writeFullEndElement(); + // + writeFullEndElement(); +} + +void NMR::CModelWriterNode_KeyStore::writeResourceData(PKeyStoreResourceData const & rd) { + // + writeStartElement(XML_3MF_ELEMENT_RESOURCEDATA); + // path - attribute + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_PATH, rd->packagePath()->getPath().c_str()); + writeStartElement(XML_3MF_ELEMENT_CEKPARAMS); + // encryptionalgorithm - attribute + writeEncryptionAlgorithmAttribute(rd->getEncryptionAlgorithm()); + // compression - attribute + if (rd->isCompressed()) + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_COMPRESSION, XML_3MF_SECURE_CONTENT_COMPRESSION_DEFLATE); + else + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_COMPRESSION, XML_3MF_SECURE_CONTENT_COMPRESSION_NONE); + + std::vector const & iv = rd->getInitVector(); + if (!iv.empty()) { + writeStartElement(XML_3MF_SECURE_CONTENT_IV); + std::string encodedIv = base64_encode(iv); + writeText(encodedIv.c_str(), (nfUint32)encodedIv.length()); + writeFullEndElement(); + } + + std::vector const & tag = rd->getAuthTag(); + if (!tag.empty()) { + writeStartElement(XML_3MF_SECURE_CONTENT_TAG); + std::string encodedTag = base64_encode(tag); + writeText(encodedTag.c_str(), (nfUint32)encodedTag.length()); + writeFullEndElement(); + } + + std::vector const & aad = rd->getAddAuthData(); + if (!aad.empty()) { + writeStartElement(XML_3MF_SECURE_CONTENT_AAD); + std::string encodedAad = base64_encode(aad); + writeText(encodedAad.c_str(), (nfUint32)encodedAad.length()); + writeFullEndElement(); + } + // + writeFullEndElement(); + // + writeFullEndElement(); +} + +void NMR::CModelWriterNode_KeyStore::writeToXML() { + writeStartElementWithNamespace(XML_3MF_ELEMENT_KEYSTORE, XML_3MF_NAMESPACE_SECURECONTENTSPEC); + writeConstPrefixedStringAttribute(XML_3MF_ATTRIBUTE_XMLNS, XML_3MF_NAMESPACEPREFIX_XENC, XML_3MF_NAMESPACE_CIPHERVALUESPEC); + writeConstPrefixedStringAttribute(XML_3MF_ATTRIBUTE_XMLNS, XML_3MF_NAMESPACEPREFIX_DS, XML_3MF_NAMESPACE_DIGITALSIGNATURESPEC); + writeConstStringAttribute(XML_3MF_SECURE_CONTENT_UUID, m_pKeyStore->getUUID()->toString().c_str()); + writeConsumers(); + writeResourceDatagroup(); + writeFullEndElement(); +} \ No newline at end of file diff --git a/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp b/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp index a3fbe3dbb..d25fb17a5 100644 --- a/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp +++ b/Source/Model/Writer/v100/NMR_ModelWriterNode100_Mesh.cpp @@ -52,7 +52,7 @@ namespace NMR { CModelWriterNode100_Mesh::CModelWriterNode100_Mesh(_In_ CModelMeshObject * pModelMeshObject, _In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor, _In_ PMeshInformation_PropertyIndexMapping pPropertyIndexMapping, _In_ int nPosAfterDecPoint, _In_ nfBool bWriteMaterialExtension, _In_ nfBool bWriteBeamLatticeExtension) - :CModelWriterNode(pModelMeshObject->getModel(), pXMLWriter, pProgressMonitor), m_nPosAfterDecPoint(nPosAfterDecPoint), m_nPutDoubleFactor((int)(pow(10, CModelWriterNode100_Mesh::m_nPosAfterDecPoint))) + :CModelWriterNode_ModelBase(pModelMeshObject->getModel(), pXMLWriter, pProgressMonitor), m_nPosAfterDecPoint(nPosAfterDecPoint), m_nPutDoubleFactor((int)(pow(10, CModelWriterNode100_Mesh::m_nPosAfterDecPoint))) { __NMRASSERT(pModelMeshObject != nullptr); if (!pPropertyIndexMapping.get()) @@ -68,13 +68,20 @@ namespace NMR { m_nTriangleBufferPos = 0; m_nVertexBufferPos = 0; m_nBeamBufferPos = 0; + m_nBallBufferPos = 0; m_nBeamRefBufferPos = 0; + m_nBallRefBufferPos = 0; putVertexString(MODELWRITERMESH100_VERTEXLINESTART); putTriangleString(MODELWRITERMESH100_TRIANGLELINESTART); putBeamString(MODELWRITERMESH100_BEAMLATTICE_BEAMLINESTART); + putBallString(MODELWRITERMESH100_BEAMLATTICE_BALLLINESTART); putBeamRefString(MODELWRITERMESH100_BEAMLATTICE_REFLINESTART); + putBallRefString(MODELWRITERMESH100_BEAMLATTICE_BALLREFLINESTART); } + bool stringRepresentationsDiffer(double a, double b, double putFactor) { + return fabs(a - b) * putFactor > 0.1; + } std::string capModeToString(eModelBeamLatticeCapMode eCapMode) { switch (eCapMode) { @@ -96,6 +103,16 @@ namespace NMR { } } + std::string ballModeToString(eModelBeamLatticeBallMode eBallMode) { + switch (eBallMode) { + case eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_NONE: return XML_3MF_BEAMLATTICE_BALLMODE_NONE; break; + case eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_MIXED: return XML_3MF_BEAMLATTICE_BALLMODE_MIXED; break; + case eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_ALL: return XML_3MF_BEAMLATTICE_BALLMODE_ALL; break; + default: + return XML_3MF_BEAMLATTICE_BALLMODE_NONE; + } + } + void CModelWriterNode100_Mesh::writeToXML() { __NMRASSERT(m_pXMLWriter); @@ -106,7 +123,8 @@ namespace NMR { const nfUint32 nNodeCount = pMesh->getNodeCount (); const nfUint32 nFaceCount = pMesh->getFaceCount(); const nfUint32 nBeamCount = pMesh->getBeamCount(); - nfUint32 nNodeIndex, nFaceIndex, nBeamIndex; + const nfUint32 nBallCount = pMesh->getBallCount(); + nfUint32 nNodeIndex, nFaceIndex, nBeamIndex, nBallIndex; // Write Mesh Element writeStartElement(XML_3MF_ELEMENT_MESH); @@ -137,7 +155,7 @@ namespace NMR { // Retrieve Mesh Informations CMeshInformation_Properties * pProperties = NULL; - ModelResourceID nObjectLevelPropertyID = 0; + UniqueResourceID nObjectLevelPropertyID = 0; ModelResourceIndex nObjectLevelPropertyIndex = 0; CMeshInformationHandler * pMeshInformationHandler = pMesh->getMeshInformationHandler(); @@ -148,8 +166,8 @@ namespace NMR { pProperties = dynamic_cast (pInformation); NMR::MESHINFORMATION_PROPERTIES * pDefaultData = (NMR::MESHINFORMATION_PROPERTIES*)pProperties->getDefaultData(); - if (pDefaultData && pDefaultData->m_nResourceID != 0) { - nObjectLevelPropertyID = pDefaultData->m_nResourceID; + if (pDefaultData && pDefaultData->m_nUniqueResourceID != 0) { + nObjectLevelPropertyID = pDefaultData->m_nUniqueResourceID; nObjectLevelPropertyIndex = m_pPropertyIndexMapping->mapPropertyIDToIndex(nObjectLevelPropertyID, pDefaultData->m_nPropertyIDs[0]); } } @@ -168,7 +186,7 @@ namespace NMR { // Get Mesh Face MESHFACE * pMeshFace = pMesh->getFace(nFaceIndex); - ModelResourceID nPropertyID = 0; + UniqueResourceID nPropertyID = 0; ModelResourceIndex nPropertyIndex1 = 0; ModelResourceIndex nPropertyIndex2 = 0; ModelResourceIndex nPropertyIndex3 = 0; @@ -178,8 +196,8 @@ namespace NMR { if (pProperties != nullptr) { MESHINFORMATION_PROPERTIES* pFaceData = (MESHINFORMATION_PROPERTIES*)pProperties->getFaceData(nFaceIndex); if (pFaceData != nullptr) { - if (pFaceData->m_nResourceID) { - nPropertyID = pFaceData->m_nResourceID; + if (pFaceData->m_nUniqueResourceID) { + nPropertyID = pFaceData->m_nUniqueResourceID; nPropertyIndex1 = m_pPropertyIndexMapping->mapPropertyIDToIndex(nPropertyID, pFaceData->m_nPropertyIDs[0]); nPropertyIndex2 = m_pPropertyIndexMapping->mapPropertyIDToIndex(nPropertyID, pFaceData->m_nPropertyIDs[1]); nPropertyIndex3 = m_pPropertyIndexMapping->mapPropertyIDToIndex(nPropertyID, pFaceData->m_nPropertyIDs[2]); @@ -190,14 +208,16 @@ namespace NMR { if (nPropertyID != 0) { bMeshHasAProperty = true; + // TODO: this is slow + ModelResourceID nPropertyModelResourceID = m_pModel->findPackageResourceID(nPropertyID)->getModelResourceID(); if ((nPropertyIndex1 != nPropertyIndex2) || (nPropertyIndex1 != nPropertyIndex3)) { - writeFaceData_ThreeProperties(pMeshFace, nPropertyID, nPropertyIndex1, nPropertyIndex2, nPropertyIndex3, pAdditionalString); + writeFaceData_ThreeProperties(pMeshFace, nPropertyModelResourceID, nPropertyIndex1, nPropertyIndex2, nPropertyIndex3, pAdditionalString); } else { if ((nPropertyID == nObjectLevelPropertyID) && (nPropertyIndex1 == nObjectLevelPropertyIndex)){ writeFaceData_Plain(pMeshFace, pAdditionalString); } else { - writeFaceData_OneProperty(pMeshFace, nPropertyID, nPropertyIndex1, pAdditionalString); + writeFaceData_OneProperty(pMeshFace, nPropertyModelResourceID, nPropertyIndex1, pAdditionalString); } } } @@ -237,16 +257,55 @@ namespace NMR { // write beamlattice writeStartElementWithPrefix(XML_3MF_ELEMENT_BEAMLATTICE, XML_3MF_NAMESPACEPREFIX_BEAMLATTICE); nfDouble dDefaultRadius = pMesh->getDefaultBeamRadius(); + nfDouble dDefaultBallRadius = pMesh->getDefaultBallRadius(); + nfBool bWriteBallsElement = nBallCount > 0; writeFloatAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_RADIUS, float(dDefaultRadius)); writeFloatAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_MINLENGTH, float(pMesh->getBeamLatticeMinLength())); + eModelBeamLatticeBallMode eBallMode = pMesh->getBeamLatticeBallMode(); + + if (eBallMode == eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_ALL) { + if (dDefaultBallRadius > 0) { + writeStringAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_BALLMODE, ballModeToString(eBallMode)); + writeFloatAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_BALLRADIUS, float(dDefaultBallRadius)); + + // Check if any balls do not use dDefaultBallRadius + bWriteBallsElement = false; + for (nfUint32 iBall = 0; iBall < nBallCount; iBall++) { + if (stringRepresentationsDiffer(pMesh->getBall(iBall)->m_radius, dDefaultBallRadius, m_nPutDoubleFactor)) { + bWriteBallsElement = true; + break; + } + } + } + else { + throw CNMRException(NMR_ERROR_BEAMLATTICEINVALIDATTRIBUTE); + } + } + else if (nBallCount > 0) { + if (eBallMode == eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_MIXED) { + if (dDefaultBallRadius > 0) { + writeStringAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_BALLMODE, ballModeToString(eBallMode)); + writeFloatAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_BALLRADIUS, float(dDefaultBallRadius)); + } + else { + throw CNMRException(NMR_ERROR_BEAMLATTICEINVALIDATTRIBUTE); + } + } + } if (m_pModelMeshObject->getBeamLatticeAttributes()->m_bHasClippingMeshID) { writeStringAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_CLIPPINGMODE, clipModeToString(m_pModelMeshObject->getBeamLatticeAttributes()->m_eClipMode)); - writeIntAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_CLIPPINGMESH, m_pModelMeshObject->getBeamLatticeAttributes()->m_nClippingMeshID->getUniqueID()); + PPackageResourceID pID = m_pModelMeshObject->getBeamLatticeAttributes()->m_pClippingMeshUniqueID; + if (pID->getPath() != m_pModel->currentPath()) + throw CNMRException(NMR_ERROR_MODELRESOURCE_IN_DIFFERENT_MODEL); + writeIntAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_CLIPPINGMESH, pID->getModelResourceID()); } if (m_pModelMeshObject->getBeamLatticeAttributes()->m_bHasRepresentationMeshID) { - writeIntAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_REPRESENTATIONMESH, m_pModelMeshObject->getBeamLatticeAttributes()->m_nRepresentationID->getUniqueID()); + PPackageResourceID pID = m_pModelMeshObject->getBeamLatticeAttributes()->m_pRepresentationUniqueID; + if (pID->getPath() != m_pModel->currentPath()) + throw CNMRException(NMR_ERROR_MODELRESOURCE_IN_DIFFERENT_MODEL); + writeIntAttribute(XML_3MF_ATTRIBUTE_BEAMLATTICE_REPRESENTATIONMESH, pID->getModelResourceID()); } eModelBeamLatticeCapMode eDefaultCapMode = pMesh->getBeamLatticeCapMode(); @@ -261,6 +320,18 @@ namespace NMR { } writeFullEndElement(); + // write beamlattice: balls + // Only if there is at least 1 ball + if (bWriteBallsElement) { + writeStartElementWithPrefix(XML_3MF_ELEMENT_BALLS, XML_3MF_NAMESPACEPREFIX_BEAMLATTICE); + for (nBallIndex = 0; nBallIndex < nBallCount; nBallIndex++) { + // write beamlattice: ball + MESHBALL * pMeshBall = pMesh->getBall(nBallIndex); + writeBallData(pMeshBall, eBallMode, dDefaultBallRadius); + } + writeFullEndElement(); + } + const nfUint32 nBeamSetCount = pMesh->getBeamSetCount(); if (nBeamSetCount > 0) { // write beamlattice: beamsets @@ -279,6 +350,11 @@ namespace NMR { // write beamlattice: ref writeRefData(pBeamSet->m_Refs[nRefIndex]); } + const nfUint32 nBallRefCount = (nfUint32)pBeamSet->m_BallRefs.size(); + for (nfUint32 nBallRefIndex = 0; nBallRefIndex < nBallRefCount; nBallRefIndex++) { + // write beamlattice: ballref + writeBallRefData(pBeamSet->m_BallRefs[nBallRefIndex]); + } writeFullEndElement(); } } @@ -461,6 +537,38 @@ namespace NMR { putDouble(dValue, m_BeamLine, m_nBeamBufferPos); } + void CModelWriterNode100_Mesh::putBallString(_In_ const nfChar * pszString) + { + __NMRASSERT(pszString); + const nfChar * pChar = pszString; + nfChar * pTarget = &m_BallLine[m_nBallBufferPos]; + + while (*pChar != 0) { + *pTarget = *pChar; + pTarget++; + pChar++; + m_nBallBufferPos++; + } + } + + void CModelWriterNode100_Mesh::putBallUInt32(_In_ const nfUint32 nValue) + { +#ifdef __GNUC__ + int nCount = sprintf(&m_BallLine[m_nBallBufferPos], "%d", nValue); +#else + int nCount = sprintf_s(&m_BallLine[m_nBallBufferPos], MODELWRITERMESH100_LINEBUFFERSIZE - m_nBallBufferPos, "%d", nValue); +#endif // __GNUC__ + + if (nCount < 1) + throw CNMRException(NMR_ERROR_COULDNOTCONVERTNUMBER); + m_nBallBufferPos += nCount; + } + + void CModelWriterNode100_Mesh::putBallDouble(_In_ const nfDouble dValue) + { + putDouble(dValue, m_BallLine, m_nBallBufferPos); + } + void CModelWriterNode100_Mesh::putBeamRefString(_In_ const nfChar * pszString) { __NMRASSERT(pszString); @@ -488,6 +596,32 @@ namespace NMR { m_nBeamRefBufferPos += nCount; } + void CModelWriterNode100_Mesh::putBallRefString(_In_ const nfChar* pszString) + { + __NMRASSERT(pszString); + const nfChar * pChar = pszString; + nfChar * pTarget = &m_BallRefLine[m_nBallRefBufferPos]; + + while (*pChar != 0) { + *pTarget = *pChar; + pTarget++; + pChar++; + m_nBallRefBufferPos++; + } + } + + void CModelWriterNode100_Mesh::putBallRefUInt32(_In_ const nfUint32 nValue) + { +#ifdef __GNUC__ + int nCount = sprintf(&m_BallRefLine[m_nBallRefBufferPos], "%d", nValue); +#else + int nCount = sprintf_s(&m_BallRefLine[m_nBallRefBufferPos], MODELWRITERMESH100_LINEBUFFERSIZE - m_nBallRefBufferPos, "%d", nValue); +#endif // __GNUC__ + + if (nCount < 1) + throw CNMRException(NMR_ERROR_COULDNOTCONVERTNUMBER); + m_nBallRefBufferPos += nCount; + } void CModelWriterNode100_Mesh::writeVertexData(_In_ MESHNODE * pNode) { @@ -568,12 +702,7 @@ namespace NMR { } putTriangleString(" />"); m_pXMLWriter->WriteRawLine(&m_TriangleLine[0], m_nTriangleBufferPos); - } - - - bool stringRepresentationsDiffer(double a, double b, double putFactor) { - return fabs(a - b) * putFactor > 0.1; - } + } __NMR_INLINE void CModelWriterNode100_Mesh::writeBeamData(_In_ MESHBEAM * pBeam, _In_ nfDouble dRadius, _In_ eModelBeamLatticeCapMode eDefaultCapMode) { @@ -612,6 +741,27 @@ namespace NMR { m_pXMLWriter->WriteRawLine(&m_BeamLine[0], m_nBeamBufferPos); } + __NMR_INLINE void CModelWriterNode100_Mesh::writeBallData(_In_ MESHBALL* pBall, _In_ eModelBeamLatticeBallMode eBallMode, _In_ nfDouble dRadius) + { + __NMRASSERT(pBall); + + nfBool bWriteR = stringRepresentationsDiffer(pBall->m_radius, dRadius, m_nPutDoubleFactor); + if (!bWriteR && eBallMode == eModelBeamLatticeBallMode::MODELBEAMLATTICEBALLMODE_ALL) { + return; + } + + m_nBallBufferPos = MODELWRITERMESH100_BEAMLATTICE_BALLSTARTLENGTH; + putBallUInt32(pBall->m_nodeindex); + if (bWriteR) { + const std::string sR = "\" " + std::string(XML_3MF_ATTRIBUTE_BEAMLATTICE_BALL_R) + "=\""; + putBallString(sR.c_str()); + putBallDouble(pBall->m_radius); + } + + putBallString("\"/>"); + m_pXMLWriter->WriteRawLine(&m_BallLine[0], m_nBallBufferPos); + } + __NMR_INLINE void CModelWriterNode100_Mesh::writeRefData(_In_ INT nRefID) { m_nBeamRefBufferPos = MODELWRITERMESH100_BEAMLATTICE_REFSTARTLENGTH; @@ -620,4 +770,12 @@ namespace NMR { m_pXMLWriter->WriteRawLine(&m_BeamRefLine[0], m_nBeamRefBufferPos); } + __NMR_INLINE void CModelWriterNode100_Mesh::writeBallRefData(_In_ INT nBallRefID) + { + m_nBallRefBufferPos = MODELWRITERMESH100_BEAMLATTICE_BALLREFSTARTLENGTH; + putBallRefUInt32(nBallRefID); + putBallRefString("\"/>"); + m_pXMLWriter->WriteRawLine(&m_BallRefLine[0], m_nBallRefBufferPos); + } + } diff --git a/Source/Model/Writer/v100/NMR_ModelWriterNode100_Model.cpp b/Source/Model/Writer/v100/NMR_ModelWriterNode100_Model.cpp index 2b5ca9374..fdf97fa43 100644 --- a/Source/Model/Writer/v100/NMR_ModelWriterNode100_Model.cpp +++ b/Source/Model/Writer/v100/NMR_ModelWriterNode100_Model.cpp @@ -57,46 +57,26 @@ This is the class for exporting the 3mf model stream root node. namespace NMR { - CModelWriterNode100_Model::CModelWriterNode100_Model(_In_ CModel * pModel, _In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor, _In_ nfUint32 nDecimalPrecision) - :CModelWriterNode(pModel, pXMLWriter, pProgressMonitor), m_nDecimalPrecision(nDecimalPrecision) + CModelWriterNode100_Model::CModelWriterNode100_Model(_In_ CModel * pModel, _In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor, + _In_ nfUint32 nDecimalPrecision, nfBool bWritesRootModel) : CModelWriterNode_ModelBase(pModel, pXMLWriter, pProgressMonitor), m_nDecimalPrecision(nDecimalPrecision) { - m_ResourceCounter = pModel->generateResourceID(); - m_pPropertyIndexMapping = std::make_shared(); + m_bIsRootModel = bWritesRootModel; m_bWriteMaterialExtension = true; m_bWriteProductionExtension = true; m_bWriteBeamLatticeExtension = true; m_bWriteSliceExtension = true; + m_bWriteSecureContentExtension = true; m_bWriteBaseMaterials = true; m_bWriteObjects = true; - m_bIsRootModel = true; m_bWriteCustomNamespaces = true; // register custom NameSpaces from metadata in objects, build items and the model itself RegisterMetaDataNameSpaces(); } - - CModelWriterNode100_Model::CModelWriterNode100_Model(_In_ CModel * pModel, _In_ CXmlWriter * pXMLWriter, _In_ PProgressMonitor pProgressMonitor, - _In_ nfUint32 nDecimalPrecision, nfBool bWritesRootModel) : CModelWriterNode(pModel, pXMLWriter, pProgressMonitor), m_nDecimalPrecision(nDecimalPrecision) - { - if (bWritesRootModel) { - throw CNMRException(NMR_ERROR_INVALIDPARAM); - } - - m_bWriteMaterialExtension = false; - m_bWriteMaterialExtension = false; - m_bWriteBeamLatticeExtension = false; - m_bWriteBaseMaterials = false; - m_bWriteObjects = false; - m_bIsRootModel = false; - m_bWriteSliceExtension = true; - m_bWriteCustomNamespaces = true; - } - - void CModelWriterNode100_Model::RegisterMetaDataGroupNameSpaces(PModelMetaDataGroup mdg) { for (nfUint32 i = 0; i < mdg->getMetaDataCount(); i++) @@ -172,6 +152,15 @@ namespace NMR { } } + if (m_bWriteSecureContentExtension) { + writeConstPrefixedStringAttribute(XML_3MF_ATTRIBUTE_XMLNS, XML_3MF_NAMESPACEPREFIX_SECURECONTENT, XML_3MF_NAMESPACE_SECURECONTENTSPEC); + if (m_pModel->RequireExtension(XML_3MF_NAMESPACE_SECURECONTENTSPEC)) { + if (sRequiredExtensions.size() > 0) + sRequiredExtensions = sRequiredExtensions + " "; + sRequiredExtensions = sRequiredExtensions + XML_3MF_NAMESPACEPREFIX_SECURECONTENT; + } + } + if (m_bWriteCustomNamespaces) { nfUint32 nNSCount = m_pXMLWriter->GetNamespaceCount(); for (nfUint32 iNSCount = 0; iNSCount < nNSCount; iNSCount++) { @@ -202,7 +191,9 @@ namespace NMR { CModelTexture2DResource * pTexture2D = m_pModel->getTexture2D(nTextureIndex); writeStartElementWithPrefix(XML_3MF_ELEMENT_TEXTURE2D, XML_3MF_NAMESPACEPREFIX_MATERIAL); - writeIntAttribute(XML_3MF_ATTRIBUTE_TEXTURE2D_ID, pTexture2D->getResourceID()->getUniqueID()); + + assertResourceIsInCurrentPath(pTexture2D->getPackageResourceID()); + writeIntAttribute(XML_3MF_ATTRIBUTE_TEXTURE2D_ID, pTexture2D->getPackageResourceID()->getModelResourceID()); writeStringAttribute(XML_3MF_ATTRIBUTE_TEXTURE2D_PATH, pTexture2D->getAttachment()->getPathURI()); writeStringAttribute(XML_3MF_ATTRIBUTE_TEXTURE2D_CONTENTTYPE, pTexture2D->getContentTypeString()); @@ -252,7 +243,8 @@ namespace NMR { pBaseMaterial->buildResourceIndexMap(); - ModelResourceID nResourceID = pBaseMaterial->getResourceID()->getUniqueID(); + assertResourceIsInCurrentPath(pBaseMaterial->getPackageResourceID()); + ModelResourceID nResourceID = pBaseMaterial->getPackageResourceID()->getModelResourceID(); writeStartElement(XML_3MF_ELEMENT_BASEMATERIALS); // Write Object ID (mandatory) @@ -260,6 +252,8 @@ namespace NMR { nfUint32 nElementCount = pBaseMaterial->getCount(); + UniqueResourceID nUniqueResourceID = pBaseMaterial->getPackageResourceID()->getUniqueID(); + for (nfUint32 j = 0; j < nElementCount; j++) { ModelPropertyID nPropertyID; if (!pBaseMaterial->mapResourceIndexToPropertyID(j, nPropertyID)) { @@ -267,7 +261,7 @@ namespace NMR { } PModelBaseMaterial pElement = pBaseMaterial->getBaseMaterial(nPropertyID); - m_pPropertyIndexMapping->registerPropertyID(nResourceID, pElement->getPropertyID(), j); + m_pPropertyIndexMapping->registerPropertyID(nUniqueResourceID, pElement->getPropertyID(), j); writeStartElement(XML_3MF_ELEMENT_BASE); writeStringAttribute(XML_3MF_ATTRIBUTE_BASEMATERIAL_NAME, pElement->getName()); @@ -301,14 +295,12 @@ namespace NMR { std::string sNameSpacePrefix = XML_3MF_NAMESPACEPREFIX_SLICE; - if ( - (!m_bIsRootModel && pSliceStackResource->OwnPath() == m_pModel->curPath()) || - (m_bIsRootModel && (pSliceStackResource->OwnPath() == m_pModel->rootPath() || pSliceStackResource->OwnPath().empty() ) ) - ) + if (pSliceStackResource->OwnPath() == m_pModel->currentPath()) { writeStartElementWithPrefix(XML_3MF_ELEMENT_SLICESTACKRESOURCE, XML_3MF_NAMESPACEPREFIX_SLICE); - writeIntAttribute(XML_3MF_ATTRIBUTE_SLICESTACKID, pSliceStackResource->getResourceID()->getUniqueID()); + assertResourceIsInCurrentPath(pSliceStackResource->getPackageResourceID()); + writeIntAttribute(XML_3MF_ATTRIBUTE_SLICESTACKID, pSliceStackResource->getPackageResourceID()->getModelResourceID()); writeFloatAttribute(XML_3MF_ATTRIBUTE_SLICESTACKZBOTTOM, (float)pSliceStackResource->getZBottom()); @@ -317,22 +309,14 @@ namespace NMR { auto sliceRef = pSliceStackResource->getSliceRef(sliceRefIndex); writeStartElementWithPrefix(XML_3MF_ELEMENT_SLICEREFRESOURCE, XML_3MF_NAMESPACEPREFIX_SLICE); - writeIntAttribute(XML_3MF_ATTRIBUTE_SLICEREF_ID, sliceRef->getResourceID()->getUniqueID()); - if (m_bIsRootModel) { - if (!sliceRef->OwnPath().empty() && (sliceRef->OwnPath() != m_pModel->rootPath())) { - writeStringAttribute(XML_3MF_ATTRIBUTE_SLICEREF_PATH, sliceRef->OwnPath()); - } - } - else { - if (!sliceRef->OwnPath().empty() && (sliceRef->OwnPath() != m_pModel->curPath())) { - writeStringAttribute(XML_3MF_ATTRIBUTE_SLICEREF_PATH, sliceRef->OwnPath()); - } + writeIntAttribute(XML_3MF_ATTRIBUTE_SLICEREF_ID, sliceRef->getPackageResourceID()->getModelResourceID()); + if (sliceRef->OwnPath() != m_pModel->currentPath()) { + writeStringAttribute(XML_3MF_ATTRIBUTE_SLICEREF_PATH, sliceRef->OwnPath()); } writeEndElement(); } } - if (pSliceStackResource->getSliceCount() > 0) { for (nfUint32 nSliceIndex = 0; nSliceIndex < pSliceStackResource->getSliceCount(); nSliceIndex++) { if (nSliceIndex % PROGRESS_SLICEUPDATE == PROGRESS_SLICEUPDATE - 1) { @@ -393,16 +377,21 @@ namespace NMR { std::list objectList = m_pModel->getSortedObjectList(); for (auto iIterator = objectList.begin(); iIterator != objectList.end(); iIterator++) { + CModelObject * pObject = *iIterator; + + PPackageModelPath pPath = pObject->getPackageResourceID()->getPackageModelPath(); + if (m_pModel->currentModelPath()->getPath() != pPath->getPath()) + { + continue; + } m_pProgressMonitor->SetProgressIdentifier(ProgressIdentifier::PROGRESS_WRITEOBJECTS); m_pProgressMonitor->IncrementProgress(1); m_pProgressMonitor->ReportProgressAndQueryCancelled(true); - CModelObject * pObject = *iIterator; - writeStartElement(XML_3MF_ELEMENT_OBJECT); // Write Object ID (mandatory) - writeIntAttribute(XML_3MF_ATTRIBUTE_OBJECT_ID, pObject->getResourceID()->getUniqueID()); + writeIntAttribute(XML_3MF_ATTRIBUTE_OBJECT_ID, pObject->getPackageResourceID()->getModelResourceID()); // Write Object Name (optional) std::string sObjectName = pObject->getName(); @@ -438,8 +427,9 @@ namespace NMR { // Slice extension content if (m_bWriteSliceExtension) { if (pObject->getSliceStack().get()) { + assertResourceIsInCurrentPath(pObject->getSliceStack()->getPackageResourceID()); writePrefixedStringAttribute(XML_3MF_NAMESPACEPREFIX_SLICE, XML_3MF_ATTRIBUTE_OBJECT_SLICESTACKID, - fnUint32ToString(pObject->getSliceStack()->getResourceID()->getUniqueID())); + fnUint32ToString(pObject->getSliceStack()->getPackageResourceID()->getModelResourceID())); } if (pObject->slicesMeshResolution() != MODELSLICESMESHRESOLUTION_FULL) { writePrefixedStringAttribute(XML_3MF_NAMESPACEPREFIX_SLICE, XML_3MF_ATTRIBUTE_OBJECT_MESHRESOLUTION, @@ -447,17 +437,14 @@ namespace NMR { } } - writeMetaDataGroup(pObject->metaDataGroup()); - // Check if object is a mesh Object CModelMeshObject * pMeshObject = dynamic_cast (pObject); if (pMeshObject) { // Prepare Object Level Property ID and Index - ModelResourceID nObjectLevelPropertyID = 0; + UniqueResourceID nObjectLevelPropertyID = 0; ModelResourceIndex nObjectLevelPropertyIndex = 0; - CMesh* pMesh = pMeshObject->getMesh(); - + if (pMesh) { CMeshInformationHandler * pMeshInformationHandler = pMesh->getMeshInformationHandler(); if (pMeshInformationHandler) { @@ -466,22 +453,24 @@ namespace NMR { if (pInformation) { auto pProperties = dynamic_cast (pInformation); NMR::MESHINFORMATION_PROPERTIES * pDefaultData = (NMR::MESHINFORMATION_PROPERTIES*)pProperties->getDefaultData(); - - if (pDefaultData && pDefaultData->m_nResourceID != 0) { - nObjectLevelPropertyID = pDefaultData->m_nResourceID; + if (pDefaultData && pDefaultData->m_nUniqueResourceID != 0) { + nObjectLevelPropertyID = pDefaultData->m_nUniqueResourceID; nObjectLevelPropertyIndex = m_pPropertyIndexMapping->mapPropertyIDToIndex(nObjectLevelPropertyID, pDefaultData->m_nPropertyIDs[0]); } } - } } - // Write Object Level Attributes (only for meshes) if (nObjectLevelPropertyID != 0) { - writeIntAttribute(XML_3MF_ATTRIBUTE_OBJECT_PID, nObjectLevelPropertyID); + ModelResourceID nPropertyModelResourceID = m_pModel->findPackageResourceID(nObjectLevelPropertyID)->getModelResourceID(); + writeIntAttribute(XML_3MF_ATTRIBUTE_OBJECT_PID, nPropertyModelResourceID); writeIntAttribute(XML_3MF_ATTRIBUTE_OBJECT_PINDEX, nObjectLevelPropertyIndex); } + } + writeMetaDataGroup(pObject->metaDataGroup()); + + if (pMeshObject) { CModelWriterNode100_Mesh ModelWriter_Mesh(pMeshObject, m_pXMLWriter, m_pProgressMonitor, m_pPropertyIndexMapping, m_nDecimalPrecision, m_bWriteMaterialExtension, m_bWriteBeamLatticeExtension); @@ -517,7 +506,7 @@ namespace NMR { if (!m_pXMLWriter->GetNamespacePrefix(sNameSpace, sNameSpacePrefix)) { throw CNMRException(NMR_ERROR_INVALIDBUFFERSIZE); } - writeStringAttribute(XML_3MF_ATTRIBUTE_METADATA_NAME, CModelMetaData::calculateKey(sNameSpacePrefix, sName)); + writeStringAttribute(XML_3MF_ATTRIBUTE_METADATA_NAME, composeNamespaceAndNameIntoKey(sNameSpacePrefix, sName)); } if (sType != "xs:string") { @@ -555,7 +544,8 @@ namespace NMR { pColorGroup->buildResourceIndexMap(); - ModelResourceID nResourceID = pColorGroup->getResourceID()->getUniqueID(); + assertResourceIsInCurrentPath(pColorGroup->getPackageResourceID()); + ModelResourceID nResourceID = pColorGroup->getPackageResourceID()->getModelResourceID(); writeStartElementWithPrefix(XML_3MF_ELEMENT_COLORGROUP, XML_3MF_NAMESPACEPREFIX_MATERIAL); // Write Object ID (mandatory) @@ -563,6 +553,7 @@ namespace NMR { nfUint32 nElementCount = pColorGroup->getCount(); + UniqueResourceID nUniqueResourceID = pColorGroup->getPackageResourceID()->getUniqueID(); for (nfUint32 j = 0; j < nElementCount; j++) { ModelPropertyID nPropertyID; if (!pColorGroup->mapResourceIndexToPropertyID(j, nPropertyID)) { @@ -570,7 +561,7 @@ namespace NMR { } nfColor pElement = pColorGroup->getColor(nPropertyID); - m_pPropertyIndexMapping->registerPropertyID(nResourceID, nPropertyID, j); + m_pPropertyIndexMapping->registerPropertyID(nUniqueResourceID, nPropertyID, j); writeStartElementWithPrefix(XML_3MF_ELEMENT_COLOR, XML_3MF_NAMESPACEPREFIX_MATERIAL); writeStringAttribute(XML_3MF_ATTRIBUTE_COLORS_COLOR, fnColorToString(pElement)); @@ -592,15 +583,17 @@ namespace NMR { pTexture2DGroup->buildResourceIndexMap(); - ModelResourceID nResourceID = pTexture2DGroup->getResourceID()->getUniqueID(); + assertResourceIsInCurrentPath(pTexture2DGroup->getPackageResourceID()); + ModelResourceID nResourceID = pTexture2DGroup->getPackageResourceID()->getModelResourceID(); writeStartElementWithPrefix(XML_3MF_ELEMENT_TEX2DGROUP, XML_3MF_NAMESPACEPREFIX_MATERIAL); // Write Object ID (mandatory) writeIntAttribute(XML_3MF_ATTRIBUTE_TEX2DGROUP_ID, nResourceID); - writeIntAttribute(XML_3MF_ATTRIBUTE_TEX2DGROUP_TEXTUREID, pTexture2DGroup->getTexture2D()->getResourceID()->getUniqueID()); + assertResourceIsInCurrentPath(pTexture2DGroup->getTexture2D()->getPackageResourceID()); + writeIntAttribute(XML_3MF_ATTRIBUTE_TEX2DGROUP_TEXTUREID, pTexture2DGroup->getTexture2D()->getPackageResourceID()->getModelResourceID()); nfUint32 nElementCount = pTexture2DGroup->getCount(); - + UniqueResourceID nUniqueResourceID = pTexture2DGroup->getPackageResourceID()->getUniqueID(); for (nfUint32 j = 0; j < nElementCount; j++) { ModelPropertyID nPropertyID; if (!pTexture2DGroup->mapResourceIndexToPropertyID(j, nPropertyID)) { @@ -608,7 +601,7 @@ namespace NMR { } MODELTEXTURE2DCOORDINATE uvCoordinate = pTexture2DGroup->getUVCoordinate(nPropertyID); - m_pPropertyIndexMapping->registerPropertyID(nResourceID, nPropertyID, j); + m_pPropertyIndexMapping->registerPropertyID(nUniqueResourceID, nPropertyID, j); writeStartElementWithPrefix(XML_3MF_ELEMENT_TEX2COORD, XML_3MF_NAMESPACEPREFIX_MATERIAL); writeFloatAttribute(XML_3MF_ATTRIBUTE_TEXTURE_U, (float)uvCoordinate.m_dU); @@ -632,13 +625,16 @@ namespace NMR { pCompositeMaterials->buildResourceIndexMap(); - ModelResourceID nResourceID = pCompositeMaterials->getResourceID()->getUniqueID(); + assertResourceIsInCurrentPath(pCompositeMaterials->getPackageResourceID()); + ModelResourceID nResourceID = pCompositeMaterials->getPackageResourceID()->getModelResourceID(); + UniqueResourceID nUniqueResourceID = pCompositeMaterials->getPackageResourceID()->getUniqueID(); writeStartElementWithPrefix(XML_3MF_ELEMENT_COMPOSITEMATERIALS, XML_3MF_NAMESPACEPREFIX_MATERIAL); // Write Object ID (mandatory) writeIntAttribute(XML_3MF_ATTRIBUTE_COMPOSITEMATERIALS_ID, nResourceID); PModelBaseMaterialResource pBaseMaterialResource = pCompositeMaterials->getBaseMaterialResource(); - ModelResourceID nBaseMaterialResourceID = pBaseMaterialResource->getResourceID()->getUniqueID(); + assertResourceIsInCurrentPath(pBaseMaterialResource->getPackageResourceID()); + ModelResourceID nBaseMaterialResourceID = pBaseMaterialResource->getPackageResourceID()->getModelResourceID(); writeIntAttribute(XML_3MF_ATTRIBUTE_COMPOSITEMATERIALS_MATID, nBaseMaterialResourceID); std::vector matIndices; @@ -650,7 +646,7 @@ namespace NMR { if (!pCompositeMaterials->mapResourceIndexToPropertyID(j, nPropertyID)) { throw CNMRException(NMR_ERROR_INVALIDPROPERTYRESOURCEID); } - m_pPropertyIndexMapping->registerPropertyID(nResourceID, nPropertyID, j); + m_pPropertyIndexMapping->registerPropertyID(nUniqueResourceID, nPropertyID, j); PModelComposite pModelComposite = pCompositeMaterials->getComposite(nPropertyID); for (auto constituents : (*pModelComposite)) { @@ -686,27 +682,29 @@ namespace NMR { void CModelWriterNode100_Model::writeMultiPropertyAttributes(_In_ CModelMultiPropertyGroupResource* pMultiPropertyGroup) { // assemble and write pids and blendmethods - std::vector vctPIDs; + std::vector vctUniqueIDs; std::vector vctBlendMethodString; nfUint32 nLayerCount = pMultiPropertyGroup->getLayerCount(); for (nfUint32 iLayer = 0; iLayer < nLayerCount; iLayer++) { MODELMULTIPROPERTYLAYER layer = pMultiPropertyGroup->getLayer(iLayer); - vctPIDs.push_back(layer.m_nResourceID); + vctUniqueIDs.push_back(layer.m_nUniqueResourceID); if (iLayer > 0) { vctBlendMethodString.push_back(CModelMultiPropertyGroupResource::blendMethodToString(layer.m_nMethod)); } } - ModelResourceID nResourceID = pMultiPropertyGroup->getResourceID()->getUniqueID(); - writeIntAttribute(XML_3MF_ATTRIBUTE_MULTIPROPERTIES_ID, nResourceID); - writeStringAttribute(XML_3MF_ATTRIBUTE_MULTIPROPERTIES_PIDS, fnVectorToSpaceDelimitedString(vctPIDs)); + assertResourceIsInCurrentPath(pMultiPropertyGroup->getPackageResourceID()); + ModelResourceID nModelResourceID = pMultiPropertyGroup->getPackageResourceID()->getModelResourceID(); + writeIntAttribute(XML_3MF_ATTRIBUTE_MULTIPROPERTIES_ID, nModelResourceID); + writeStringAttribute(XML_3MF_ATTRIBUTE_MULTIPROPERTIES_PIDS, fnVectorToSpaceDelimitedString(vctUniqueIDs)); writeStringAttribute(XML_3MF_ATTRIBUTE_MULTIPROPERTIES_BLENDMETHODS, fnVectorToSpaceDelimitedString(vctBlendMethodString)); } void CModelWriterNode100_Model::writeMultiPropertyMultiElements(_In_ CModelMultiPropertyGroupResource* pMultiPropertyGroup) { // assemble and write MultiPropertyElements - ModelResourceID nResourceID = pMultiPropertyGroup->getResourceID()->getUniqueID(); + assertResourceIsInCurrentPath(pMultiPropertyGroup->getPackageResourceID()); + UniqueResourceID nUniqueResourceID = pMultiPropertyGroup->getPackageResourceID()->getUniqueID(); nfUint32 nMultiCount = pMultiPropertyGroup->getCount(); nfUint32 nLayerCount = pMultiPropertyGroup->getLayerCount(); @@ -715,14 +713,14 @@ namespace NMR { if (!pMultiPropertyGroup->mapResourceIndexToPropertyID(iMulti, nPropertyID)) { throw CNMRException(NMR_ERROR_INVALIDPROPERTYRESOURCEID); } - m_pPropertyIndexMapping->registerPropertyID(nResourceID, nPropertyID, iMulti); + m_pPropertyIndexMapping->registerPropertyID(nUniqueResourceID, nPropertyID, iMulti); PModelMultiProperty pMultiProperty = pMultiPropertyGroup->getMultiProperty(nPropertyID); std::vector vctPIndices; for (nfUint32 iLayer = 0; iLayer < nLayerCount; iLayer++) { MODELMULTIPROPERTYLAYER layer = pMultiPropertyGroup->getLayer(iLayer); if (iLayer < pMultiProperty->size()) { - nfUint32 pIndex = m_pPropertyIndexMapping->mapPropertyIDToIndex(layer.m_nResourceID, (*pMultiProperty)[iLayer]); + nfUint32 pIndex = m_pPropertyIndexMapping->mapPropertyIDToIndex(layer.m_nUniqueResourceID, (*pMultiProperty)[iLayer]); vctPIndices.push_back(pIndex); } else { throw CNMRException(NMR_ERROR_MULTIPROPERTIES_NOT_ENOUGH_PROPERTYIDS_SPECIFIED); @@ -784,6 +782,9 @@ namespace NMR { if (m_bWriteSliceExtension) { writeSliceStacks(); } + if (m_bWriteObjects) { + writeObjects(); + } } writeFullEndElement(); @@ -809,10 +810,18 @@ namespace NMR { PModelBuildItem pBuildItem = m_pModel->getBuildItem(nIndex); writeStartElement(XML_3MF_ELEMENT_ITEM); - writeIntAttribute(XML_3MF_ATTRIBUTE_ITEM_OBJECTID, pBuildItem->getObjectID()); + + CModelObject* pObject = pBuildItem->getObject(); + PPackageResourceID pID = pObject->getPackageResourceID(); + + writeIntAttribute(XML_3MF_ATTRIBUTE_ITEM_OBJECTID, pID->getModelResourceID()); + if (pID->getPath() != m_pModel->currentPath()) + writePrefixedStringAttribute(XML_3MF_NAMESPACEPREFIX_PRODUCTION, XML_3MF_PRODUCTION_PATH, pID->getPath()); + if (!pBuildItem->getPartNumber().empty()) writeStringAttribute(XML_3MF_ATTRIBUTE_ITEM_PARTNUMBER, pBuildItem->getPartNumber()); + if (m_bWriteProductionExtension) { if (!pBuildItem->uuid().get()) { throw CNMRException(NMR_ERROR_MISSINGUUID); @@ -848,7 +857,19 @@ namespace NMR { for (nIndex = 0; nIndex < nCount; nIndex++) { PModelComponent pComponent = pComponentsObject->getComponent(nIndex); writeStartElement(XML_3MF_ELEMENT_COMPONENT); - writeIntAttribute(XML_3MF_ATTRIBUTE_COMPONENT_OBJECTID, pComponent->getObjectID()); + PPackageResourceID pObjectID = pComponent->getObject()->getPackageResourceID(); + writeIntAttribute(XML_3MF_ATTRIBUTE_COMPONENT_OBJECTID, pObjectID->getModelResourceID()); + if (pObjectID->getPath() != m_pModel->currentPath()) { + if (m_pModel->currentPath() != m_pModel->rootPath()) { + throw CNMRException(NMR_ERROR_REFERENCESTOODEEP); + } + if (m_bWriteProductionExtension) { + writePrefixedStringAttribute(XML_3MF_NAMESPACEPREFIX_PRODUCTION, XML_3MF_PRODUCTION_PATH, pObjectID->getPath()); + } + else { + throw CNMRException(NMR_ERROR_PRODUCTIONEXTENSION_REQUIRED); + } + } if (pComponent->hasTransform()) writeStringAttribute(XML_3MF_ATTRIBUTE_COMPONENT_TRANSFORM, pComponent->getTransformString()); if (m_bWriteProductionExtension) { @@ -863,17 +884,4 @@ namespace NMR { writeFullEndElement(); } - - ModelResourceID CModelWriterNode100_Model::generateOutputResourceID() - { - ModelResourceID nResourceID = m_ResourceCounter; - if (nResourceID >= XML_3MF_MAXRESOURCECOUNT) - throw CNMRException(NMR_ERROR_INVALIDRESOURCECOUNT); - - m_ResourceCounter++; - - return nResourceID; - - } - } diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index de62d3a8f..b86260201 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1,16 +1,28 @@ -ADD_SUBDIRECTORY (googletest EXCLUDE_FROM_ALL) enable_testing() -SET_TARGET_PROPERTIES (gtest PROPERTIES FOLDER gtest) -SET_TARGET_PROPERTIES (gtest_main PROPERTIES FOLDER gtest) +if (USE_INCLUDED_GTEST) + SET(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + ADD_SUBDIRECTORY (googletest EXCLUDE_FROM_ALL) + SET_TARGET_PROPERTIES (gtest PROPERTIES FOLDER gtest) + SET_TARGET_PROPERTIES (gtest_main PROPERTIES FOLDER gtest) + SET(gtest_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/googletest/googletest") +endif() + +if (USE_INCLUDED_SSL) + SET(LIBRESSL_APPS OFF CACHE BOOL "" FORCE) + SET(LIBRESSL_TESTS OFF CACHE BOOL "" FORCE) + ADD_SUBDIRECTORY (libressl EXCLUDE_FROM_ALL) + SET_TARGET_PROPERTIES (ssl PROPERTIES FOLDER LibreSSL) + SET_TARGET_PROPERTIES (crypto PROPERTIES FOLDER LibreSSL) +endif() -SET(gtest_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/googletest/googletest") add_definitions( -DTESTFILESPATH="${CMAKE_CURRENT_SOURCE_DIR}/TestFiles/") add_definitions( -DLTESTFILESPATH=L"${CMAKE_CURRENT_SOURCE_DIR}/TestFiles/") add_definitions( -DLOUTFILESPATH=L"${CMAKE_BINARY_DIR}/") add_definitions( -DOUTFILESPATH="${CMAKE_BINARY_DIR}/") file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/Writer) +file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/SecureContent) # Test the CPP-Bindings of the library add_subdirectory(CPP_Bindings) diff --git a/Tests/CPP_Bindings/CMakeLists.txt b/Tests/CPP_Bindings/CMakeLists.txt index 8c552c48f..ac631237c 100644 --- a/Tests/CPP_Bindings/CMakeLists.txt +++ b/Tests/CPP_Bindings/CMakeLists.txt @@ -7,11 +7,12 @@ set(SRCS_UNITTEST ./Source/AllTests.cpp ./Source/Attachments.cpp ./Source/BaseMaterialGroup.cpp - ./Source/ColorGroup.cpp - ./Source/CompositeMaterials.cpp ./Source/BeamLattice.cpp ./Source/BeamSets.cpp ./Source/BuildItems.cpp + ./Source/ColorGroup.cpp + ./Source/CompositeMaterials.cpp + ./Source/EncryptionMethods.cpp ./Source/MeshObject.cpp ./Source/MetaData.cpp ./Source/MetaDataGroup.cpp @@ -20,12 +21,15 @@ set(SRCS_UNITTEST ./Source/MultiProperties.cpp ./Source/Object.cpp ./Source/Outbox.cpp + ./Source/ProductionExtension.cpp ./Source/ProgressCallback.cpp ./Source/Properties.cpp ./Source/Reader.cpp + ./Source/SecureContent.cpp ./Source/Slice.cpp ./Source/SliceStack.cpp - ./Source/Utilities.cpp + ./Source/UnitTest_Utilities.cpp + ./Source/UnitTest_EncryptionUtils.cpp ./Source/Writer.cpp ./Source/TextureProperty.cpp ./Source/TextureResources.cpp @@ -39,19 +43,36 @@ add_executable(${TESTNAME} ${SRCS_UNITTEST}) set(STARTUPPROJECT ${TESTNAME}) if (WIN32) - target_compile_options(${TESTNAME} PUBLIC "$<$:/Od;/Ob0;/sdl;/W3;/WX;/FC;/MTd;/wd4996>") - target_compile_options(${TESTNAME} PUBLIC "$<$:/O2;/sdl;/WX;/Oi;/Gy;/FC;/MT;/wd4996>") + target_compile_options(${TESTNAME} PUBLIC "$<$:/Od;/Ob0;/sdl;/W3;/WX;/FC;/MDd;/wd4996>") + target_compile_options(${TESTNAME} PUBLIC "$<$:/O2;/sdl;/WX;/Oi;/Gy;/FC;/MD;/wd4996>") endif() +add_dependencies(${TESTNAME} ssl) +add_dependencies(${TESTNAME} crypto) + target_include_directories(${TESTNAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include ${gtest_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/../libressl/include ${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/Bindings/Cpp ) + target_link_libraries(${TESTNAME} ${PROJECT_NAME} gtest gtest_main) +target_link_libraries(${TESTNAME} ${PROJECT_NAME} ssl crypto) + +if (WIN32) + target_link_libraries(${TESTNAME} ws2_32) +endif() + + set_target_properties(${TESTNAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/") add_test(${TESTNAME} ${CMAKE_CURRENT_BINARY_DIR}/${TESTNAME}) -set(STARTUPPROJECT ${STARTUPPROJECT} PARENT_SCOPE) +find_program(VALGRIND "valgrind") +if(VALGRIND) + add_custom_target(lib3mf_memcheck + COMMAND "${VALGRIND}" --tool=memcheck --leak-check=full --error-exitcode=1 --suppressions=${CMAKE_SOURCE_DIR}/Tests/memcheck/conditional.valgrind.supp $) +endif() +set(STARTUPPROJECT ${STARTUPPROJECT} PARENT_SCOPE) diff --git a/Tests/CPP_Bindings/Include/UnitTest_EncryptionUtils.h b/Tests/CPP_Bindings/Include/UnitTest_EncryptionUtils.h new file mode 100644 index 000000000..5e4355ab1 --- /dev/null +++ b/Tests/CPP_Bindings/Include/UnitTest_EncryptionUtils.h @@ -0,0 +1,179 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +UnitTest_EncryptionUtils.h: Encryption Utilities for UnitTests + +--*/ + +#ifndef __NMR_UNITTEST_ENCRYPTIONUTILS +#define __NMR_UNITTEST_ENCRYPTIONUTILS +#include "lib3mf_implicit.hpp" + +#include +#include +#include + + + +using Byte = Lib3MF_uint8; +using ByteVector = std::vector; + +using PEVP_ENCODE_CTX = std::unique_ptr; +using PBIO = std::unique_ptr; +using PEVP_CIPHER_CTX = std::shared_ptr; +using PEVP_PKEY = std::unique_ptr; +using PRSA = std::unique_ptr; + +struct KekContext { + EVP_PKEY * key; + size_t size; + Lib3MF::CWrapper * wrapper; +}; + +struct DekContext { + std::map ciphers; + Lib3MF::CWrapper * wrapper; +}; + +inline std::shared_ptr make_shared(EVP_CIPHER_CTX * ctx) { + return std::shared_ptr(ctx, ::EVP_CIPHER_CTX_free); +} + +namespace AesMethods { + + namespace Decrypt { + PEVP_CIPHER_CTX init(Lib3MF_uint8 const * key, Lib3MF_uint8 const * iv); + + size_t decrypt(PEVP_CIPHER_CTX ctx, Lib3MF_uint32 size, Lib3MF_uint8 const * cipher, Lib3MF_uint8 * plain); + + bool finish(PEVP_CIPHER_CTX ctx, Lib3MF_uint8 * plain, Lib3MF_uint8 * tag); + } + namespace Encrypt { + PEVP_CIPHER_CTX init(Lib3MF_uint8 const * key, Lib3MF_uint8 const * iv); + + size_t encrypt(PEVP_CIPHER_CTX ctx, Lib3MF_uint32 size, Lib3MF_uint8 const * plain, Lib3MF_uint8 * cipher); + + bool finish(PEVP_CIPHER_CTX ctx, Lib3MF_uint8 * cipher, Lib3MF_uint32 tagSize, Lib3MF_uint8 * tag); + } +} + +namespace RsaMethods { + PEVP_PKEY loadPrivateKey(ByteVector const & privKey); + + PEVP_PKEY loadPublicKey(ByteVector const & pubKey); + + size_t getSize(EVP_PKEY * evpKey); + + size_t decrypt(EVP_PKEY * evpKey, size_t cipherSize, uint8_t const * cipher, uint8_t * plain); + + size_t encrypt(EVP_PKEY * evpKey, size_t plainSize, uint8_t const * plain, uint8_t * cipher); +} + +struct EncryptionCallbacks { + + static void cleanup(); + + /** + * ContentEncryptionCallback - A callback to encrypt/decrypt content called on each resource encrypted. This might be called several times depending on content size. If cipher size is zero, clients must return the result of authenticated tag validation + * + * @param[in] pCEKParams - The params of the encryption process. + * @param[in] nInputBufferSize - Number of elements in buffer + * @param[in] pInputBuffer - uint8 buffer of Buffer to the original data. In encrypting, this will be the plain data. If derypting, this will be the cipher data + * @param[in] nOutputBufferSize - Number of elements in buffer + * @param[out] pOutputNeededCount - will be filled with the count of the written elements, or needed buffer size. + * @param[out] pOutputBuffer - uint8 buffer of Buffer to hold the transformed data. When encrypting, this will be the cipher data. When decrypting, this shall be the plain data. If buffer is null, neededBytes return the necessary amount of bytes. Otherwise, amount of bytes decrypted if succeed or zero on error + * @param[in] pUserData - Userdata that is passed to the callback function + */ + + static void dataEncryptClientCallback( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 plainSize, + const Lib3MF_uint8 * plainBuffer, + const Lib3MF_uint64 cipherSize, + Lib3MF_uint64 * cipherNeeded, + Lib3MF_uint8 * cipherBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status); + + + /** + * KeyWrappingCallback - A callback used to wrap (encrypt) the content key available in keystore resource group + * + * @param[in] accessRight - The information about the parameters used used to wrap the key to the contents + * @param[in] plainSize - Number of elements in buffer + * @param[in] plainBuffer - uint8 buffer of Buffer to the input value. When encrypting, this should be the plain key. When decrypting, this should be the key cipher. + * @param[in] cipherSize - Number of elements in buffer + * @param[out] cipherNeeded - will be filled with the count of the written elements, or needed buffer size. + * @param[out] cipherBuffer - uint8 buffer of Buffer where the data will be placed. When encrypting, this will be the key cipher. When decrypting, this will be the plain key. When buffer is null, neededBytes contains the required bytes to run. When not, Amount it reflects the encrypted/decrypted bytes when succeed or zero when error + * @param[in] userData - Userdata that is passed to the callback function + */ + static void keyEncryptClientCallback( + Lib3MF_AccessRight accessRight, + Lib3MF_uint64 plainSize, + const Lib3MF_uint8 * plainBuffer, + const Lib3MF_uint64 cipherSize, + Lib3MF_uint64* cipherNeeded, + Lib3MF_uint8 * cipherBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status); + + static void dataDecryptClientCallback( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 cipherSize, + const Lib3MF_uint8 * cipherBuffer, + const Lib3MF_uint64 plainSize, + Lib3MF_uint64 * plainNeeded, + Lib3MF_uint8 * plainBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status); + + static void keyDecryptClientCallback( + Lib3MF_AccessRight accessRight, + Lib3MF_uint64 cipherSize, + const Lib3MF_uint8 * cipherBuffer, + const Lib3MF_uint64 plainSize, + Lib3MF_uint64* plainNeeded, + Lib3MF_uint8 * plainBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status); + + /** + * RandomNumberCallback - Callback to generate random numbers + * + * @param[in] nByteData - Point to a buffer where to store the data + * @param[in] nNumBytes - Size of available bytes in the buffer + * @param[in] pUserData - Userdata that is passed to the callback function + * @param[out] pBytesWritten - Number of bytes generated when succeed. 0 or less if failed. + */ + static void randomNumberCallback( + Lib3MF_uint64 nByteData, + Lib3MF_uint64 nNumBytes, + Lib3MF_pvoid pUserData, + Lib3MF_uint64 * pBytesWritten); +}; +#endif \ No newline at end of file diff --git a/Tests/CPP_Bindings/Include/UnitTest_Utilities.h b/Tests/CPP_Bindings/Include/UnitTest_Utilities.h index 43beab5f1..ec6d6736a 100644 --- a/Tests/CPP_Bindings/Include/UnitTest_Utilities.h +++ b/Tests/CPP_Bindings/Include/UnitTest_Utilities.h @@ -76,6 +76,14 @@ inline std::vector ReadFileIntoBuffer(std::string sFileName) return buffer; } +inline void WriteBufferToFile(std::vector const & buffer, std::string sFileName) +{ + std::ofstream file(sFileName, std::ios::binary); + for (Lib3MF_uint8 cByte: buffer) { + file.put(cByte); + } + file.close(); +} inline sLib3MFTransform getIdentityTransform() { diff --git a/Tests/CPP_Bindings/Source/BeamLattice.cpp b/Tests/CPP_Bindings/Source/BeamLattice.cpp index e250c2723..b256b0318 100644 --- a/Tests/CPP_Bindings/Source/BeamLattice.cpp +++ b/Tests/CPP_Bindings/Source/BeamLattice.cpp @@ -158,6 +158,113 @@ namespace Lib3MF ASSERT_FALSE(true); } + TEST_F(BeamLattice, BallMode) + { + beamLattice->SetBallOptions(eBeamLatticeBallMode::None, 1.2); + + sBeam beam; + beam.m_Radii[0] = 1.0; + beam.m_Radii[1] = 1.0; + beam.m_Indices[0] = 0; + beam.m_Indices[1] = 1; + beamLattice->AddBeam(beam); + beam.m_Indices[0] = 1; + beam.m_Indices[1] = 2; + beamLattice->AddBeam(beam); + ASSERT_EQ(beamLattice->GetBallCount(), 0); + + beamLattice->SetBallOptions(eBeamLatticeBallMode::Mixed, 1.2); + sBall ball; + + ball.m_Index = 1; + ball.m_Radius = 1.5; + beamLattice->AddBall(ball); + ASSERT_EQ(beamLattice->GetBallCount(), 1); + + beamLattice->SetBallOptions(eBeamLatticeBallMode::All, 1.2); + ASSERT_EQ(beamLattice->GetBallCount(), mesh->GetVertexCount()); + + // Ball order can change between platforms + std::map ballMap; + + for (Lib3MF_uint32 iBall = 0; iBall < beamLattice->GetBallCount(); iBall++) { + auto outBall = beamLattice->GetBall(iBall); + ballMap[outBall.m_Index] = outBall.m_Radius; + } + + ASSERT_DOUBLE_EQ(ballMap[0], 1.2); + ASSERT_DOUBLE_EQ(ballMap[1], ball.m_Radius); + ASSERT_DOUBLE_EQ(ballMap[2], 1.2); + + ball.m_Index = 2; + ball.m_Radius = 3.1; + beamLattice->AddBall(ball); + + auto writer = model->QueryWriter("3mf"); + std::vector buffer; + writer->WriteToBuffer(buffer); + + auto readModel = wrapper->CreateModel(); + auto reader = readModel->QueryReader("3mf"); + reader->SetStrictModeActive(true); + reader->ReadFromBuffer(buffer); + + auto meshObjects = readModel->GetMeshObjects(); + PLib3MFMeshObject firstMesh; + while (meshObjects->MoveNext()) { + if (!firstMesh.get()) { + firstMesh = meshObjects->GetCurrentMeshObject(); + } + else { + auto meshObject = meshObjects->GetCurrentMeshObject(); + auto readBeamLattice = meshObject->BeamLattice(); + eBeamLatticeBallMode ballMode; + Lib3MF_double defaultBallRadius; + readBeamLattice->GetBallOptions(ballMode, defaultBallRadius); + ASSERT_EQ(ballMode, eBeamLatticeBallMode::All); + + ballMap.clear(); + for (Lib3MF_uint32 iBall = 0; iBall < beamLattice->GetBallCount(); iBall++) { + auto outBall = beamLattice->GetBall(iBall); + ballMap[outBall.m_Index] = outBall.m_Radius; + } + + ASSERT_DOUBLE_EQ(ballMap[0], 1.2); + ASSERT_DOUBLE_EQ(ballMap[1], 1.5); + ASSERT_DOUBLE_EQ(ballMap[2], ball.m_Radius); + return; + } + } + + } + + TEST_F(BeamLattice, BallModeAll) + { + beamLattice->SetBallOptions(eBeamLatticeBallMode::All, 1.2); + + sBeam beam; + + beam.m_Radii[0] = 1.0; + beam.m_Radii[1] = 1.0; + beam.m_Indices[0] = 0; + beam.m_Indices[1] = 2; + beamLattice->AddBeam(beam); + + ASSERT_EQ(beamLattice->GetBallCount(), 2); + + std::vector outBalls; + beamLattice->GetBalls(outBalls); + + // Ball order can change between platforms + std::map ballMap; + + for (auto outBall : outBalls) { + ballMap[outBall.m_Index] = outBall.m_Radius; + } + + ASSERT_EQ(ballMap.size(), beamLattice->GetBallCount()); + ASSERT_DOUBLE_EQ(ballMap[2], 1.2); + } TEST_F(BeamLattice, GeometryShouldFail) { @@ -195,6 +302,41 @@ namespace Lib3MF catch (ELib3MFException) { ASSERT_TRUE(true); } + + //Invalid ball options, should fail + try { + beamLattice->SetBallOptions(eBeamLatticeBallMode::All, 0.0); + } + catch (ELib3MFException) { + ASSERT_TRUE(true); + } + + beamLattice->SetBallOptions(eBeamLatticeBallMode::All, 1.6); + + sBall ball; + ball.m_Index = 0; + ball.m_Radius = 2.2; + // This one works + beamLattice->AddBall(ball); + + ball.m_Radius = -2.2; + try { + beamLattice->SetBall(0, ball); + ASSERT_FALSE(true); + } + catch (ELib3MFException) { + ASSERT_TRUE(true); + } + + ball.m_Index = 2; + ball.m_Radius = 2.2; + try { + beamLattice->AddBall(ball); + ASSERT_FALSE(true); + } + catch (ELib3MFException) { + ASSERT_TRUE(true); + } } TEST_F(BeamLattice, Geometry) @@ -229,6 +371,28 @@ namespace Lib3MF beam.m_Radii[0] = 4; beam.m_Radii[1] = 3.2; beamLattice->SetBeam(2, beam); + + beamLattice->SetBallOptions(eBeamLatticeBallMode::Mixed, 1.2); + + ASSERT_EQ(beamLattice->GetBallCount(), 0); + sBall ball; + + ball.m_Index = 0; + ball.m_Radius = 2.0; + beamLattice->AddBall(ball); + + ball.m_Index = 1; + ball.m_Radius = 2.4; + beamLattice->AddBall(ball); + + ball.m_Index = 2; + ball.m_Radius = 1.8; + beamLattice->AddBall(ball); + ASSERT_EQ(beamLattice->GetBallCount(), 3); + + auto outBall = beamLattice->GetBall(2); + ASSERT_EQ(outBall.m_Index, ball.m_Index); + ASSERT_DOUBLE_EQ(outBall.m_Radius, ball.m_Radius); } TEST_F(BeamLattice, GeometryBulk) @@ -267,6 +431,49 @@ namespace Lib3MF catch (ELib3MFException) { ASSERT_TRUE(true); } + + // fix beams for adding balls + beams[0].m_Indices[0] = 0; + beamLattice->SetBeams(beams); + + beamLattice->SetBallOptions(eBeamLatticeBallMode::All, 1.8); + + sBall ball; + std::vector balls(2); + ball.m_Index = 1; + ball.m_Radius = 1.9; + balls[0] = ball; + ball.m_Index = 2; + ball.m_Radius = 2.1; + balls[1] = ball; + + beamLattice->SetBalls(balls); + + std::vector outBalls; + beamLattice->GetBalls(outBalls); + + // Ball order can change between platforms + std::map ballMap; + + for (auto outBall : outBalls) { + ballMap[outBall.m_Index] = outBall.m_Radius; + } + + ASSERT_DOUBLE_EQ(ballMap[0], 1.8); + + for (int i = 1; i < 3; i++) { + ASSERT_DOUBLE_EQ(ballMap[i], balls[i-1].m_Radius); + } + + // modify balls to fail: + balls[0].m_Index = 12; + try { + beamLattice->SetBalls(balls); + ASSERT_FALSE(true); + } + catch (ELib3MFException) { + ASSERT_TRUE(true); + } } TEST_F(BeamLattice, BeamSet) diff --git a/Tests/CPP_Bindings/Source/BeamSets.cpp b/Tests/CPP_Bindings/Source/BeamSets.cpp index 9b3173a3b..ef30f5ca1 100644 --- a/Tests/CPP_Bindings/Source/BeamSets.cpp +++ b/Tests/CPP_Bindings/Source/BeamSets.cpp @@ -68,6 +68,17 @@ namespace Lib3MF } beamLattice->SetBeams(beams); + + beamLattice->SetBallOptions(eBeamLatticeBallMode::Mixed, 1.8); + sBall ball; + ball.m_Radius = 1.8; + std::vector balls(3); + for (int i = 0; i < 3; i++) { + ball.m_Index = i; + balls[i] = ball; + } + + beamLattice->SetBalls(balls); } virtual void TearDown() { model.reset(); @@ -101,6 +112,45 @@ namespace Lib3MF ASSERT_EQ(beamSet->GetIdentifier(), ident); } + TEST_F(BeamSet, UniqueIdentifier) + { + auto beamSet = beamLattice->AddBeamSet(); + std::string ident1 = "ASDF"; + std::string ident2 = "GHJKL"; + beamSet->SetIdentifier(ident1); + + beamSet = beamLattice->AddBeamSet(); + beamSet->SetIdentifier(ident2); + + beamSet = beamLattice->AddBeamSet(); + try { + beamSet->SetIdentifier(ident1); + ASSERT_FALSE(true); + } + catch (ELib3MFException) { + ASSERT_TRUE(true); + } + } + + TEST_F(BeamSet, ReadUniqueIdentifier) + { + std::string fName("BeamSet_Unique.3mf"); + auto model = wrapper->CreateModel(); + { + auto reader = model->QueryReader("3mf"); + reader->ReadFromFile(sTestFilesPath + "/" + "BeamLattice" + "/" + fName); + ASSERT_EQ(reader->GetWarningCount(), 0); + } + + fName = "BeamSet_Not_Unique.3mf"; + model = wrapper->CreateModel(); + { + auto reader = model->QueryReader("3mf"); + reader->ReadFromFile(sTestFilesPath + "/" + "BeamLattice" + "/" + fName); + ASSERT_NE(reader->GetWarningCount(), 0); + } + } + TEST_F(BeamSet, References) { auto beamSet = beamLattice->AddBeamSet(); @@ -133,4 +183,35 @@ namespace Lib3MF } + TEST_F(BeamSet, BallReferences) + { + auto beamSet = beamLattice->AddBeamSet(); + + ASSERT_EQ(beamSet->GetBallReferenceCount(), 0); + + Lib3MF_uint32 nBallReferences = 2; + std::vector ballReferences(nBallReferences); + ballReferences[0] = 2; + ballReferences[1] = 5; + try { + beamSet->SetBallReferences(ballReferences); + ASSERT_FALSE(true); + } + catch (ELib3MFException) { + ASSERT_TRUE(true); + } + + ballReferences[1] = 1; + beamSet->SetBallReferences(ballReferences); + + ASSERT_EQ(beamSet->GetBallReferenceCount(), nBallReferences); + + std::vector ballReferencesOut; + beamSet->GetBallReferences(ballReferencesOut); + ASSERT_EQ(beamSet->GetBallReferenceCount(), ballReferencesOut.size()); + for (size_t i = 0; i < ballReferencesOut.size(); i++) { + ASSERT_EQ(ballReferencesOut[i], ballReferences[i]); + } + } + } diff --git a/Tests/CPP_Bindings/Source/EncryptionMethods.cpp b/Tests/CPP_Bindings/Source/EncryptionMethods.cpp new file mode 100644 index 000000000..d0ef970e8 --- /dev/null +++ b/Tests/CPP_Bindings/Source/EncryptionMethods.cpp @@ -0,0 +1,359 @@ +#include "UnitTest_Utilities.h" +#include "UnitTest_EncryptionUtils.h" +#include "lib3mf_implicit.hpp" + +#include + +namespace Lib3MF { + + class EncryptionMethods : public ::testing::Test { + protected: + PModel model; + PEVP_PKEY privateKey; + sPosition pVertices[8]; + sTriangle pTriangles[12]; + std::string publicKey; + + public: + EncryptionMethods(): privateKey(nullptr, ::EVP_PKEY_free) { + ByteVector key = ReadFileIntoBuffer(sTestFilesPath + "/SecureContent/sample.pem"); + privateKey = RsaMethods::loadPrivateKey(key); + ByteVector pubKey = ReadFileIntoBuffer(sTestFilesPath + "/SecureContent/sample.pub.pem"); + publicKey = std::string(pubKey.begin(), pubKey.end()); + model = wrapper->CreateModel(); + } + + virtual ~EncryptionMethods() { + //attempt to solve leaks + EncryptionCallbacks::cleanup(); + } + + static PWrapper wrapper; + + static void SetUpTestCase() { + wrapper = CWrapper::loadLibrary(); + } + + virtual void SetUp() { + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + pVertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + pVertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + pVertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + pVertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + pVertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + pVertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + pVertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + pVertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + pTriangles[0] = fnCreateTriangle(2, 1, 0); + pTriangles[1] = fnCreateTriangle(0, 3, 2); + pTriangles[2] = fnCreateTriangle(4, 5, 6); + pTriangles[3] = fnCreateTriangle(6, 7, 4); + pTriangles[4] = fnCreateTriangle(0, 1, 5); + pTriangles[5] = fnCreateTriangle(5, 4, 0); + pTriangles[6] = fnCreateTriangle(2, 3, 7); + pTriangles[7] = fnCreateTriangle(7, 6, 2); + pTriangles[8] = fnCreateTriangle(1, 2, 6); + pTriangles[9] = fnCreateTriangle(6, 5, 1); + pTriangles[10] = fnCreateTriangle(3, 0, 4); + pTriangles[11] = fnCreateTriangle(4, 7, 3); + model = wrapper->CreateModel(); + + model->SetRandomNumberCallback(EncryptionCallbacks::randomNumberCallback, nullptr); + + } + + virtual void TearDown() { + model.reset(); + } + + void reset(DekContext & context) { + context.ciphers.clear(); + context.wrapper = wrapper.get(); + } + + void reset(KekContext & context) { + context.key = privateKey.get(); + context.wrapper = wrapper.get(); + } + + + void generateTestFile(bool compressed, std::string const & fileName) { + ByteVector buffer; + { + PModel modelToCrpt = wrapper->CreateModel(); + modelToCrpt->SetRandomNumberCallback(EncryptionCallbacks::randomNumberCallback, nullptr); + + PReader reader = modelToCrpt->QueryReader("3mf"); + reader->ReadFromFile(sTestFilesPath + "/Production/detachedmodel.3mf"); + + auto meshObjIt = modelToCrpt->GetMeshObjects(); + ASSERT_EQ(meshObjIt->Count(), 1); + ASSERT_TRUE(meshObjIt->MoveNext()); + auto meshObj = meshObjIt->GetCurrentMeshObject(); + ASSERT_NE(nullptr, meshObj); + auto part = meshObj->PackagePart(); + ASSERT_NE(nullptr, meshObj); + auto keyStore = modelToCrpt->GetKeyStore(); + auto consumer = keyStore->AddConsumer("LIB3MF#TEST", "contentKey", publicKey); + auto rdGroup = keyStore->AddResourceDataGroup(); + rdGroup->AddAccessRight(consumer.get(), + eWrappingAlgorithm::RSA_OAEP, + eMgfAlgorithm::MGF1_SHA1, + eDigestMethod::SHA1); + + ByteVector aad = { 'l', 'i', 'b', '3', 'm', 'f', 's', 'a', 'm', 'p', 'l', 'e' }; + auto rd = keyStore->AddResourceData(rdGroup.get(), part.get(), + eEncryptionAlgorithm::AES256_GCM, (compressed? eCompression::Deflate : eCompression::NoCompression), aad); + + PWriter writer = modelToCrpt->QueryWriter("3mf"); + DekContext dekUserData; + reset(dekUserData); + writer->SetContentEncryptionCallback(EncryptionCallbacks::dataEncryptClientCallback, (Lib3MF_pvoid)(&dekUserData)); + + KekContext kekUserData; + reset(kekUserData); + writer->AddKeyWrappingCallback("LIB3MF#TEST", EncryptionCallbacks::keyEncryptClientCallback, &kekUserData); + + writer->WriteToBuffer(buffer); + + auto count = writer->GetWarningCount(); + ASSERT_EQ(count, 0); + //WriteBufferToFile(buffer, sOutFilesPath + "/SecureContent/" + fileName); + } + { + PModel encryptedModel = wrapper->CreateModel(); + PReader reader = encryptedModel->QueryReader("3mf"); + DekContext dekUserData; + reset(dekUserData); + reader->SetContentEncryptionCallback(EncryptionCallbacks::dataDecryptClientCallback, (Lib3MF_pvoid)(&dekUserData)); + + KekContext kekUserData; + reset(kekUserData); + reader->AddKeyWrappingCallback("LIB3MF#TEST", EncryptionCallbacks::keyDecryptClientCallback, &kekUserData); + + reader->ReadFromBuffer(buffer); + + auto meshObjIt = encryptedModel->GetMeshObjects(); + ASSERT_EQ(meshObjIt->Count(), 1); + auto objCount = encryptedModel->GetObjects(); + ASSERT_EQ(objCount->Count(), 28); + } + } + }; + + PWrapper EncryptionMethods::wrapper; + + TEST_F(EncryptionMethods, RemoveEncryptionFromResource) { + + auto reader = model->QueryReader("3mf"); + //set descryption callbacks in the reader + DekContext dekUserData; + reset(dekUserData); + reader->SetContentEncryptionCallback(EncryptionCallbacks::dataDecryptClientCallback, (Lib3MF_pvoid)(&dekUserData)); + + KekContext kekUserData; + reset(kekUserData); + reader->AddKeyWrappingCallback("LIB3MF#TEST", EncryptionCallbacks::keyDecryptClientCallback, &kekUserData); + + //do the actual reading + reader->ReadFromFile(sTestFilesPath + "/SecureContent/keystore_encrypted_compressed.3mf"); + + //assert model assumptions + auto resources = model->GetResources(); + ASSERT_EQ(28, resources->Count()); + + auto keyStore = model->GetKeyStore(); + ASSERT_EQ(1, keyStore->GetResourceDataGroupCount()); + ASSERT_EQ(1, keyStore->GetResourceDataCount()); + + //find the target resource data and remove it from keystore + Lib3MF::PPackagePart part = model->FindOrCreatePackagePart("/3D/3dexternal.model"); + auto resourceData = keyStore->FindResourceData(part.get()); + ASSERT_NE(nullptr, resourceData); + keyStore->RemoveResourceData(resourceData.get()); + + //write model again + PWriter writer = model->QueryWriter("3mf"); + ByteVector buffer; + writer->WriteToBuffer(buffer); + } + + TEST_F(EncryptionMethods, WriteEncryptedProductionModel) { + Lib3MF::PModel secureModel = wrapper->CreateModel(); + secureModel->SetRandomNumberCallback(EncryptionCallbacks::randomNumberCallback, nullptr); + + //create a mesh and add to the model + Lib3MF::PMeshObject meshObject = secureModel->AddMeshObject(); + meshObject->SetGeometry(CLib3MFInputVector(pVertices, 8), CLib3MFInputVector(pTriangles, 12)); + sTransform transformation; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) + transformation.m_Fields[i][j] = Lib3MF_single(i - j); + } + secureModel->AddBuildItem(meshObject.get(), transformation); + + //set the mesh in a non root model + std::string path = "/3D/securemesh.model"; + auto secureMeshPart = secureModel->FindOrCreatePackagePart(path); + meshObject->SetPackagePart(secureMeshPart.get()); + + Lib3MF::PKeyStore keyStore = secureModel->GetKeyStore(); + keyStore->SetUUID("b7aa9c75-5fbd-48c1-a893-40289e45ab8f"); + + //add a consumer + std::string keyValue = "-----BEGIN PUBLIC KEY-----\r\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw53q4y2KB2WcoOBUE9OE\r\nXI0OCzUf4SI1J6fDx6XeDJ8PzqxN4pPRtXgtKfp/RiSL0invf7ASfkBMcXuhD8XP\r\n0uki3JIzvsxTH+Jnnz/PrYnS9DFa6c9MYciTIV8vC4u03vkZH6OuGq4rWeSZuNCT\r\nCgT59q67Ly6OytNsQgsDHL2QO8xhpYdQ4bx7F0uNn5LAxFyA0ymsFsgSSLONJWza\r\nVtsq9jvkIOEdTzYq52PAXMUIpegbyqSheNlmedcss8teqiZGnCOxpBxL3z+ogcFe\r\nnX1S8kq2UhzOjXLEjPs9B0SchwXSadephL89shJwra+30NS3R3frwfCz+a3H6wTV\r\nBwIDAQAB\r\n-----END PUBLIC KEY-----\r\n\t\t"; + std::string keyId = "KEK_xxx"; + std::string consumerId = "HP#MOP44B#SG5693454"; + Lib3MF::PConsumer consumer = keyStore->AddConsumer(consumerId, keyId, keyValue); + + //add a resource data group + Lib3MF::PResourceDataGroup dataGroup = keyStore->AddResourceDataGroup(); + + //establish consumer access to the datagroup + Lib3MF::PAccessRight accessRight = dataGroup->AddAccessRight( + consumer.get(), + Lib3MF::eWrappingAlgorithm::RSA_OAEP, + Lib3MF::eMgfAlgorithm::MGF1_SHA1, + Lib3MF::eDigestMethod::SHA1); + + + ByteVector aad = { 1, 2 , 3, 4, 5, 6, 7, 8, 9, 10 }; + //add resource data as part of the datagroup + Lib3MF::PResourceData resourceData = keyStore->AddResourceData( + dataGroup.get(), + secureMeshPart.get(), + Lib3MF::eEncryptionAlgorithm::AES256_GCM, + Lib3MF::eCompression::Deflate, + aad); + + + PWriter writer = secureModel->QueryWriter("3mf"); + //set encryption callbacks + DekContext writeDekUserData; + reset(writeDekUserData); + writer->SetContentEncryptionCallback(EncryptionCallbacks::dataEncryptClientCallback, (Lib3MF_pvoid)(&writeDekUserData)); + + KekContext writeKekUserData; + reset(writeKekUserData); + writer->AddKeyWrappingCallback(consumerId, EncryptionCallbacks::keyEncryptClientCallback, &writeKekUserData); + + //do the actual writing + ByteVector buffer; + writer->WriteToBuffer(buffer); + + //re-read the model + auto reader = model->QueryReader("3mf"); + //sets decryption callbacks + DekContext readDekUserData; + reset(readDekUserData); + reader->SetContentEncryptionCallback(EncryptionCallbacks::dataDecryptClientCallback, (Lib3MF_pvoid)(&readDekUserData)); + + KekContext readKekUserData; + reset(readKekUserData); + reader->AddKeyWrappingCallback(consumerId, EncryptionCallbacks::keyDecryptClientCallback, &readKekUserData); + + //do the actual reading + reader->ReadFromBuffer(buffer); + + //assert assumptions + auto meshObj = model->GetMeshObjects(); + ASSERT_EQ(1, meshObj->Count()); + } + + + + TEST_F(EncryptionMethods, WriteAdditionalConsumerToEncryptedModel) { + ByteVector buffer; + { + //read existing model + auto reader = model->QueryReader("3mf"); + DekContext dekUserData; + reset(dekUserData); + reader->SetContentEncryptionCallback(EncryptionCallbacks::dataDecryptClientCallback, (Lib3MF_pvoid)(&dekUserData)); + + KekContext kekUserData; + reset(kekUserData); + reader->AddKeyWrappingCallback("LIB3MF#TEST", EncryptionCallbacks::keyDecryptClientCallback, &kekUserData); + + //do the actual reading + reader->ReadFromFile(sTestFilesPath + "/SecureContent/keystore_encrypted.3mf"); + + //assert model assumptions + auto meshObjIt = model->GetMeshObjects(); + ASSERT_EQ(meshObjIt->Count(), 1); + + auto keyStore = model->GetKeyStore(); + ASSERT_EQ(keyStore->GetConsumerCount(), 1); + ASSERT_EQ(keyStore->GetResourceDataCount(), 1); + ASSERT_EQ(keyStore->GetResourceDataGroupCount(), 1); + + auto dataGroup = keyStore->GetResourceDataGroup(0); + auto existingConsumer = keyStore->GetConsumer(0); + auto existingAccess = dataGroup->FindAccessRightByConsumer(existingConsumer.get()); + + ASSERT_NE(existingAccess, nullptr); + + //add new consumer + auto consumer = keyStore->AddConsumer("LIB3MF#TEST2", "", ""); + + + //add rights for the consumer to the existing datagroup + Lib3MF::PAccessRight accessRight = dataGroup->AddAccessRight( + consumer.get(), + Lib3MF::eWrappingAlgorithm::RSA_OAEP, + Lib3MF::eMgfAlgorithm::MGF1_SHA1, + Lib3MF::eDigestMethod::SHA1); + //write new model + auto writer = model->QueryWriter("3mf"); + reset(dekUserData); + writer->SetContentEncryptionCallback(EncryptionCallbacks::dataEncryptClientCallback, &dekUserData); + reset(kekUserData); + writer->AddKeyWrappingCallback("LIB3MF#TEST2", EncryptionCallbacks::keyEncryptClientCallback, &kekUserData); + //do the actual writing + writer->WriteToBuffer(buffer); + } + + //reset model for assertion of assumption + model.reset(); + + model = wrapper->CreateModel(); + model->SetRandomNumberCallback(EncryptionCallbacks::randomNumberCallback, nullptr); + { + //read generated model + auto reader = model->QueryReader("3mf"); + DekContext dekUserData; + reset(dekUserData); + reader->SetContentEncryptionCallback(EncryptionCallbacks::dataDecryptClientCallback, (Lib3MF_pvoid)(&dekUserData)); + + KekContext kekUserData; + reset(kekUserData); + reader->AddKeyWrappingCallback("LIB3MF#TEST2", EncryptionCallbacks::keyDecryptClientCallback, &kekUserData); + reader->ReadFromBuffer(buffer); + + //assert assumptions + auto meshObjIt = model->GetMeshObjects(); + ASSERT_EQ(meshObjIt->Count(), 1); + + auto keyStore = model->GetKeyStore(); + ASSERT_EQ(keyStore->GetConsumerCount(), 2); + ASSERT_EQ(keyStore->GetResourceDataGroupCount(), 1); + auto dataGroup = keyStore->GetResourceDataGroup(0); + for (Lib3MF_uint32 i = 0; i < keyStore->GetConsumerCount(); ++i) { + auto c = keyStore->GetConsumer(i); + auto a = dataGroup->FindAccessRightByConsumer(c.get()); + ASSERT_NE(a, nullptr); + } + } + } + + TEST_F(EncryptionMethods, MakeExistingModelEncrypted) { + generateTestFile(false, "keystore_encrypted.3mf"); + generateTestFile(true, "keystore_encrypted_compressed.3mf"); + } + + +} diff --git a/Tests/CPP_Bindings/Source/Model.cpp b/Tests/CPP_Bindings/Source/Model.cpp index fd0d60c24..89ae9f761 100644 --- a/Tests/CPP_Bindings/Source/Model.cpp +++ b/Tests/CPP_Bindings/Source/Model.cpp @@ -150,7 +150,7 @@ namespace Lib3MF ASSERT_FALSE(true); } catch (ELib3MFException &e) { - ASSERT_EQ(e.getErrorCode(), LIB3MF_ERROR_INVALIDBASEMATERIALGROUP); + ASSERT_EQ(e.getErrorCode(), LIB3MF_ERROR_RESOURCENOTFOUND); } } diff --git a/Tests/CPP_Bindings/Source/Object.cpp b/Tests/CPP_Bindings/Source/Object.cpp index 302eb3cf1..3bfc73ca8 100644 --- a/Tests/CPP_Bindings/Source/Object.cpp +++ b/Tests/CPP_Bindings/Source/Object.cpp @@ -355,11 +355,13 @@ namespace Lib3MF TEST_F(ObjectThumbnail, ReadObjectThumbnail) { - auto reader = model->QueryReader("3mf"); + auto readModel = wrapper->CreateModel(); + + auto reader = readModel->QueryReader("3mf"); reader->ReadFromFile(sTestFilesPath+"/Objects/HelixWithThumbnail.3mf"); - ASSERT_EQ(model->GetAttachmentCount(), 1); - auto meshObjects = model->GetMeshObjects(); + ASSERT_EQ(readModel->GetAttachmentCount(), 1); + auto meshObjects = readModel->GetMeshObjects(); ASSERT_EQ(meshObjects->MoveNext(), true); auto mesh = meshObjects->GetCurrentMeshObject(); auto thumbnail = mesh->GetThumbnailAttachment(); @@ -369,7 +371,9 @@ namespace Lib3MF TEST_F(ObjectThumbnail, ReadInvalidObjectThumbnail) { - auto reader = model->QueryReader("3mf"); + auto readModel = wrapper->CreateModel(); + + auto reader = readModel->QueryReader("3mf"); reader->AddRelationToRead("otherrelationship"); reader->ReadFromFile(sTestFilesPath + "/Objects/HelixWithThumbnail_IncorrectRelationship.3mf"); CheckReaderWarnings(reader, 1); diff --git a/Tests/CPP_Bindings/Source/ProductionExtension.cpp b/Tests/CPP_Bindings/Source/ProductionExtension.cpp new file mode 100644 index 000000000..5cf929f9a --- /dev/null +++ b/Tests/CPP_Bindings/Source/ProductionExtension.cpp @@ -0,0 +1,215 @@ +/*++ + +Copyright (C) 2019 3MF Consortium + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Abstract: + +UnitTest_ProductionExtension.cpp: Defines Unittests for the Production extension +classes + +--*/ + +#include "UnitTest_Utilities.h" +#include "lib3mf_implicit.hpp" + +namespace Lib3MF +{ + class ProductionExtension : public ::testing::Test { + protected: + sPosition pVertices[8]; + sTriangle pTriangles[12]; + + virtual void SetUp() { + model = wrapper->CreateModel(); + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + pVertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + pVertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + pVertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + pVertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + pVertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + pVertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + pVertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + pVertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + pTriangles[0] = fnCreateTriangle(2, 1, 0); + pTriangles[1] = fnCreateTriangle(0, 3, 2); + pTriangles[2] = fnCreateTriangle(4, 5, 6); + pTriangles[3] = fnCreateTriangle(6, 7, 4); + pTriangles[4] = fnCreateTriangle(0, 1, 5); + pTriangles[5] = fnCreateTriangle(5, 4, 0); + pTriangles[6] = fnCreateTriangle(2, 3, 7); + pTriangles[7] = fnCreateTriangle(7, 6, 2); + pTriangles[8] = fnCreateTriangle(1, 2, 6); + pTriangles[9] = fnCreateTriangle(6, 5, 1); + pTriangles[10] = fnCreateTriangle(3, 0, 4); + pTriangles[11] = fnCreateTriangle(4, 7, 3); + } + virtual void TearDown() { + model.reset(); + } + + PModel model; + + static void SetUpTestCase() { + wrapper = CWrapper::loadLibrary(); + } + static PWrapper wrapper; + }; + PWrapper ProductionExtension::wrapper; + + TEST_F(ProductionExtension, ManipulatePaths) + { + auto rootPart = model->RootModelPart(); + auto otherPart = model->FindOrCreatePackagePart("/somepart"); + ASSERT_SPECIFIC_THROW(otherPart->SetPath(rootPart->GetPath()), ELib3MFException); + } + + TEST_F(ProductionExtension, ReadInspect) + { + auto buffer = ReadFileIntoBuffer(sTestFilesPath + "/Production/" + "2ProductionBoxes.3mf"); + auto reader3MF = model->QueryReader("3mf"); + reader3MF->ReadFromBuffer(buffer); + CheckReaderWarnings(reader3MF, 0); + } + + //TEST_F(ProductionExtension, ReadWrite) + //{ + //} + + //TEST_F(ProductionExtension, ReadWriteReadInspect) + //{ + //} + + TEST_F(ProductionExtension, ReadModifyWrite) + { + auto buffer = ReadFileIntoBuffer(sTestFilesPath + "/Production/" + "2ProductionBoxes.3mf"); + auto reader3MF = model->QueryReader("3mf"); + reader3MF->ReadFromBuffer(buffer); + CheckReaderWarnings(reader3MF, 0); + + auto resources = model->GetResources(); + auto partToChange = model->FindOrCreatePackagePart("/3D/box2.model"); + partToChange->SetPath("/3D/boxPathChanged.model"); + + auto newPart = model->FindOrCreatePackagePart("/3D/boxPathNew.model"); + + while (resources->MoveNext()) { + auto resource = resources->GetCurrent(); + std::cout << resource->PackagePart()->GetPath() << ":" << resource->GetModelResourceID() << std::endl; + if (resource->PackagePart()->GetPath() == "/3D/box1.model") { + resource->SetPackagePart(newPart.get()); + } + } + auto writer = model->QueryWriter("3mf"); + writer->WriteToFile("outProduction.3mf"); + } + + //TEST_F(ProductionExtension, ReadModifySplitWriteReadInspect) + //{ + //} + + //TEST_F(ProductionExtension, ReadModifyJoinWriteReadInspect) + //{ + //} + + TEST_F(ProductionExtension, SetupWrite) + { + std::vector vctVertices; + std::vector vctTriangles; + + auto mesh1 = model->AddMeshObject(); + fnCreateBox(vctVertices, vctTriangles); + mesh1->SetGeometry(vctVertices, vctTriangles); + + auto component1 = model->AddComponentsObject(); + component1->AddComponent(mesh1.get(), wrapper->GetIdentityTransform()); + + model->AddBuildItem(component1.get(), wrapper->GetIdentityTransform()); + auto writer = model->QueryWriter("3mf"); + writer->WriteToFile("SetupWriteRead1.3mf"); + + auto newPart = model->FindOrCreatePackagePart("/3D/outsourced.model"); + mesh1->SetPackagePart(newPart.get()); + writer->WriteToFile("SetupWriteRead2.3mf"); + + component1->SetPackagePart(newPart.get()); + writer->WriteToFile("SetupWriteRead3.3mf"); + + mesh1->SetPackagePart(model->RootModelPart().get()); + ASSERT_SPECIFIC_THROW(writer->WriteToFile("SetupWriteRead4.3mf"), ELib3MFException); + + auto newPart2 = model->FindOrCreatePackagePart("/3D/outsourced2.model"); + mesh1->SetPackagePart(newPart2.get()); + ASSERT_SPECIFIC_THROW(writer->WriteToFile("SetupWriteRead5.3mf"), ELib3MFException); + } + + //TEST_F(ProductionExtension, SetupWriteReadInspect) + //{ + + //} + + TEST_F(ProductionExtension, ProductionWriteExternalModel) { + //create the attachment to be secured + auto lModel = wrapper->CreateModel(); + auto meshObject = lModel->AddMeshObject(); + meshObject->SetGeometry(CLib3MFInputVector(pVertices, 8), CLib3MFInputVector(pTriangles, 12)); + sTransform transformation = wrapper->GetIdentityTransform(); + + auto part1 = lModel->FindOrCreatePackagePart("/3D/nonrootmodel1.model"); + lModel->AddBuildItem(meshObject.get(), transformation); + meshObject->SetPackagePart(part1.get()); + + meshObject = lModel->AddMeshObject(); + meshObject->SetGeometry(CLib3MFInputVector(pVertices, 8), CLib3MFInputVector(pTriangles, 12)); + transformation = wrapper->GetTranslationTransform(0.0, 250.0, 0.0); + meshObject->SetPackagePart(part1.get()); + lModel->AddBuildItem(meshObject.get(), transformation); + + meshObject = lModel->AddMeshObject(); + meshObject->SetGeometry(CLib3MFInputVector(pVertices, 8), CLib3MFInputVector(pTriangles, 12)); + transformation = wrapper->GetTranslationTransform(0.0, 250.0, 0.0); + lModel->AddBuildItem(meshObject.get(), transformation); + auto part2 = lModel->FindOrCreatePackagePart("/3D/nonrootmodel2.model"); + meshObject->SetPackagePart(part2.get()); + + + auto writer = lModel->QueryWriter("3mf"); + //std::vector buffer; + writer->WriteToFile("nonrootmodels.3mf"); + //writer->WriteToBuffer(buffer); + + auto modelAssert = wrapper->CreateModel(); + auto reader = modelAssert->QueryReader("3mf"); + reader->ReadFromFile("nonrootmodels.3mf"); + //reader->ReadFromBuffer(buffer); + ASSERT_EQ(3, modelAssert->GetObjects()->Count()); + ASSERT_EQ(3, modelAssert->GetBuildItems()->Count()); + } +} diff --git a/Tests/CPP_Bindings/Source/Properties.cpp b/Tests/CPP_Bindings/Source/Properties.cpp index a1cdb6550..e83ff0300 100644 --- a/Tests/CPP_Bindings/Source/Properties.cpp +++ b/Tests/CPP_Bindings/Source/Properties.cpp @@ -166,6 +166,56 @@ namespace Lib3MF CompareColors(baseMaterialGroup->GetDisplayColor(someMaterial), readBaseMaterialGroup->GetDisplayColor(nObjectPropertyID)); } + + // Copy-pasted from the previous test ("ObjectLevelPropertiesWriteRead"), but adds metadata to the mesh + TEST_F(Properties, ObjectLevelPropertiesWriteRead_WithMetaData) + { + auto baseMaterialGroup = model->AddBaseMaterialGroup(); + auto someMaterial = baseMaterialGroup->AddMaterial("SomeMaterial", wrapper->RGBAToColor(100, 200, 150, 255)); + auto anotherMaterial = baseMaterialGroup->AddMaterial("AnotherMaterial", wrapper->RGBAToColor(100, 200, 150, 255)); + + std::vector properties(mesh->GetTriangleCount()); + for (Lib3MF_uint64 i = 0; i < mesh->GetTriangleCount(); i++) { + properties[i].m_ResourceID = baseMaterialGroup->GetResourceID(); + for (int j = 0; j < 3; j++) { + properties[i].m_PropertyIDs[j] = (i % (2 + j)) ? someMaterial : anotherMaterial; + } + } + mesh->SetAllTriangleProperties(properties); + mesh->SetObjectLevelProperty(baseMaterialGroup->GetResourceID(), someMaterial); + + mesh->GetMetaDataGroup()->AddMetaData("", "Designer", "SomeDesigner", "xs:string", true); + + auto writer = model->QueryWriter("3mf"); + std::vector buffer; + writer->WriteToBuffer(buffer); + + auto readModel = wrapper->CreateModel(); + auto reader3MF = readModel->QueryReader("3mf"); + reader3MF->ReadFromBuffer(buffer); + + auto readMesh = readModel->GetMeshObjectByID(2); + std::vector readProperties; + readMesh->GetAllTriangleProperties(readProperties); + + ASSERT_EQ(readMesh->GetTriangleCount(), mesh->GetTriangleCount()); + for (Lib3MF_uint64 i = 0; i < readMesh->GetTriangleCount(); i++) { + auto readBaseMaterialGroup = readModel->GetBaseMaterialGroupByID(readProperties[i].m_ResourceID); + for (int j = 0; j < 3; j++) { + CompareColors(baseMaterialGroup->GetDisplayColor(properties[i].m_PropertyIDs[j]), baseMaterialGroup->GetDisplayColor(readProperties[i].m_PropertyIDs[j])); + } + } + + Lib3MF_uint32 nObjectResourceID = 0; + Lib3MF_uint32 nObjectPropertyID = 0; + EXPECT_TRUE(readMesh->GetObjectLevelProperty(nObjectResourceID, nObjectPropertyID)); + EXPECT_EQ(nObjectResourceID, 1); + EXPECT_EQ(nObjectPropertyID, someMaterial); + + auto readBaseMaterialGroup = readModel->GetBaseMaterialGroupByID(nObjectResourceID); + CompareColors(baseMaterialGroup->GetDisplayColor(someMaterial), readBaseMaterialGroup->GetDisplayColor(nObjectPropertyID)); + } + TEST_F(Properties, ObjectLevelPropertiesReadOnly1) { auto readModel = wrapper->CreateModel(); diff --git a/Tests/CPP_Bindings/Source/Reader.cpp b/Tests/CPP_Bindings/Source/Reader.cpp index 8214fa181..9e67992e5 100644 --- a/Tests/CPP_Bindings/Source/Reader.cpp +++ b/Tests/CPP_Bindings/Source/Reader.cpp @@ -69,6 +69,13 @@ namespace Lib3MF { Reader::readerSTL->ReadFromFile(sTestFilesPath + "/Reader/" + "Pyramid.stl"); CheckReaderWarnings(Reader::readerSTL, 0); + auto meshObjects = model->GetMeshObjects(); + ASSERT_TRUE(meshObjects->Count() > 0); + while (meshObjects->MoveNext()) { + auto meshObject = meshObjects->GetCurrentMeshObject(); + ASSERT_TRUE(meshObject->GetVertexCount() > 0); + ASSERT_TRUE(meshObject->GetTriangleCount() > 0); + } } TEST_F(Reader, STLReadWriteRead) @@ -111,4 +118,18 @@ namespace Lib3MF CheckReaderWarnings(Reader::reader3MF, 0); } + TEST_F(Reader, Production) + { + auto buffer = ReadFileIntoBuffer(sTestFilesPath + "/Production/" + "2ProductionBoxes.3mf"); + Reader::reader3MF->ReadFromBuffer(buffer); + CheckReaderWarnings(Reader::reader3MF, 0); + } + + TEST_F(Reader, ProductionExternalModel) { + auto reader = model->QueryReader("3mf"); + reader->ReadFromFile(sTestFilesPath + "/Production/" + "detachedmodel.3mf"); + ASSERT_EQ(27, model->GetBuildItems()->Count()); + ASSERT_EQ(28, model->GetObjects()->Count()); + } + } diff --git a/Tests/CPP_Bindings/Source/SecureContent.cpp b/Tests/CPP_Bindings/Source/SecureContent.cpp new file mode 100644 index 000000000..dab5931ff --- /dev/null +++ b/Tests/CPP_Bindings/Source/SecureContent.cpp @@ -0,0 +1,637 @@ +#include "UnitTest_Utilities.h" +#include "lib3mf_implicit.hpp" + +#include +#include + +namespace Lib3MF { + + class SecureContentT : public ::testing::Test { + protected: + sPosition pVertices[8]; + sTriangle pTriangles[12]; + std::string publicKey; + + PModel model; + + const std::string UNENCRYPTEDKEYSTORE = "/SecureContent/keystore.3mf"; + const std::string UNENCRYPTEDCOMPRESSEDKEYSTORE = "/SecureContent/keystore_compressed.3mf"; + const std::string NEGATIVEUNENCRYPTEDKEYSTOREEMPTY = "/SecureContent/negative_keystore_empty.3mf"; + const std::string NEGATIVEUNENCRYPTEDKEYSTOREMISSINGATTRIBUTES = "/SecureContent/negative_keystore_missing_attributes.3mf"; + const std::string NEGATIVEUNENCRYPTEDKEYSTOREINVALIDATTRIBUTES = "/SecureContent/negative_keystore_invalid_attributes.3mf"; + protected: + SecureContentT() + {} + + virtual void SetUp() { + std::vector pubKey = ReadFileIntoBuffer(sTestFilesPath + "/SecureContent/sample.pub.pem"); + publicKey = std::string(pubKey.begin(), pubKey.end()); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + pVertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + pVertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + pVertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + pVertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + pVertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + pVertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + pVertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + pVertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + pTriangles[0] = fnCreateTriangle(2, 1, 0); + pTriangles[1] = fnCreateTriangle(0, 3, 2); + pTriangles[2] = fnCreateTriangle(4, 5, 6); + pTriangles[3] = fnCreateTriangle(6, 7, 4); + pTriangles[4] = fnCreateTriangle(0, 1, 5); + pTriangles[5] = fnCreateTriangle(5, 4, 0); + pTriangles[6] = fnCreateTriangle(2, 3, 7); + pTriangles[7] = fnCreateTriangle(7, 6, 2); + pTriangles[8] = fnCreateTriangle(1, 2, 6); + pTriangles[9] = fnCreateTriangle(6, 5, 1); + pTriangles[10] = fnCreateTriangle(3, 0, 4); + pTriangles[11] = fnCreateTriangle(4, 7, 3); + model = wrapper->CreateModel(); + model->SetRandomNumberCallback(notRandomBytesAtAll, nullptr); + } + + virtual void TearDown() { + model.reset(); + } + + static void SetUpTestCase() { + wrapper = CWrapper::loadLibrary(); + } + + PReader readKeyStore(std::string filename) { + auto reader = model->QueryReader("3mf"); + KEKCallbackData kekData; + kekData.value = 1; + kekData.consumerId = "LIB3MF#TEST"; + kekData.keyId = "contentKey"; + reader->AddKeyWrappingCallback(kekData.consumerId, testKEKCallback, (Lib3MF_pvoid)&kekData); + + DEKCallbackData dekData; + reader->SetContentEncryptionCallback(testDEKCallback, (Lib3MF_pvoid)&dekData); + + reader->ReadFromFile(sTestFilesPath + filename); + return reader; + } + + PReader readUnencryptedKeyStore() { + return readKeyStore(UNENCRYPTEDKEYSTORE); + } + public: + + static PWrapper wrapper; + + static void notRandomBytesAtAll(Lib3MF_uint64 byteData, Lib3MF_uint64 size, Lib3MF_pvoid userData, Lib3MF_uint64 * bytesWritten) { + static Lib3MF_uint8 random = 0; + Lib3MF_uint8 * buffer = (Lib3MF_uint8 *)byteData; + *bytesWritten = size; + while (size > 0) + *(buffer + (--size)) = ++random; + } + + struct KEKCallbackData { + int value; + std::string consumerId; + std::string keyId; + }; + + struct DEKCallbackData { + std::map context; + }; + + static void testKEKCallback( + Lib3MF_AccessRight access, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeeded, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + + CAccessRight a(SecureContentT::wrapper.get(), access); + SecureContentT::wrapper->Acquire(&a); + + PConsumer c = a.GetConsumer(); + + ASSERT_NE(userData, nullptr); + + KEKCallbackData * cb = (KEKCallbackData *)userData; + ASSERT_GE(cb->value, 1); + cb->value++; + + ASSERT_EQ(c->GetConsumerID(), cb->consumerId); + ASSERT_EQ(c->GetKeyID(), cb->keyId); + ASSERT_FALSE(c->GetKeyValue().empty()); + + if (nullptr == outBuffer || outSize == 0) { + *outNeeded = inSize; + *status = inSize; + } else { + std::copy(inBuffer, inBuffer + outSize, outBuffer); + *status = outSize; + } + } + + static void testDEKCallback( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 inSize, + const Lib3MF_uint8 * inBuffer, + const Lib3MF_uint64 outSize, + Lib3MF_uint64 * outNeededSize, + Lib3MF_uint8 * outBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + CContentEncryptionParams cd(SecureContentT::wrapper.get(), params); + SecureContentT::wrapper->Acquire(&cd); + + ASSERT_GE(cd.GetDescriptor(), 1); + ASSERT_NE(userData, nullptr); + + DEKCallbackData * cb = (DEKCallbackData *)userData; + auto localDescriptor = cb->context.find(cd.GetDescriptor()); + if (localDescriptor != cb->context.end()) + localDescriptor->second++; + else + cb->context[cd.GetDescriptor()] = 0; + + if (0 == inSize || nullptr == inBuffer) { + //finalize + *status = 1; + } else if (0 == outSize || nullptr == outBuffer) { + //return size needed + *outNeededSize = inSize; + *status = inSize; + } else { + //perform encryption/decription process + std::copy(inBuffer, inBuffer + outSize, outBuffer); + *status = outSize; + } + } + + void generateTestFiles(bool compressed, std::string const & fileName) { + std::vector buffer; + { + PModel modelToCrpt = wrapper->CreateModel(); + + PReader reader = modelToCrpt->QueryReader("3mf"); + reader->ReadFromFile(sTestFilesPath + "/Production/detachedmodel.3mf"); + + auto meshObjIt = modelToCrpt->GetMeshObjects(); + ASSERT_EQ(meshObjIt->Count(), 1); + ASSERT_TRUE(meshObjIt->MoveNext()); + auto meshObj = meshObjIt->GetCurrentMeshObject(); + ASSERT_NE(nullptr, meshObj); + auto part = meshObj->PackagePart(); + ASSERT_NE(nullptr, meshObj); + auto keyStore = modelToCrpt->GetKeyStore(); + auto consumer = keyStore->AddConsumer("LIB3MF#TEST", "contentKey", publicKey); + auto rdGroup = keyStore->AddResourceDataGroup(); + rdGroup->AddAccessRight(consumer.get(), + eWrappingAlgorithm::RSA_OAEP, + eMgfAlgorithm::MGF1_SHA1, + eDigestMethod::SHA1); + + std::vector aad = { 'l', 'i', 'b', '3', 'm', 'f', 's', 'a', 'm', 'p', 'l', 'e' }; + auto rd = keyStore->AddResourceData(rdGroup.get(), part.get(), + eEncryptionAlgorithm::AES256_GCM, (compressed ? eCompression::Deflate : eCompression::NoCompression), aad); + + PWriter writer = modelToCrpt->QueryWriter("3mf"); + DEKCallbackData contentData; + writer->SetContentEncryptionCallback(testDEKCallback, (Lib3MF_pvoid)&contentData); + + KEKCallbackData wrappingData; + wrappingData.value = 1; + wrappingData.consumerId = "LIB3MF#TEST"; + wrappingData.keyId = "contentKey"; + writer->AddKeyWrappingCallback(wrappingData.consumerId, testKEKCallback, (Lib3MF_pvoid)&wrappingData); + + writer->WriteToBuffer(buffer); + + auto count = writer->GetWarningCount(); + ASSERT_GE(count, 1U); + Lib3MF_uint32 warning; + writer->GetWarning(0, warning); + // Using cryptographically weak random number generator + ASSERT_EQ(warning, 0xA00C); + //WriteBufferToFile(buffer, sOutFilesPath + "/SecureContent/" + fileName); + } + { + PModel encryptedModel = wrapper->CreateModel(); + PReader reader = encryptedModel->QueryReader("3mf"); + DEKCallbackData dekData; + reader->SetContentEncryptionCallback(testDEKCallback, (Lib3MF_pvoid)&dekData); + + KEKCallbackData kekData; + kekData.value = 1; + kekData.consumerId = "LIB3MF#TEST"; + kekData.keyId = "contentKey"; + reader->AddKeyWrappingCallback(kekData.consumerId, testKEKCallback, (Lib3MF_pvoid)&kekData); + + reader->ReadFromBuffer(buffer); + + auto meshObjIt = encryptedModel->GetMeshObjects(); + ASSERT_EQ(meshObjIt->Count(), 1); + auto objCount = encryptedModel->GetObjects(); + ASSERT_EQ(objCount->Count(), 28); + } + } + }; + PWrapper SecureContentT::wrapper; + + + + using Lib3MF_buffer = std::vector; + + /*********************************** + The 'model' is empty on the tests. + You need to do the reading/writing. + Read existing models by defining + functions for it, so we better track + the files used for testing. + ***********************************/ + + // + //Keystore basic, empty model tests + // + + TEST_F(SecureContentT, ModelKeyStoreUUID) { + std::string uuid = "df81fc77-cfd1-4266-a432-9759a0d26c2a"; + auto ks = model->GetKeyStore(); + ASSERT_TRUE(ks != nullptr); + ks->SetUUID(uuid); + bool hasUUID; + std::string uuid2 = ks->GetUUID(hasUUID); + ASSERT_TRUE(hasUUID); + ASSERT_EQ(uuid2, uuid); + } + + TEST_F(SecureContentT, CreateMultipleConsumersKeyStore) { + Lib3MF::PKeyStore keyStore = model->GetKeyStore(); + + std::string firstId = "firstId"; + std::string secondId = "secondId"; + + std::string firstKeyId = "firstKeyId"; + std::string secondKeyId = "secondKeyId"; + std::string firstKeyValue = "firstKeyValue"; + std::string secondKeyValue = "secondKeyValue"; + + Lib3MF::PConsumer consumer1 = keyStore->AddConsumer(firstId, firstKeyId, firstKeyValue); + Lib3MF::PConsumer consumer2 = keyStore->AddConsumer(secondId, secondKeyId, secondKeyValue); + + ASSERT_EQ(2, keyStore->GetConsumerCount()); + ASSERT_EQ(firstId, keyStore->GetConsumer(0)->GetConsumerID()); + ASSERT_EQ(secondId, keyStore->GetConsumer(1)->GetConsumerID()); + + keyStore->RemoveConsumer(consumer1.get()); + ASSERT_EQ(1, keyStore->GetConsumerCount()); + ASSERT_EQ(secondId, keyStore->GetConsumer(0)->GetConsumerID()); + } + + TEST_F(SecureContentT, CreateMultipleResourceDataKeyStore) { + Lib3MF::PKeyStore keyStore = model->GetKeyStore(); + ASSERT_TRUE(nullptr != keyStore); + + std::string path1 = "/3D/nonrootmodel1.model"; + auto part1 = model->FindOrCreatePackagePart(path1); + + auto dataGroup = keyStore->AddResourceDataGroup(); + + std::string dguuid = dataGroup->GetKeyUUID(); + ASSERT_FALSE(dguuid.empty()); + + keyStore->AddResourceData(dataGroup.get(), part1.get(), Lib3MF::eEncryptionAlgorithm::AES256_GCM, Lib3MF::eCompression::Deflate, std::vector()); + + std::string path2 = "/3D/nonrootmodel2.model"; + auto part2 = model->FindOrCreatePackagePart(path2); + + keyStore->AddResourceData(dataGroup.get(), part2.get(), Lib3MF::eEncryptionAlgorithm::AES256_GCM, Lib3MF::eCompression::Deflate, std::vector()); + + ASSERT_EQ(2, keyStore->GetResourceDataCount()); + ASSERT_EQ(path1, keyStore->GetResourceData(0)->GetPath()->GetPath()); + ASSERT_EQ(path2, keyStore->GetResourceData(1)->GetPath()->GetPath()); + } + + + TEST_F(SecureContentT, ManageAccessRight) { + Lib3MF::PKeyStore keyStore = model->GetKeyStore(); + ASSERT_TRUE(nullptr != keyStore); + + std::string path1 = "/3D/nonrootmodel1.model"; + auto part1 = model->FindOrCreatePackagePart(path1); + + auto dataGroup1 = keyStore->AddResourceDataGroup(); + + keyStore->AddResourceData(dataGroup1.get(), part1.get(), Lib3MF::eEncryptionAlgorithm::AES256_GCM, Lib3MF::eCompression::Deflate, std::vector()); + + std::string path2 = "/3D/nonrootmodel2.model"; + auto part2 = model->FindOrCreatePackagePart(path2); + + auto dataGroup2 = keyStore->AddResourceDataGroup(); + + keyStore->AddResourceData(dataGroup2.get(), part2.get(), Lib3MF::eEncryptionAlgorithm::AES256_GCM, Lib3MF::eCompression::Deflate, std::vector()); + + Lib3MF::PConsumer consumer1 = keyStore->AddConsumer("consumerId1", "consumerKeyId1", "consumerKeyValue1"); + Lib3MF::PConsumer consumer2 = keyStore->AddConsumer("consumerId2", "consumerKeyId2", "consumerKeyValue2"); + + //Test add decrypt right to different resource data + + dataGroup1->AddAccessRight(consumer1.get(), eWrappingAlgorithm::RSA_OAEP, eMgfAlgorithm::MGF1_SHA1, eDigestMethod::SHA1); + dataGroup2->AddAccessRight(consumer2.get(), eWrappingAlgorithm::RSA_OAEP, eMgfAlgorithm::MGF1_SHA256, eDigestMethod::SHA256); + + auto accessRight1 = keyStore->GetResourceDataGroup(0)->FindAccessRightByConsumer(consumer1.get()); + ASSERT_NE(accessRight1, nullptr); + ASSERT_EQ(consumer1->GetConsumerID(), accessRight1->GetConsumer()->GetConsumerID()); + ASSERT_EQ(Lib3MF::eWrappingAlgorithm::RSA_OAEP, accessRight1->GetWrappingAlgorithm()); + ASSERT_EQ(Lib3MF::eMgfAlgorithm::MGF1_SHA1, accessRight1->GetMgfAlgorithm()); + ASSERT_EQ(Lib3MF::eDigestMethod::SHA1, accessRight1->GetDigestMethod()); + + auto accessRight2 = keyStore->GetResourceDataGroup(1)->FindAccessRightByConsumer(consumer2.get()); + ASSERT_NE(accessRight2, nullptr); + ASSERT_EQ(consumer2->GetConsumerID(), accessRight2->GetConsumer()->GetConsumerID()); + ASSERT_EQ(Lib3MF::eWrappingAlgorithm::RSA_OAEP, accessRight2->GetWrappingAlgorithm()); + ASSERT_EQ(Lib3MF::eMgfAlgorithm::MGF1_SHA256, accessRight2->GetMgfAlgorithm()); + ASSERT_EQ(Lib3MF::eDigestMethod::SHA256, accessRight2->GetDigestMethod()); + + //we can't find access right for consumer 1 on the second resource data group + auto notFound = keyStore->GetResourceDataGroup(1)->FindAccessRightByConsumer(consumer1.get()); + ASSERT_EQ(notFound, nullptr); + + //Test remove decrypt right from resource data using a consumer + keyStore->GetResourceDataGroup(0)->RemoveAccessRight(consumer1.get()); + + notFound = keyStore->GetResourceDataGroup(0)->FindAccessRightByConsumer(consumer1.get()); + ASSERT_EQ(notFound, nullptr); + } + + + + + + // + //Keystore test which require preexisting model + // + + TEST_F(SecureContentT, ModelReaderKeyStoreNoWarnings) { + PReader reader3MF = readUnencryptedKeyStore(); + CheckReaderWarnings(reader3MF, 0); + } + + TEST_F(SecureContentT, ModelReaderEmptyKeyStoreWarnings) { + try { + PReader reader3MF = readKeyStore(NEGATIVEUNENCRYPTEDKEYSTOREEMPTY); + ASSERT_FALSE(true); + } catch (ELib3MFException const & e) { + ASSERT_EQ(e.getErrorCode(), LIB3MF_ERROR_GENERICEXCEPTION); + //Lib3MF_uint32 iWarning = 0; + + //// NMR_ERROR_KEYSTOREINVALIDCONSUMERINDEX + //// consumer index is higher than consumer count + //reader3MF->GetWarning(0, iWarning); + //ASSERT_EQ(0x80F6, iWarning); + } + } + + TEST_F(SecureContentT, ModelReaderKeyStoreNoAttributesWarnings) { + PReader reader3MF = readKeyStore(NEGATIVEUNENCRYPTEDKEYSTOREMISSINGATTRIBUTES); + CheckReaderWarnings(reader3MF, 6); + Lib3MF_uint32 iWarning = 0; + + // NMR_ERROR_KEYSTOREMISSINGCONSUMERID + // consumerid is not defined on consumer + reader3MF->GetWarning(0, iWarning); + ASSERT_EQ(0x80F3, iWarning); + + // NMR_ERROR_KEYSTOREMISSINGKEYUUID + // resourcedatagroup keyuuid is not defined + reader3MF->GetWarning(1, iWarning); + ASSERT_EQ(0x8107, iWarning); + + // NMR_ERROR_KEYSTOREMISSINGALGORTHM + // missing wrappingalgorithm on kekparams + reader3MF->GetWarning(2, iWarning); + ASSERT_EQ(0x810A, iWarning); + + // NMR_ERROR_KEYSTOREMISSINGCONSUMERINDEX + // consumerindex on accessright is not defined + reader3MF->GetWarning(3, iWarning); + ASSERT_EQ(0x8105, iWarning); + + // NMR_ERROR_KEYSTOREMISSINGALGORTHM + // missing encryptionalgorithm on cekparams + reader3MF->GetWarning(4, iWarning); + ASSERT_EQ(0x810A, iWarning); + + // NMR_ERROR_MISSINGUUID + //missing guid on keystore + reader3MF->GetWarning(5, iWarning); + ASSERT_EQ(0x80B0, iWarning); + + } + + TEST_F(SecureContentT, ModelReaderKeyStoreInvalidAttributesWarnings) { + PReader reader3MF = readKeyStore(NEGATIVEUNENCRYPTEDKEYSTOREINVALIDATTRIBUTES); + CheckReaderWarnings(reader3MF, 8); + Lib3MF_uint32 iWarning = 0; + + // NMR_ERROR_KEYSTOREDUPLICATECONSUMERID + // consumer has multiple consumerid attributes + reader3MF->GetWarning(0, iWarning); + ASSERT_EQ(0x80F1, iWarning); + + // NMR_ERROR_KEYSTOREINVALIDKEYUUID + // resourcedatagroup keyuuid is invalid + reader3MF->GetWarning(1, iWarning); + ASSERT_EQ(0x80FF, iWarning); + + // NMR_ERROR_NAMESPACE_INVALID_ATTRIBUTE + // encryptionalgorithm on accessright + reader3MF->GetWarning(2, iWarning); + ASSERT_EQ(0x80A7, iWarning); + + // NMR_ERROR_KEYSTOREINVALIDALGORITHM + // invalid wrappinglagorithm attribute in kekparams + reader3MF->GetWarning(3, iWarning); + ASSERT_EQ(0x80F7, iWarning); + + // NMR_ERROR_KEYSTOREINVALIDMGF + // invalid mgfalgorithm + reader3MF->GetWarning(4, iWarning); + ASSERT_EQ(0x8102, iWarning); + + // NMR_ERROR_KEYSTOREINVALIDDIGEST + // invlid digestmethod + reader3MF->GetWarning(5, iWarning); + ASSERT_EQ(0x8103, iWarning); + + // NMR_ERROR_KEYSTOREINVALIDALGORITHM + // invalid encryptionalgorithm attribute in cekparams + reader3MF->GetWarning(6, iWarning); + ASSERT_EQ(0x80F7, iWarning); + + // NMR_ERROR_KEYSTOREINVALIDCOMPRESSION + // invalid compression attribute in ResourceData + reader3MF->GetWarning(7, iWarning); + ASSERT_EQ(0x80F8, iWarning); + } + + TEST_F(SecureContentT, CheckKeyStoreConsumers) { + readUnencryptedKeyStore(); + auto keyStore = model->GetKeyStore(); + ASSERT_TRUE(keyStore != nullptr); + const size_t consumerCount = keyStore->GetConsumerCount(); + for (int i = 0; i < consumerCount; ++i) { + PConsumer consumer = keyStore->GetConsumer(i); + + ASSERT_EQ("LIB3MF#TEST", consumer->GetConsumerID()); + ASSERT_EQ("contentKey", consumer->GetKeyID()); + + PConsumer consumerNotFound = keyStore->FindConsumer("does not exist"); + ASSERT_EQ(nullptr, consumerNotFound); + PConsumer consumerFound = keyStore->FindConsumer(consumer->GetConsumerID()); + ASSERT_EQ(consumer->GetConsumerID(), consumerFound->GetConsumerID()); + + std::string keyValue = consumer->GetKeyValue(); + keyValue.erase(std::remove_if(keyValue.begin(), keyValue.end(), ::isspace), keyValue.end()); + std::string expected = publicKey; + expected.erase(std::remove_if(expected.begin(), expected.end(), ::isspace), expected.end()); + + + ASSERT_EQ(expected, keyValue); + + } + } + + TEST_F(SecureContentT, CheckKeyStoreResourceData) { + readUnencryptedKeyStore(); + auto keyStore = model->GetKeyStore(); + ASSERT_TRUE(keyStore != nullptr); + const size_t resourceDataCount = keyStore->GetResourceDataCount(); + + ASSERT_TRUE(resourceDataCount > 0); + + PPackagePart newPart = model->FindOrCreatePackagePart("/3D/newpart.model"); + PResourceData resourceDataNotFound = keyStore->FindResourceData(newPart.get()); + ASSERT_TRUE(nullptr == resourceDataNotFound); + + for (int i = 0; i < resourceDataCount; ++i) { + PResourceData resourceData = keyStore->GetResourceData(i); + ASSERT_TRUE(resourceData != nullptr); + + PResourceData resourceDataFound = keyStore->FindResourceData(resourceData->GetPath().get()); + ASSERT_TRUE(resourceDataFound != nullptr); + + ASSERT_EQ(resourceData->GetPath()->GetPath(), resourceDataFound->GetPath()->GetPath()); + + ASSERT_EQ(Lib3MF::eEncryptionAlgorithm::AES256_GCM, resourceData->GetEncryptionAlgorithm()); + ASSERT_EQ(Lib3MF::eCompression::NoCompression, resourceData->GetCompression()); + ASSERT_EQ("/3D/3dexternal.model", resourceData->GetPath()->GetPath()); + } + } + + TEST_F(SecureContentT, DEKReadTest) { + auto reader = model->QueryReader("3mf"); + DEKCallbackData data; + reader->SetContentEncryptionCallback(testDEKCallback, (Lib3MF_pvoid)&data); + reader->ReadFromFile(sTestFilesPath + UNENCRYPTEDKEYSTORE); + ASSERT_EQ(data.context.size(), 1); + ASSERT_GE(data.context.begin()->second, 1); + } + + + TEST_F(SecureContentT, ReadCompressedTest) { + auto reader = model->QueryReader("3mf"); + DEKCallbackData data; + reader->SetContentEncryptionCallback(testDEKCallback, (Lib3MF_pvoid)&data); + reader->ReadFromFile(sTestFilesPath + UNENCRYPTEDCOMPRESSEDKEYSTORE); + ASSERT_EQ(data.context.size(), 1); + ASSERT_GE(data.context.begin()->second, 1); + } + + TEST_F(SecureContentT, DEKWriteTest) { + readUnencryptedKeyStore(); + auto writer = model->QueryWriter("3mf"); + DEKCallbackData data; + writer->SetContentEncryptionCallback(testDEKCallback, (Lib3MF_pvoid)&data); + writer->WriteToFile(sOutFilesPath + UNENCRYPTEDCOMPRESSEDKEYSTORE); + ASSERT_EQ(data.context.size(), 1); + ASSERT_GE(data.context.begin()->second, 1); + } + + TEST_F(SecureContentT, KEKReadTest) { + auto reader = model->QueryReader("3mf"); + KEKCallbackData data; + data.value = 1; + data.consumerId = "LIB3MF#TEST"; + data.keyId = "contentKey"; + reader->AddKeyWrappingCallback(data.consumerId, testKEKCallback, (Lib3MF_pvoid)&data); + reader->ReadFromFile(sTestFilesPath + UNENCRYPTEDKEYSTORE); + ASSERT_EQ(3, data.value); + } + + + TEST_F(SecureContentT, KEKWriteTest) { + readUnencryptedKeyStore(); + Lib3MF::PKeyStore keyStore = model->GetKeyStore(); + ASSERT_TRUE(nullptr != keyStore); + ASSERT_EQ(keyStore->GetConsumerCount(), 1); + Lib3MF::PConsumer consumer1 = keyStore->AddConsumer("consumerId", "contentKey", "consumerKeyValue"); + Lib3MF::PResourceData rd = keyStore->GetResourceData(0); + Lib3MF::PResourceDataGroup dg = keyStore->FindResourceDataGroup(rd->GetPath().get()); + Lib3MF::PAccessRight ar = dg->AddAccessRight(consumer1.get(), eWrappingAlgorithm::RSA_OAEP, eMgfAlgorithm::MGF1_SHA1, eDigestMethod::SHA1); + + auto writer = model->QueryWriter("3mf"); + + DEKCallbackData contentData; + writer->SetContentEncryptionCallback(testDEKCallback, (Lib3MF_pvoid)&contentData); + + KEKCallbackData wrappingData; + wrappingData.value = 1; + wrappingData.consumerId = "consumerId"; + wrappingData.keyId = "contentKey"; + writer->AddKeyWrappingCallback(wrappingData.consumerId, testKEKCallback, (Lib3MF_pvoid)&wrappingData); + std::vector buffer; + writer->WriteToBuffer(buffer); + ASSERT_EQ(3, wrappingData.value); + } + + TEST_F(SecureContentT, KEKWriteTestUnregisteredConsumer) { + readUnencryptedKeyStore(); + Lib3MF::PKeyStore keyStore = model->GetKeyStore(); + ASSERT_TRUE(nullptr != keyStore); + + ASSERT_TRUE(keyStore->GetResourceDataCount() >= 1); + + Lib3MF::PConsumer consumer1 = keyStore->AddConsumer("UnregisteredConsumer", "contentKey", ""); + Lib3MF::PResourceData rd = keyStore->GetResourceData(0); + Lib3MF::PLib3MFResourceDataGroup dg = keyStore->FindResourceDataGroup(rd->GetPath().get()); + Lib3MF::PAccessRight ar = dg->AddAccessRight(consumer1.get(), eWrappingAlgorithm::RSA_OAEP, eMgfAlgorithm::MGF1_SHA1, eDigestMethod::SHA1); + + auto writer = model->QueryWriter("3mf"); + DEKCallbackData contentData; + writer->SetContentEncryptionCallback(testDEKCallback, (Lib3MF_pvoid)&contentData); + + std::vector buffer; + try { + writer->WriteToBuffer(buffer); + ASSERT_FALSE(true); + } catch (Lib3MF::ELib3MFException const &e) { + ASSERT_EQ(e.getErrorCode(), LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED); + } + } + + TEST_F(SecureContentT, MakeExistingModelEncrypted) { + generateTestFiles(false, "keystore.3mf"); + generateTestFiles(true, "keystore_compressed.3mf"); + } +} diff --git a/Tests/CPP_Bindings/Source/UnitTest_EncryptionUtils.cpp b/Tests/CPP_Bindings/Source/UnitTest_EncryptionUtils.cpp new file mode 100644 index 000000000..e35b5b60f --- /dev/null +++ b/Tests/CPP_Bindings/Source/UnitTest_EncryptionUtils.cpp @@ -0,0 +1,314 @@ +#include "UnitTest_EncryptionUtils.h" + +#include "gtest/gtest.h" + +#include + +#define AES256GCM_KEYSIZE 32 +#define AES256GCM_IVSIZE 12 +#define AES256GCM_TAGSIZE 16 +#define RSAOEAP_KEYSIZE 256 + + +namespace AesMethods { + + namespace Decrypt { + PEVP_CIPHER_CTX init(Lib3MF_uint8 const * key, Lib3MF_uint8 const * iv, Lib3MF_uint64 aadSize, Lib3MF_uint8 const * aad) { + PEVP_CIPHER_CTX ctx = make_shared(EVP_CIPHER_CTX_new()); + if (!ctx) + throw std::runtime_error("unable to initialize context"); + + if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_256_gcm(), nullptr, nullptr, nullptr)) + throw std::runtime_error("unable to initialize cipher"); + + if (!EVP_DecryptInit_ex(ctx.get(), nullptr, nullptr, key, iv)) + throw std::runtime_error("unable to initialize key and iv"); + + if (aadSize > 0) { + int len; + if (!EVP_DecryptUpdate(ctx.get(), nullptr, &len, aad, (int)aadSize)) + throw std::runtime_error("aad failed"); + } + return ctx; + } + + size_t decrypt(PEVP_CIPHER_CTX ctx, Lib3MF_uint32 size, Lib3MF_uint8 const * cipher, Lib3MF_uint8 * plain) { + int len = 0; + if (!EVP_DecryptUpdate(ctx.get(), plain, &len, cipher, size)) + throw std::runtime_error("unable to decrypt"); + return len; + } + + bool finish(PEVP_CIPHER_CTX ctx, Lib3MF_uint8 * plain, Lib3MF_uint8 * tag) { + if (1 != EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, 16, tag)) + throw std::runtime_error("unable to set tag"); + int len = 0; + int ret = EVP_DecryptFinal_ex(ctx.get(), plain, &len); + return ret > 0; + } + } + namespace Encrypt { + PEVP_CIPHER_CTX init(Lib3MF_uint8 const * key, Lib3MF_uint8 const * iv, Lib3MF_uint64 aadSize, Lib3MF_uint8 const * aad) { + PEVP_CIPHER_CTX ctx = make_shared(EVP_CIPHER_CTX_new()); + if (!ctx) + throw std::runtime_error("unable to intialize cipher context"); + + if (1 != EVP_EncryptInit_ex(ctx.get(), EVP_aes_256_gcm(), nullptr, nullptr, nullptr)) + throw std::runtime_error("unable to initialize encryption mechanism"); + + if (1 != EVP_EncryptInit_ex(ctx.get(), nullptr, nullptr, key, iv)) + throw std::runtime_error("unable to init key and iv"); + if (aadSize > 0) { + int len; + if (1 != EVP_EncryptUpdate(ctx.get(), nullptr, &len, aad, (int)aadSize)) + throw std::runtime_error("aad failed"); + } + return ctx; + } + + size_t encrypt(PEVP_CIPHER_CTX ctx, Lib3MF_uint32 size, Lib3MF_uint8 const * plain, Lib3MF_uint8 * cipher) { + int len = 0; + if (1 != EVP_EncryptUpdate(ctx.get(), cipher, &len, plain, size)) + throw std::runtime_error("unable to encrypt message"); + return len; + } + + bool finish(PEVP_CIPHER_CTX ctx, Lib3MF_uint8 * cipher, Lib3MF_uint32 tagSize, Lib3MF_uint8 * tag) { + int len = 0; + if (1 != EVP_EncryptFinal_ex(ctx.get(), cipher, &len)) + throw std::runtime_error("unable to finalize encryption"); + + if (1 != EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, tagSize, tag)) + throw std::runtime_error("unable to get tag"); + return true; + } + } +} + +namespace RsaMethods { + PEVP_PKEY loadPrivateKey(ByteVector const & privKey) { + PBIO keybio(BIO_new(BIO_s_mem()), ::BIO_free); + BIO_write(keybio.get(), privKey.data(), (int)privKey.size()); + EVP_PKEY * evpKey = 0; + PEM_read_bio_PrivateKey(keybio.get(), &evpKey, NULL, NULL); + PEVP_PKEY pevpKey(evpKey, ::EVP_PKEY_free); + return pevpKey; + } + + PEVP_PKEY loadPublicKey(ByteVector const & pubKey) { + PBIO keybio(BIO_new(BIO_s_mem()), ::BIO_free); + BIO_write(keybio.get(), pubKey.data(), (int)pubKey.size()); + EVP_PKEY * evpKey = 0; + PEM_read_bio_PUBKEY(keybio.get(), &evpKey, NULL, NULL); + PEVP_PKEY pevpKey(evpKey, ::EVP_PKEY_free); + return pevpKey; + } + + size_t getSize(EVP_PKEY * evpKey) { + PRSA rsa(EVP_PKEY_get1_RSA(evpKey), ::RSA_free); + size_t rsaSize = RSA_size(rsa.get()); + return rsaSize; + } + + size_t decrypt(EVP_PKEY * evpKey, size_t cipherSize, uint8_t const * cipher, uint8_t * plain) { + PRSA rsa(EVP_PKEY_get1_RSA(evpKey), ::RSA_free); + int result = RSA_private_decrypt((int)cipherSize, cipher, plain, rsa.get(), RSA_PKCS1_OAEP_PADDING); + if (result < 0) + throw std::runtime_error("unable to decrypt"); + return result; + } + + size_t encrypt(EVP_PKEY * evpKey, size_t plainSize, uint8_t const * plain, uint8_t * cipher) { + PRSA rsa(EVP_PKEY_get1_RSA(evpKey), ::RSA_free); + int result = RSA_public_encrypt((int)plainSize, plain, cipher, rsa.get(), RSA_PKCS1_OAEP_PADDING); + if (result < 0) + throw std::runtime_error("unable do encrypt"); + return result; + } +} + +void EncryptionCallbacks::cleanup() { + RAND_cleanup(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); +} + +void EncryptionCallbacks::dataEncryptClientCallback( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 plainSize, + const Lib3MF_uint8 * plainBuffer, + const Lib3MF_uint64 cipherSize, + Lib3MF_uint64 * cipherNeeded, + Lib3MF_uint8 * cipherBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + DekContext * dek = (DekContext *)userData; + + Lib3MF::CContentEncryptionParams p(dek->wrapper, params); + dek->wrapper->Acquire(&p); + + + if (Lib3MF::eEncryptionAlgorithm::AES256_GCM != p.GetEncryptionAlgorithm()) + *status = 0; + else { + PEVP_CIPHER_CTX ctx; + + auto it = dek->ciphers.find(p.GetDescriptor()); + + if (it != dek->ciphers.end()) { + ctx = it->second; + } else { + ByteVector key, iv, aad; + p.GetKey(key); + p.GetInitializationVector(iv); + p.GetAdditionalAuthenticationData(aad); + ctx = AesMethods::Encrypt::init(key.data(), iv.data(), aad.size(), aad.data()); + dek->ciphers[p.GetDescriptor()] = ctx; + } + + if (0 == plainSize || nullptr == plainBuffer) { + ByteVector tag(16, 0); + + if (!AesMethods::Encrypt::finish(ctx, cipherBuffer, (Lib3MF_uint32)tag.size(), tag.data())) { + *status = 0; + } else { + *status = tag.size(); + p.SetAuthenticationTag(tag); + } + dek->ciphers.erase(it); + ctx.reset(); + } else if (0 == cipherSize || nullptr == cipherBuffer) { + *cipherNeeded = plainSize; + *status = plainSize; + } else { + size_t encrypted = AesMethods::Encrypt::encrypt(ctx, (Lib3MF_uint32)plainSize, plainBuffer, cipherBuffer); + *status = encrypted; + } + } +} + +void EncryptionCallbacks::keyEncryptClientCallback( + Lib3MF_AccessRight accessRight, + Lib3MF_uint64 plainSize, + const Lib3MF_uint8 * plainBuffer, + const Lib3MF_uint64 cipherSize, + Lib3MF_uint64* cipherNeeded, + Lib3MF_uint8 * cipherBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + KekContext const * context = (KekContext const *)userData; + Lib3MF::CAccessRight ar(context->wrapper, accessRight); + context->wrapper->Acquire(&ar); + + if (Lib3MF::eWrappingAlgorithm::RSA_OAEP != ar.GetWrappingAlgorithm() + || Lib3MF::eMgfAlgorithm::MGF1_SHA1 != ar.GetMgfAlgorithm() + || Lib3MF::eDigestMethod::SHA1 != ar.GetDigestMethod()) + *status = 0; + else if (nullptr == cipherBuffer || cipherSize == 0) { + *cipherNeeded = RsaMethods::getSize(context->key); + *status = *cipherNeeded; + } else { + KekContext const * context = (KekContext const *)userData; + *status = RsaMethods::encrypt(context->key, plainSize, plainBuffer, cipherBuffer); + } +} + +void EncryptionCallbacks::dataDecryptClientCallback( + Lib3MF_ContentEncryptionParams params, + Lib3MF_uint64 cipherSize, + const Lib3MF_uint8 * cipherBuffer, + const Lib3MF_uint64 plainSize, + Lib3MF_uint64 * plainNeeded, + Lib3MF_uint8 * plainBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + DekContext * dek = (DekContext *)userData; + + Lib3MF::CContentEncryptionParams p(dek->wrapper, params); + dek->wrapper->Acquire(&p); + + + if (Lib3MF::eEncryptionAlgorithm::AES256_GCM != p.GetEncryptionAlgorithm()) + *status = 0; + else { + PEVP_CIPHER_CTX ctx; + + auto it = dek->ciphers.find(p.GetDescriptor()); + + if (it != dek->ciphers.end()) { + ctx = it->second; + } else { + ByteVector key(32, 0), iv(12, 0), aad; + p.GetKey(key); + p.GetInitializationVector(iv); + p.GetAdditionalAuthenticationData(aad); + ctx = AesMethods::Decrypt::init(key.data(), iv.data(), aad.size(), aad.data()); + dek->ciphers[p.GetDescriptor()] = ctx; + } + + if (0 == cipherSize || nullptr == cipherBuffer) { + ByteVector tag(16, 0); + p.GetAuthenticationTag(tag); + if (!AesMethods::Decrypt::finish(ctx, plainBuffer, tag.data())) { + *status = 0; + } else { + *status = tag.size(); + } + dek->ciphers.erase(it); + ctx.reset(); + } else if (0 == plainSize || nullptr == plainBuffer) { + *plainNeeded = cipherSize; + *status = cipherSize; + } else { + size_t decrypted = AesMethods::Decrypt::decrypt(ctx, (Lib3MF_uint32)plainSize, cipherBuffer, plainBuffer); + *status = decrypted; + } + } +} + +void EncryptionCallbacks::keyDecryptClientCallback( + Lib3MF_AccessRight accessRight, + Lib3MF_uint64 cipherSize, + const Lib3MF_uint8 * cipherBuffer, + const Lib3MF_uint64 plainSize, + Lib3MF_uint64* plainNeeded, + Lib3MF_uint8 * plainBuffer, + Lib3MF_pvoid userData, + Lib3MF_uint64 * status) { + + KekContext const * context = (KekContext const *)userData; + Lib3MF::CAccessRight ar(context->wrapper, accessRight); + context->wrapper->Acquire(&ar); + + if (Lib3MF::eWrappingAlgorithm::RSA_OAEP != ar.GetWrappingAlgorithm() + || Lib3MF::eMgfAlgorithm::MGF1_SHA1 != ar.GetMgfAlgorithm() + || Lib3MF::eDigestMethod::SHA1 != ar.GetDigestMethod()) + *status = 0; + else if (nullptr == plainBuffer || 0 == plainSize) { + *plainNeeded = 32; + *status = 32; + } + else { + ASSERT_EQ(cipherSize, 256); + ASSERT_GE(plainSize, 32); + + *status = RsaMethods::decrypt(context->key, cipherSize, cipherBuffer, plainBuffer); + } +} + +void EncryptionCallbacks::randomNumberCallback( + Lib3MF_uint64 nByteData, + Lib3MF_uint64 nNumBytes, + Lib3MF_pvoid pUserData, + Lib3MF_uint64 * pBytesWritten) { + + int rc = RAND_bytes((unsigned char *)nByteData, (int)nNumBytes); + if (rc != 1) + *pBytesWritten = 0; + else + *pBytesWritten = nNumBytes; +} + diff --git a/Tests/CPP_Bindings/Source/Utilities.cpp b/Tests/CPP_Bindings/Source/UnitTest_Utilities.cpp similarity index 100% rename from Tests/CPP_Bindings/Source/Utilities.cpp rename to Tests/CPP_Bindings/Source/UnitTest_Utilities.cpp diff --git a/Tests/CPP_Bindings/Source/Wrapper.cpp b/Tests/CPP_Bindings/Source/Wrapper.cpp index 3fdc206bf..6fed74627 100644 --- a/Tests/CPP_Bindings/Source/Wrapper.cpp +++ b/Tests/CPP_Bindings/Source/Wrapper.cpp @@ -86,14 +86,20 @@ namespace Lib3MF wrapper->GetSpecificationVersion("http://schemas.microsoft.com/3dmanufacturing/beamlattice/2017/02", bIsSupported, nMajor, nMinor, nMicro); ASSERT_TRUE(bIsSupported); ASSERT_EQ(nMajor, 1); - ASSERT_EQ(nMinor, 0); - ASSERT_EQ(nMicro, 4); + ASSERT_EQ(nMinor, 1); + ASSERT_EQ(nMicro, 0); wrapper->GetSpecificationVersion("http://schemas.microsoft.com/3dmanufacturing/slice/2015/07", bIsSupported, nMajor, nMinor, nMicro); ASSERT_TRUE(bIsSupported); ASSERT_EQ(nMajor, 1); ASSERT_EQ(nMinor, 0); ASSERT_EQ(nMicro, 2); + + wrapper->GetSpecificationVersion("http://schemas.microsoft.com/3dmanufacturing/securecontent/2019/04", bIsSupported, nMajor, nMinor, nMicro); + ASSERT_TRUE(bIsSupported); + ASSERT_EQ(nMajor, 1); + ASSERT_EQ(nMinor, 0); + ASSERT_EQ(nMicro, 2); } TEST(Wrapper, CreateModel) diff --git a/Tests/CPP_Bindings/Source/Writer.cpp b/Tests/CPP_Bindings/Source/Writer.cpp index ec33bfca1..2ce5aa7cb 100644 --- a/Tests/CPP_Bindings/Source/Writer.cpp +++ b/Tests/CPP_Bindings/Source/Writer.cpp @@ -37,12 +37,43 @@ namespace Lib3MF { class Writer : public ::testing::Test { protected: + sPosition pVertices[8]; + sTriangle pTriangles[12]; + virtual void SetUp() { model = wrapper->CreateModel(); auto reader = model->QueryReader("3mf"); reader->ReadFromFile(InFolder + "Pyramid.3mf"); writer3MF = model->QueryWriter("3mf"); writerSTL = model->QueryWriter("stl"); + + float fSizeX = 100.0f; + float fSizeY = 200.0f; + float fSizeZ = 300.0f; + + // Manually create vertices + pVertices[0] = fnCreateVertex(0.0f, 0.0f, 0.0f); + pVertices[1] = fnCreateVertex(fSizeX, 0.0f, 0.0f); + pVertices[2] = fnCreateVertex(fSizeX, fSizeY, 0.0f); + pVertices[3] = fnCreateVertex(0.0f, fSizeY, 0.0f); + pVertices[4] = fnCreateVertex(0.0f, 0.0f, fSizeZ); + pVertices[5] = fnCreateVertex(fSizeX, 0.0f, fSizeZ); + pVertices[6] = fnCreateVertex(fSizeX, fSizeY, fSizeZ); + pVertices[7] = fnCreateVertex(0.0f, fSizeY, fSizeZ); + + // Manually create triangles + pTriangles[0] = fnCreateTriangle(2, 1, 0); + pTriangles[1] = fnCreateTriangle(0, 3, 2); + pTriangles[2] = fnCreateTriangle(4, 5, 6); + pTriangles[3] = fnCreateTriangle(6, 7, 4); + pTriangles[4] = fnCreateTriangle(0, 1, 5); + pTriangles[5] = fnCreateTriangle(5, 4, 0); + pTriangles[6] = fnCreateTriangle(2, 3, 7); + pTriangles[7] = fnCreateTriangle(7, 6, 2); + pTriangles[8] = fnCreateTriangle(1, 2, 6); + pTriangles[9] = fnCreateTriangle(6, 5, 1); + pTriangles[10] = fnCreateTriangle(3, 0, 4); + pTriangles[11] = fnCreateTriangle(4, 7, 3); } virtual void TearDown() { model.reset(); @@ -158,5 +189,4 @@ namespace Lib3MF ASSERT_TRUE(std::equal(buffer.begin(), buffer.end(), callbackBuffer.vec.begin())); } - } diff --git a/Tests/TestFiles/BeamLattice/BeamSet_Not_Unique.3mf b/Tests/TestFiles/BeamLattice/BeamSet_Not_Unique.3mf new file mode 100644 index 000000000..1a0ddbfac Binary files /dev/null and b/Tests/TestFiles/BeamLattice/BeamSet_Not_Unique.3mf differ diff --git a/Tests/TestFiles/BeamLattice/BeamSet_Unique.3mf b/Tests/TestFiles/BeamLattice/BeamSet_Unique.3mf new file mode 100644 index 000000000..60c84a746 Binary files /dev/null and b/Tests/TestFiles/BeamLattice/BeamSet_Unique.3mf differ diff --git a/Tests/TestFiles/Production/2ProductionBoxes.3mf b/Tests/TestFiles/Production/2ProductionBoxes.3mf new file mode 100644 index 000000000..f85796115 Binary files /dev/null and b/Tests/TestFiles/Production/2ProductionBoxes.3mf differ diff --git a/Tests/TestFiles/Production/detachedmodel.3mf b/Tests/TestFiles/Production/detachedmodel.3mf new file mode 100644 index 000000000..6df8e88ba Binary files /dev/null and b/Tests/TestFiles/Production/detachedmodel.3mf differ diff --git a/Tests/TestFiles/Schema/beamlattice_2017_02.xsd b/Tests/TestFiles/Schema/beamlattice_2017_02.xsd index 7306d1e3a..208986bbf 100644 --- a/Tests/TestFiles/Schema/beamlattice_2017_02.xsd +++ b/Tests/TestFiles/Schema/beamlattice_2017_02.xsd @@ -24,11 +24,14 @@ + + + @@ -58,11 +61,29 @@ + + + + + + + + + + + + + + + + + + @@ -80,7 +101,21 @@ + + + + + + + + + + + + + + @@ -114,7 +149,10 @@ + + + diff --git a/Tests/TestFiles/SecureContent/keystore.3mf b/Tests/TestFiles/SecureContent/keystore.3mf new file mode 100644 index 000000000..cc396063d Binary files /dev/null and b/Tests/TestFiles/SecureContent/keystore.3mf differ diff --git a/Tests/TestFiles/SecureContent/keystore_compressed.3mf b/Tests/TestFiles/SecureContent/keystore_compressed.3mf new file mode 100644 index 000000000..841a59b8d Binary files /dev/null and b/Tests/TestFiles/SecureContent/keystore_compressed.3mf differ diff --git a/Tests/TestFiles/SecureContent/keystore_encrypted.3mf b/Tests/TestFiles/SecureContent/keystore_encrypted.3mf new file mode 100644 index 000000000..ca9006271 Binary files /dev/null and b/Tests/TestFiles/SecureContent/keystore_encrypted.3mf differ diff --git a/Tests/TestFiles/SecureContent/keystore_encrypted_compressed.3mf b/Tests/TestFiles/SecureContent/keystore_encrypted_compressed.3mf new file mode 100644 index 000000000..de091c39c Binary files /dev/null and b/Tests/TestFiles/SecureContent/keystore_encrypted_compressed.3mf differ diff --git a/Tests/TestFiles/SecureContent/negative_keystore_empty.3mf b/Tests/TestFiles/SecureContent/negative_keystore_empty.3mf new file mode 100644 index 000000000..5e4433805 Binary files /dev/null and b/Tests/TestFiles/SecureContent/negative_keystore_empty.3mf differ diff --git a/Tests/TestFiles/SecureContent/negative_keystore_invalid_attributes.3mf b/Tests/TestFiles/SecureContent/negative_keystore_invalid_attributes.3mf new file mode 100644 index 000000000..81000e924 Binary files /dev/null and b/Tests/TestFiles/SecureContent/negative_keystore_invalid_attributes.3mf differ diff --git a/Tests/TestFiles/SecureContent/negative_keystore_missing_attributes.3mf b/Tests/TestFiles/SecureContent/negative_keystore_missing_attributes.3mf new file mode 100644 index 000000000..2d1aad990 Binary files /dev/null and b/Tests/TestFiles/SecureContent/negative_keystore_missing_attributes.3mf differ diff --git a/Tests/TestFiles/SecureContent/sample.pem b/Tests/TestFiles/SecureContent/sample.pem new file mode 100644 index 000000000..46dd8771e --- /dev/null +++ b/Tests/TestFiles/SecureContent/sample.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAw53q4y2KB2WcoOBUE9OEXI0OCzUf4SI1J6fDx6XeDJ8PzqxN +4pPRtXgtKfp/RiSL0invf7ASfkBMcXuhD8XP0uki3JIzvsxTH+Jnnz/PrYnS9DFa +6c9MYciTIV8vC4u03vkZH6OuGq4rWeSZuNCTCgT59q67Ly6OytNsQgsDHL2QO8xh +pYdQ4bx7F0uNn5LAxFyA0ymsFsgSSLONJWzaVtsq9jvkIOEdTzYq52PAXMUIpegb +yqSheNlmedcss8teqiZGnCOxpBxL3z+ogcFenX1S8kq2UhzOjXLEjPs9B0SchwXS +adephL89shJwra+30NS3R3frwfCz+a3H6wTVBwIDAQABAoIBAF4jei139ewXX2gg +bPXZneI4U6DbIQtkPfZmixZiYVjrl1zbmOPIRWyyd/GyxltILS2n1sU5Q70UTnVy +jJEdniUe4xMJHPPeOsamWz3NJLGcGTRBKEJK67RHJV8zAl3pDtMbR5btW1UlqmEp +XT0OyyRQPscTUaukGT3Mv1WNHSNP01nlFnhJ1JeLbhNMRqKln7HiqV4CkGdeBdwC +Ufdk0MG9o0lirlS6nr55YS6wEsos6FxNCvirovdVurNbMr3ZOSHPU5XB8gLPt2aT +gCl6k4KrNGpC3ugQbSf/uW/QOluSPB/xxGrWDj9P2a/LkWAZaLpuBJUjOLOlNiOI +C2FtciECgYEA4k3kiXFTx+dKR6OHjQcRzOk5XuXbHjhmYvB1FAyo5zqoaCnPImZH +Rd/uKPWBoPGiCoMm7J8MBQEs14JJ8JVIUlLZtknzeelxIJFq66yluUcDRSnAi19Y +B2BRNi5189Kefeeasy7KnIm/iyVrtAx1gxt/eYP+j3pdqwvbXrT+7ZcCgYEA3Ukp +KJdKWDmWaeky1vCzQjA7dw1L1vp8sCoMkgB3EJguZuPqXl2+XSkRnFYmU1DwC+Z/ +1SXP26ZhoXkQ+uIMlOqRqwqTkiM3iqz2WAdF1GPCJdR+X1whw4tpBa8NLaRl5qFy +1IR7Jeu65fkblCdBhUlUwyPIeCui9klWwAzfIhECgYEAgHtovP+yaVRPP80AMHlL +CeN/xvkJJmcu+g06618kpeMPqdPS3dzjqjAwruBz8EQ/k2hSuRSzZkP8iX5XLFgU +72hKYswph5WZvLvS0Gr8y+wdVy8VOguvlsCAWxqVrRBvG1xa4FA4iBdMwFtGgrpw +HTeHcB4YcK0wcOQSb/qioZECgYEAhKmpzTX2UjIkJNazrfyb22CDJfqIrxd4zTxI +UPeKah5yIykchvp4d+15K1rSmzx4zQmhNa33kV2MRnwIXABNPrHqJrqugfwu/ip3 +fYrOqGguKvPb11uqukrH6apqoiRfGwdLinDqS2+pmtnfWNC4DSpLcLnxI2o1xqVt +JrIQy6ECgYAkIBkDv2zs1uhnG6IzJZ4ZAOy6ix7EB+miTkQ4yafjTyz9sg3NlYrB +o/BD8W6hQ/bf4/hdBdsYuXS3PiG38SALfbApbBPNJ9RiYf69yBrUtS8QkfDM2wnw +k11HqRAxLaTTIX7ryBJb9mtK985JahDni+KGQu7SfVG2r3pWcl23RQ== +-----END RSA PRIVATE KEY----- diff --git a/Tests/TestFiles/SecureContent/sample.pub.pem b/Tests/TestFiles/SecureContent/sample.pub.pem new file mode 100644 index 000000000..b29bbea8c --- /dev/null +++ b/Tests/TestFiles/SecureContent/sample.pub.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw53q4y2KB2WcoOBUE9OE +XI0OCzUf4SI1J6fDx6XeDJ8PzqxN4pPRtXgtKfp/RiSL0invf7ASfkBMcXuhD8XP +0uki3JIzvsxTH+Jnnz/PrYnS9DFa6c9MYciTIV8vC4u03vkZH6OuGq4rWeSZuNCT +CgT59q67Ly6OytNsQgsDHL2QO8xhpYdQ4bx7F0uNn5LAxFyA0ymsFsgSSLONJWza +Vtsq9jvkIOEdTzYq52PAXMUIpegbyqSheNlmedcss8teqiZGnCOxpBxL3z+ogcFe +nX1S8kq2UhzOjXLEjPs9B0SchwXSadephL89shJwra+30NS3R3frwfCz+a3H6wTV +BwIDAQAB +-----END PUBLIC KEY----- diff --git a/Tests/TestFiles/SecureContent/sources/encrypted.txt b/Tests/TestFiles/SecureContent/sources/encrypted.txt new file mode 100644 index 000000000..bac2e9f55 --- /dev/null +++ b/Tests/TestFiles/SecureContent/sources/encrypted.txt @@ -0,0 +1,3 @@ +AES Key cipher (base64): M1YQJ+RuGnueBtDEHLjcF2MXmEe4pbf0dM+l81ZkaLJO91MgzTmCx95VqEf1TqvmylweuMyXlstbOHYrgrtwHrd8CYyUb0AGBwuacIOdvg0DO0neih5koNCFo3rnFBqflSStck7jqSEUK1me5vd4fzg052NZtTsnOj7mtbWAyP7jtD1vyGtXCzE80MEuJSHmQP4SN0LVRELXDAI/NF0LDdkgYfkHMODyL3A9HmWlZc0EcXrMvNnufPPmnDeTgWUhcb0gAu1jA8lndBgjBQia+nPKt7GZitQcYOLdpZSKk+1TaJHlquA62shAOTH2WYlqmMWGF4cDK/kNzb94N3OD2w== +AES IV (base64): +J7dJXpFg0tPpscn +AES Tag (base64): rnFabtH2rHKNIPScY9ZoJg== diff --git a/Tests/TestFiles/SecureContent/sources/encrypted_compressed.txt b/Tests/TestFiles/SecureContent/sources/encrypted_compressed.txt new file mode 100644 index 000000000..2c1bcdad7 --- /dev/null +++ b/Tests/TestFiles/SecureContent/sources/encrypted_compressed.txt @@ -0,0 +1,3 @@ +AES Key cipher (base64): S8MfTVvCiEAd27jAf48WlXJjwNfh5viXSMXqIXMYr91e2TVKtaN2Rwa5tz5CsTW9VWuRfmBG8r1297vPcBnsb8EoTysVOT8ccJVo3hK/Co7MyKfoSUK9X2Lo0bPtprXr7DnVvuLP9HSYrjSUhjapXGjSzlxjW+ARVWSwTPV9sL44ruP/J9WakaLd2uB09aWhCgZrfm9APK2dKHA0qve2+zLvNRzUiLIP1CpFAnVbWQFJxXX6kJIcUSJLd41bBanO3+E4EPm2QHfFjnXcUMB9bA6GBYSWYPXZ1pMNK/0OmrYQdUtV0+aphWv6k5FOjyTGVzZa4MOKt4nc39S/A/7IVg== +AES IV (base64): 7YBluZXfQFplDxMR +AES Tag (base64): 9vzayJDcMdDO50sPvcZgZA== diff --git a/Tests/TestFiles/SecureContent/sources/keystore_encrypted_compressed.txt b/Tests/TestFiles/SecureContent/sources/keystore_encrypted_compressed.txt new file mode 100644 index 000000000..d7575630f --- /dev/null +++ b/Tests/TestFiles/SecureContent/sources/keystore_encrypted_compressed.txt @@ -0,0 +1,6 @@ +AES Key (plain): e1 39 6a 1b f8 e 24 4b 64 c7 c6 b2 dc 79 a3 c9 98 20 b7 ee 35 bf f8 b4 79 b4 e 85 9a 2f 3a a9 +AES Key (cipher): ab 45 d6 62 da a fc a8 7c 0 27 77 da c2 db 82 69 11 62 4e 73 e0 f5 b7 77 42 bd 8c 30 b5 2 c 1f 46 89 87 8b 5d 66 f 85 22 fe c7 89 3b bb 33 ba 1c 2c 9d 40 87 b 80 5f 3e 46 78 4a a6 aa cc 50 c1 fb 4a 3d 51 86 7d 3d 33 2c ac f3 64 2 44 24 e7 40 1c 3d 56 de 80 c8 4e b7 fc ba 27 96 17 a1 e4 b6 c c 43 6e f8 32 b6 c5 b1 ef cd 9e 2d 78 58 3f 5d b 45 9c f d5 5f 21 5c 38 57 ac 1d 59 3f 4 34 bd f4 c1 48 6d 7f 6 eb 78 5c 1 39 a7 dc ff b5 3a 8b f7 e9 42 bc a4 53 55 be 3d 21 25 19 f4 bc a5 20 ce ff d1 bb 57 cb 8b 53 dc 27 a4 16 b7 cb 2b 83 17 cd a9 dc 97 d7 17 39 59 1 e6 33 71 2a 32 b3 7e c2 f3 21 70 f4 de 37 e 44 e5 12 73 cc ee 69 96 ae ed c8 41 86 f4 3a df b 3 82 bf c6 6f 39 86 cf 4b ff 8b de 4b 84 64 1c da 69 4b 6d f4 5b c c9 3f ae 95 ad b0 fa 57 a5 +AES IV (plain): 62 58 ed 1d 7b a2 b0 ed 5c 92 73 41 +AES Tag (plain): 7c 88 d1 43 f7 98 b0 2b 6f f3 9f 4e e8 d2 b4 7f +data size: 11c +IV Key (cipher) Tag (base64): YljtHXuisO1cknNBq0XWYtoK/Kh8ACd32sLbgmkRYk5z4PW3d0K9jDC1AgwfRomHi11mD4Ui/seJO7szuhwsnUCHC4BfPkZ4SqaqzFDB+0o9UYZ9PTMsrPNkAkQk50AcPVbegMhOt/y6J5YXoeS2DAxDbvgytsWx782eLXhYP10LRZwP1V8hXDhXrB1ZPwQ0vfTBSG1/But4XAE5p9z/tTqL9+lCvKRTVb49ISUZ9LylIM7/0btXy4tT3CekFrfLK4MXzancl9cXOVkB5jNxKjKzfsLzIXD03jcOROUSc8zuaZau7chBhvQ63wsDgr/GbzmGz0v/i95LhGQc2mlLbfRbDMk/rpWtsPpXpXyI0UP3mLArb/OfTujStH8= \ No newline at end of file diff --git a/Tests/TestFiles/SecureContent/sources/sample.txt b/Tests/TestFiles/SecureContent/sources/sample.txt new file mode 100644 index 000000000..2dbf8e639 --- /dev/null +++ b/Tests/TestFiles/SecureContent/sources/sample.txt @@ -0,0 +1,9 @@ +Modulus: c3 9d ea e3 2d 8a 7 65 9c a0 e0 54 13 d3 84 5c 8d e b 35 1f e1 22 35 27 a7 c3 c7 a5 de c 9f f ce ac 4d e2 93 d1 b5 78 2d 29 fa 7f 46 24 8b d2 29 ef 7f b0 12 7e 40 4c 71 7b a1 f c5 cf d2 e9 22 dc 92 33 be cc 53 1f e2 67 9f 3f cf ad 89 d2 f4 31 5a e9 cf 4c 61 c8 93 21 5f 2f b 8b b4 de f9 19 1f a3 ae 1a ae 2b 59 e4 99 b8 d0 93 a 4 f9 f6 ae bb 2f 2e 8e ca d3 6c 42 b 3 1c bd 90 3b cc 61 a5 87 50 e1 bc 7b 17 4b 8d 9f 92 c0 c4 5c 80 d3 29 ac 16 c8 12 48 b3 8d 25 6c da 56 db 2a f6 3b e4 20 e1 1d 4f 36 2a e7 63 c0 5c c5 8 a5 e8 1b ca a4 a1 78 d9 66 79 d7 2c b3 cb 5e aa 26 46 9c 23 b1 a4 1c 4b df 3f a8 81 c1 5e 9d 7d 52 f2 4a b6 52 1c ce 8d 72 c4 8c fb 3d 7 44 9c 87 5 d2 69 d7 a9 84 bf 3d b2 12 70 ad af b7 d0 d4 b7 47 77 eb c1 f0 b3 f9 ad c7 eb 4 d5 7 +Modulus (base64): w53q4y2KB2WcoOBUE9OEXI0OCzUf4SI1J6fDx6XeDJ8PzqxN4pPRtXgtKfp/RiSL0invf7ASfkBMcXuhD8XP0uki3JIzvsxTH+Jnnz/PrYnS9DFa6c9MYciTIV8vC4u03vkZH6OuGq4rWeSZuNCTCgT59q67Ly6OytNsQgsDHL2QO8xhpYdQ4bx7F0uNn5LAxFyA0ymsFsgSSLONJWzaVtsq9jvkIOEdTzYq52PAXMUIpegbyqSheNlmedcss8teqiZGnCOxpBxL3z+ogcFenX1S8kq2UhzOjXLEjPs9B0SchwXSadephL89shJwra+30NS3R3frwfCz+a3H6wTVBw== +Exponent: 1 0 1 +Exponent (base64): AQAB +AES Key (plain): 55 71 20 42 d5 ee 8b 72 f8 b0 70 8e 3a e1 66 da 8c d0 8d 16 c5 ea b4 96 6d 44 23 c2 65 cb c0 2f +AES Key (cipher): 55 a8 c5 cd dd ae c3 8a 7e 60 21 75 b9 41 68 f1 2b 13 7d af d9 4d 21 c9 1d 3c 6f d8 d4 13 30 9c ab 27 f7 f7 e5 a3 e4 8a 75 9f 24 16 b5 17 d2 27 39 d3 25 5b 92 36 a0 84 6e e8 a2 ef ab c9 e1 de a1 7d 56 c9 d4 f8 5d 60 a0 d4 93 24 f3 55 20 78 5e b3 cf d7 e3 7a a3 df 2 64 93 db 83 aa ea 9f a1 aa 85 f2 c2 e3 f1 a8 93 11 75 9f 32 d4 df 3b 97 8 4a 82 49 e9 be 0 3d f2 c2 46 34 7d 37 d0 5 9d 9e ad aa 91 e0 48 ce ac b0 e7 c4 21 9d eb 94 4e 14 cb 8e 1f 35 b5 57 7e 91 f0 6f d2 25 e9 8b 68 5f 81 2f 57 56 fa da 3b a8 5a b3 ab 72 c1 f2 16 f5 0 3 fb f9 a8 40 cd cb 0 ff f4 ad a6 7c fd 6 98 1a 97 ef cb a1 42 c 53 b8 fb 4f 9f b6 77 82 69 3e f2 7e dc ce 33 c fe 64 a7 93 6 24 57 cd ca 16 78 86 74 78 39 b8 c5 c0 2d d7 73 3f 41 d6 57 63 6c d0 29 56 36 85 ad c9 b5 72 25 +AES IV (plain): a4 fc a e8 4 9 6f 29 b3 e6 4b 31 +AES Tag (plain): aa 2e 9a 20 30 5 30 e3 f5 c9 72 b8 d0 98 3 74 +IV Key (cipher) Tag (base64): pPwK6AQJbymz5ksxVajFzd2uw4p+YCF1uUFo8SsTfa/ZTSHJHTxv2NQTMJyrJ/f35aPkinWfJBa1F9InOdMlW5I2oIRu6KLvq8nh3qF9VsnU+F1goNSTJPNVIHhes8/X43qj3wJkk9uDquqfoaqF8sLj8aiTEXWfMtTfO5cISoJJ6b4APfLCRjR9N9AFnZ6tqpHgSM6ssOfEIZ3rlE4Uy44fNbVXfpHwb9Il6YtoX4EvV1b62juoWrOrcsHyFvUAA/v5qEDNywD/9K2mfP0GmBqX78uhQgxTuPtPn7Z3gmk+8n7czjMM/mSnkwYkV83KFniGdHg5uMXALddzP0HWV2Ns0ClWNoWtybVyJaoumiAwBTDj9clyuNCYA3Q= \ No newline at end of file diff --git a/Tests/libressl b/Tests/libressl new file mode 160000 index 000000000..c80f8ed8f --- /dev/null +++ b/Tests/libressl @@ -0,0 +1 @@ +Subproject commit c80f8ed8f1ce203f7cd86fa0324bfef952c21661 diff --git a/Tests/memcheck/conditional.valgrind.supp b/Tests/memcheck/conditional.valgrind.supp new file mode 100644 index 000000000..9b881eed8 --- /dev/null +++ b/Tests/memcheck/conditional.valgrind.supp @@ -0,0 +1,13 @@ +{ + + Memcheck:Cond + ... + fun:lib3mf_writer_writetobuffer +} + +{ + + Memcheck:Cond + ... + fun:lib3mf_reader_readfromfile +} diff --git a/cmake/GenerateMakeFast.sh b/cmake/GenerateMakeFast.sh new file mode 100644 index 000000000..f8c1ac4bf --- /dev/null +++ b/cmake/GenerateMakeFast.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +basepath="$(cd "$(dirname "$0")" && pwd)" +builddir="$basepath/../build" +mkdir -p "$builddir" +cd "$builddir" +cmake .. -G "Unix Makefiles" -DCMAKE_CXX_FLAGS:STRING="-Ofast" "$@" + diff --git a/lib3MF.pc.in b/lib3mf.pc.in similarity index 89% rename from lib3MF.pc.in rename to lib3mf.pc.in index 9afb6ee88..bb8030abf 100644 --- a/lib3MF.pc.in +++ b/lib3mf.pc.in @@ -8,5 +8,5 @@ Description: @PROJECT_DESCRIPTION@ Version: @PROJECT_VERSION@ Requires: -Libs: -L${libdir} -l3MF -lzip -lz +Libs: -L${libdir} -l3mf -lzip -lz Cflags: -I${includedir}