From 11f6f498ab8e2f906a190a0f6e0d9a622bdc6bdb Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Tue, 23 Sep 2025 14:17:47 -0500 Subject: [PATCH] 3rdParty: Remove original libE57Format --- src/3rdParty/libE57Format/.clang-format | 108 - .../libE57Format/.clang-format-ignore | 1 - src/3rdParty/libE57Format/.github/FUNDING.yml | 1 - .../libE57Format/.github/workflows/build.yml | 82 - src/3rdParty/libE57Format/.travis.yml | 42 - src/3rdParty/libE57Format/CHANGELOG.md | 103 - src/3rdParty/libE57Format/CMakeLists.txt | 206 - src/3rdParty/libE57Format/CONTRIBUTING.md | 21 - src/3rdParty/libE57Format/LICENSE.md | 23 - src/3rdParty/libE57Format/README.md | 53 - .../cmake/Modules/ClangFormat.cmake | 19 - .../cmake/Modules/E57ExportHeader.cmake | 38 - .../libE57Format/cmake/Modules/Tags.cmake | 41 - .../libE57Format/cmake/e57format-config.cmake | 9 - .../libE57Format/extern/CRCpp/CMakeLists.txt | 14 - .../libE57Format/extern/CRCpp/LICENSE | 28 - .../libE57Format/extern/CRCpp/README.md | 154 - .../libE57Format/extern/CRCpp/inc/CRC.h | 1703 ------ .../libE57Format/include/CMakeLists.txt | 28 - .../libE57Format/include/E57Exception.h | 136 - src/3rdParty/libE57Format/include/E57Format.h | 697 --- .../libE57Format/include/E57SimpleData.h | 653 --- .../libE57Format/include/E57SimpleReader.h | 186 - .../libE57Format/include/E57SimpleWriter.h | 137 - .../libE57Format/src/BlobNodeImpl.cpp | 226 - src/3rdParty/libE57Format/src/BlobNodeImpl.h | 65 - src/3rdParty/libE57Format/src/CMakeLists.txt | 63 - src/3rdParty/libE57Format/src/CheckedFile.cpp | 803 --- src/3rdParty/libE57Format/src/CheckedFile.h | 128 - src/3rdParty/libE57Format/src/Common.cpp | 39 - src/3rdParty/libE57Format/src/Common.h | 183 - .../src/CompressedVectorNodeImpl.cpp | 360 -- .../src/CompressedVectorNodeImpl.h | 93 - .../src/CompressedVectorReaderImpl.cpp | 607 -- .../src/CompressedVectorReaderImpl.h | 75 - .../src/CompressedVectorWriterImpl.cpp | 661 --- .../src/CompressedVectorWriterImpl.h | 76 - .../libE57Format/src/DecodeChannel.cpp | 88 - src/3rdParty/libE57Format/src/DecodeChannel.h | 55 - src/3rdParty/libE57Format/src/Decoder.cpp | 892 --- src/3rdParty/libE57Format/src/Decoder.h | 180 - .../libE57Format/src/E57Exception.cpp | 447 -- src/3rdParty/libE57Format/src/E57Format.cpp | 4891 ----------------- .../libE57Format/src/E57SimpleData.cpp | 25 - .../libE57Format/src/E57SimpleReader.cpp | 131 - .../libE57Format/src/E57SimpleWriter.cpp | 103 - src/3rdParty/libE57Format/src/E57Version.h | 12 - .../libE57Format/src/E57XmlParser.cpp | 919 ---- src/3rdParty/libE57Format/src/E57XmlParser.h | 126 - src/3rdParty/libE57Format/src/Encoder.cpp | 977 ---- src/3rdParty/libE57Format/src/Encoder.h | 197 - .../libE57Format/src/FloatNodeImpl.cpp | 242 - src/3rdParty/libE57Format/src/FloatNodeImpl.h | 67 - .../libE57Format/src/ImageFileImpl.cpp | 945 ---- src/3rdParty/libE57Format/src/ImageFileImpl.h | 124 - .../libE57Format/src/IntegerNodeImpl.cpp | 167 - .../libE57Format/src/IntegerNodeImpl.h | 65 - src/3rdParty/libE57Format/src/NodeImpl.cpp | 431 -- src/3rdParty/libE57Format/src/NodeImpl.h | 101 - src/3rdParty/libE57Format/src/Packet.cpp | 734 --- src/3rdParty/libE57Format/src/Packet.h | 141 - src/3rdParty/libE57Format/src/ReaderImpl.cpp | 1434 ----- src/3rdParty/libE57Format/src/ReaderImpl.h | 112 - .../src/ScaledIntegerNodeImpl.cpp | 240 - .../libE57Format/src/ScaledIntegerNodeImpl.h | 76 - .../libE57Format/src/SectionHeaders.cpp | 97 - .../libE57Format/src/SectionHeaders.h | 67 - .../libE57Format/src/SourceDestBufferImpl.cpp | 1045 ---- .../libE57Format/src/SourceDestBufferImpl.h | 132 - .../libE57Format/src/StringNodeImpl.cpp | 145 - .../libE57Format/src/StringNodeImpl.h | 61 - .../libE57Format/src/StructureNodeImpl.cpp | 470 -- .../libE57Format/src/StructureNodeImpl.h | 71 - .../libE57Format/src/VectorNodeImpl.cpp | 139 - .../libE57Format/src/VectorNodeImpl.h | 59 - src/3rdParty/libE57Format/src/WriterImpl.cpp | 1113 ---- src/3rdParty/libE57Format/src/WriterImpl.h | 87 - 77 files changed, 25270 deletions(-) delete mode 100644 src/3rdParty/libE57Format/.clang-format delete mode 100644 src/3rdParty/libE57Format/.clang-format-ignore delete mode 100644 src/3rdParty/libE57Format/.github/FUNDING.yml delete mode 100644 src/3rdParty/libE57Format/.github/workflows/build.yml delete mode 100644 src/3rdParty/libE57Format/.travis.yml delete mode 100644 src/3rdParty/libE57Format/CHANGELOG.md delete mode 100644 src/3rdParty/libE57Format/CMakeLists.txt delete mode 100644 src/3rdParty/libE57Format/CONTRIBUTING.md delete mode 100644 src/3rdParty/libE57Format/LICENSE.md delete mode 100644 src/3rdParty/libE57Format/README.md delete mode 100644 src/3rdParty/libE57Format/cmake/Modules/ClangFormat.cmake delete mode 100644 src/3rdParty/libE57Format/cmake/Modules/E57ExportHeader.cmake delete mode 100644 src/3rdParty/libE57Format/cmake/Modules/Tags.cmake delete mode 100644 src/3rdParty/libE57Format/cmake/e57format-config.cmake delete mode 100644 src/3rdParty/libE57Format/extern/CRCpp/CMakeLists.txt delete mode 100644 src/3rdParty/libE57Format/extern/CRCpp/LICENSE delete mode 100644 src/3rdParty/libE57Format/extern/CRCpp/README.md delete mode 100644 src/3rdParty/libE57Format/extern/CRCpp/inc/CRC.h delete mode 100644 src/3rdParty/libE57Format/include/CMakeLists.txt delete mode 100644 src/3rdParty/libE57Format/include/E57Exception.h delete mode 100644 src/3rdParty/libE57Format/include/E57Format.h delete mode 100644 src/3rdParty/libE57Format/include/E57SimpleData.h delete mode 100644 src/3rdParty/libE57Format/include/E57SimpleReader.h delete mode 100644 src/3rdParty/libE57Format/include/E57SimpleWriter.h delete mode 100644 src/3rdParty/libE57Format/src/BlobNodeImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/BlobNodeImpl.h delete mode 100644 src/3rdParty/libE57Format/src/CMakeLists.txt delete mode 100644 src/3rdParty/libE57Format/src/CheckedFile.cpp delete mode 100644 src/3rdParty/libE57Format/src/CheckedFile.h delete mode 100644 src/3rdParty/libE57Format/src/Common.cpp delete mode 100644 src/3rdParty/libE57Format/src/Common.h delete mode 100644 src/3rdParty/libE57Format/src/CompressedVectorNodeImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/CompressedVectorNodeImpl.h delete mode 100644 src/3rdParty/libE57Format/src/CompressedVectorReaderImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/CompressedVectorReaderImpl.h delete mode 100644 src/3rdParty/libE57Format/src/CompressedVectorWriterImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/CompressedVectorWriterImpl.h delete mode 100644 src/3rdParty/libE57Format/src/DecodeChannel.cpp delete mode 100644 src/3rdParty/libE57Format/src/DecodeChannel.h delete mode 100644 src/3rdParty/libE57Format/src/Decoder.cpp delete mode 100644 src/3rdParty/libE57Format/src/Decoder.h delete mode 100644 src/3rdParty/libE57Format/src/E57Exception.cpp delete mode 100644 src/3rdParty/libE57Format/src/E57Format.cpp delete mode 100644 src/3rdParty/libE57Format/src/E57SimpleData.cpp delete mode 100644 src/3rdParty/libE57Format/src/E57SimpleReader.cpp delete mode 100644 src/3rdParty/libE57Format/src/E57SimpleWriter.cpp delete mode 100644 src/3rdParty/libE57Format/src/E57Version.h delete mode 100644 src/3rdParty/libE57Format/src/E57XmlParser.cpp delete mode 100644 src/3rdParty/libE57Format/src/E57XmlParser.h delete mode 100644 src/3rdParty/libE57Format/src/Encoder.cpp delete mode 100644 src/3rdParty/libE57Format/src/Encoder.h delete mode 100644 src/3rdParty/libE57Format/src/FloatNodeImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/FloatNodeImpl.h delete mode 100644 src/3rdParty/libE57Format/src/ImageFileImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/ImageFileImpl.h delete mode 100644 src/3rdParty/libE57Format/src/IntegerNodeImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/IntegerNodeImpl.h delete mode 100644 src/3rdParty/libE57Format/src/NodeImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/NodeImpl.h delete mode 100644 src/3rdParty/libE57Format/src/Packet.cpp delete mode 100644 src/3rdParty/libE57Format/src/Packet.h delete mode 100644 src/3rdParty/libE57Format/src/ReaderImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/ReaderImpl.h delete mode 100644 src/3rdParty/libE57Format/src/ScaledIntegerNodeImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/ScaledIntegerNodeImpl.h delete mode 100644 src/3rdParty/libE57Format/src/SectionHeaders.cpp delete mode 100644 src/3rdParty/libE57Format/src/SectionHeaders.h delete mode 100644 src/3rdParty/libE57Format/src/SourceDestBufferImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/SourceDestBufferImpl.h delete mode 100644 src/3rdParty/libE57Format/src/StringNodeImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/StringNodeImpl.h delete mode 100644 src/3rdParty/libE57Format/src/StructureNodeImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/StructureNodeImpl.h delete mode 100644 src/3rdParty/libE57Format/src/VectorNodeImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/VectorNodeImpl.h delete mode 100644 src/3rdParty/libE57Format/src/WriterImpl.cpp delete mode 100644 src/3rdParty/libE57Format/src/WriterImpl.h diff --git a/src/3rdParty/libE57Format/.clang-format b/src/3rdParty/libE57Format/.clang-format deleted file mode 100644 index 263a8e7976..0000000000 --- a/src/3rdParty/libE57Format/.clang-format +++ /dev/null @@ -1,108 +0,0 @@ -# libE57Format -# Options are listed here: -# https://clang.llvm.org/docs/ClangFormatStyleOptions.html ---- -AccessModifierOffset: -3 -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignEscapedNewlines: Right -AlignOperands: true -AlignTrailingComments: true -AllowAllArgumentsOnNextLine: true -AllowAllConstructorInitializersOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: None -AllowShortLambdasOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Never -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: MultiLine -BinPackArguments: true -BinPackParameters: true -BraceWrapping: - AfterCaseLabel: true - AfterClass: true - AfterControlStatement: true - AfterEnum: true - AfterFunction: true - AfterNamespace: true - AfterStruct: true - AfterUnion: true - AfterExternBlock: true - BeforeCatch: true - BeforeElse: true - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Custom -BreakBeforeInheritanceComma: false -BreakInheritanceList: BeforeColon -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: AfterColon -BreakStringLiterals: true -ColumnLimit: 120 -CommentPragmas: '^ IWYU pragma:' -CompactNamespaces: false -ConstructorInitializerAllOnOneLineOrOnePerLine: false -ConstructorInitializerIndentWidth: 3 -ContinuationIndentWidth: 3 -Cpp11BracedListStyle: false -DerivePointerAlignment: false -FixNamespaceComments: false -IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - - Regex: '.*' - Priority: 1 -IncludeIsMainRegex: '(Test)?$' -IndentCaseLabels: true -IndentPPDirectives: None -IndentWidth: 3 -IndentWrappedFunctionNames: true -KeepEmptyLinesAtTheStartOfBlocks: true -Language: Cpp -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: All -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 1000 -PointerAlignment: Right -ReflowComments: true -SortIncludes: true -SortUsingDeclarations: true -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInParentheses: true -SpacesInSquareBrackets: false -Standard: Cpp11 -TabWidth: 3 -UseTab: Never -... diff --git a/src/3rdParty/libE57Format/.clang-format-ignore b/src/3rdParty/libE57Format/.clang-format-ignore deleted file mode 100644 index da7f5bcd6d..0000000000 --- a/src/3rdParty/libE57Format/.clang-format-ignore +++ /dev/null @@ -1 +0,0 @@ -extern/* diff --git a/src/3rdParty/libE57Format/.github/FUNDING.yml b/src/3rdParty/libE57Format/.github/FUNDING.yml deleted file mode 100644 index 23969bd50a..0000000000 --- a/src/3rdParty/libE57Format/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -github: [asmaloney] diff --git a/src/3rdParty/libE57Format/.github/workflows/build.yml b/src/3rdParty/libE57Format/.github/workflows/build.yml deleted file mode 100644 index aab2850418..0000000000 --- a/src/3rdParty/libE57Format/.github/workflows/build.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Build - -on: [push, pull_request] - -jobs: - build: - name: ${{ matrix.config.name }} (${{ matrix.build_type }}) - runs-on: ${{ matrix.config.os }} - if: "!contains(github.event.head_commit.message, '[skip ci]')" - - strategy: - fail-fast: false - matrix: - build_type: ["Debug", "Release"] - config: - - { - name: "macOS Clang", - os: macos-latest, - } - - { - name: "Ubuntu GCC", - os: ubuntu-latest, - } - - { - name: "Windows MSVC", - os: windows-latest, - } - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Install Dependencies (macOS) - if: matrix.config.os == 'macos-latest' - run: | - brew install ninja xerces-c - - - name: Install Dependencies (Ubuntu) - if: matrix.config.os == 'ubuntu-latest' - run: | - sudo apt-get update - - sudo apt-get install -y libxerces-c-dev ninja-build - - - name: Install miniconda (Windows) - if: matrix.config.os == 'windows-latest' - uses: conda-incubator/setup-miniconda@v2 - with: - auto-update-conda: true - channels: conda-forge - miniconda-version: 'latest' - - - name: Install Dependencies (Windows) - if: matrix.config.os == 'windows-latest' - run: | - conda install -y ninja xerces-c - - - name: Configure MSVC console (Windows) - if: matrix.config.os == 'windows-latest' - uses: ilammy/msvc-dev-cmd@v1 - - - name: Set environment for MSVC (Windows) - if: matrix.config.os == 'windows-latest' - run: | - # Set these env vars so cmake picks the correct compiler - echo "CXX=cl.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - echo "CC=cl.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Configure - run: > - mkdir libE57Format-build - - cmake - -B libE57Format-build - -G "Ninja" - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} - -DCMAKE_CXX_FLAGS_DEBUG="-g -DE57_MAX_VERBOSE" - . - - - name: Build - run: | - cmake --build libE57Format-build diff --git a/src/3rdParty/libE57Format/.travis.yml b/src/3rdParty/libE57Format/.travis.yml deleted file mode 100644 index cecd002599..0000000000 --- a/src/3rdParty/libE57Format/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -dist: xenial -sudo: false -language: cpp - -env: - global: - # For coverity - - secure: "Ddou0BLHkn4V8b/Q6E56lUVz4woSXS8eI0IzRxyYqkDvXtqqjSlxqtu2fuU/awieA6Y5rzEHZrpHnvJU80uC+gnlIfMkIU9O0Cj0rwppKTTTWpXzohrESfXzJc8iZs+3gxpReZhWp6IGrfitdudfpFAgLWBENgzemWsHy7prnDcQQA99FBUhCuhbqhtXRR8wxXUWNQr2RntbFbH22Eqcwbd5a+OYpPSCtV296ZII6/iskMI3OeXCEGnqKBxe2L9oohcrTS/0beCLM7dhCflelns8MTGa1AYmJEwXf3/n4PmwRo7EjTpSBow70n9SCps5mS42+wRDU8FMBTNgqzBNjOdDojrPhijnEPfhRzFygsyfgoEmuZjD2MuXBSIwpYa9mFusVpN2BON3zZLvmw5Y1HuBadf3yLoD0/Vy1K6YBnQRMIm5JhVYj4hY8ogtPNVfjYjckHEPlCRcwzS5rwh/sZ2eYW30LW3IusCB2wu3/iR97jamBu3sEOY67ln3M6EOjnMPHApBqsVhapQv+XtOtxaVPzKVc1u6tlzRRijPCfcN6ssNHzFh1feqFopthapY4erfA+DrjQivW+E49Yv306ig6HVBbrMkOR+TX+bgDmZisLtbJ8d2eym063KuojBRqDlq8wrz0MlUXVIz2H0FhXPIho8z9Uj7fkswM+jQiJc=" - matrix: - - BUILD_TYPE=Debug - - BUILD_TYPE=Release - -compiler: - - clang - - gcc - -before_install: - - echo -n | openssl s_client -connect https://scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- - -addons: - apt: - packages: - - libxerces-c-dev - coverity_scan: - project: - name: "asmaloney/libE57Format" - description: "Library for reading & writing the E57 file format (fork of E57RefImpl) " - notification_email: asmaloney@gmail.com - build_command_prepend: "cmake -DCMAKE_BUILD_TYPE=Debug ." - build_command: "make -j2" - branch_pattern: coverity_scan - -before_script: - - mkdir build-${BUILD_TYPE} - - cd build-${BUILD_TYPE} - - cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_CXX_FLAGS_DEBUG="-g -DE57_MAX_VERBOSE" .. - -script: - - if [[ "${COVERITY_SCAN_BRANCH}" != 1 ]]; then - $CC_FOR_BUILD -v && $CXX_FOR_BUILD -v && cmake --version; - make -j2; - fi diff --git a/src/3rdParty/libE57Format/CHANGELOG.md b/src/3rdParty/libE57Format/CHANGELOG.md deleted file mode 100644 index 30c083bcbf..0000000000 --- a/src/3rdParty/libE57Format/CHANGELOG.md +++ /dev/null @@ -1,103 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - -## 2.2.1 - (in progress) - -### Fixed - -- Fix compilation with [musl libc](https://musl.libc.org/) ([#70](https://github.com/asmaloney/libE57Format/pull/70)) (Thanks Dimitri!) -- Add missing include for [GCC 11](https://gcc.gnu.org/gcc-11/porting_to.html#header-dep-changes) ([#68](https://github.com/asmaloney/libE57Format/pull/68)) (Thanks bartoszek!) - -## [2.2.0](https://github.com/asmaloney/libE57Format/releases/tag/v2.2.0) - 2021-04-01 - -### Added - -- Added and updated the E57Simple API from the old reference library. ([#41](https://github.com/asmaloney/libE57Format/pull/41), [#63](https://github.com/asmaloney/libE57Format/pull/63)) (Thanks Jiri & Grégoire!) -- Enabled building E57Format as a shared library. ([#40](https://github.com/asmaloney/libE57Format/pull/40)) (Thanks Amodio!) -- Added a [clang-format](https://clang.llvm.org/docs/ClangFormat.html) file, a cmake target for it ("format"), and reformatted the code. -- {doc} Added info about using [SPDX License Identifiers](https://spdx.org/ids). -- {ci} Added GitHub Actions to build macOS, Linux, and Windows. ([#35](https://github.com/asmaloney/libE57Format/pull/35)) - -### Changed - -- `E57_V1_0_URI` was changed from a `#define` to a `constexpr`, so if you use it, it will need to be updated with a namespace: `e57::E57_V1_0_URI`. -- {doc} Moved some documentation to new repo ([libE57Format-docs](https://github.com/asmaloney/libE57Format-docs)) and generate the [docs](https://asmaloney.github.io/libE57Format-docs/). -- {cmake} Reviewed and updated cmake files. CMake minimum version was changed to 3.10. - -### Fixed - -- Fixed building with E57_MAX_VERBOSE defined. ([#44](https://github.com/asmaloney/libE57Format/pull/44)) -- {win} Fixed MSVC warnings. ([#34](https://github.com/asmaloney/libE57Format/pull/34), [#36](https://github.com/asmaloney/libE57Format/pull/36)) - -### Other - -- Removed all internal usage of dynamic_cast<>. ([#39](https://github.com/asmaloney/libE57Format/pull/39)) (Thanks Jiri!) -- Split classes out from E57FormatImpl.[h,cpp] intot their own files. - -## [2.1.0](https://github.com/asmaloney/libE57Format/releases/tag/v2.1) - 2020-04-01 - -### Added - -- Added support for UTF8 file names on Windows. (based on [#26](https://github.com/asmaloney/libE57Format/issues/26)) -- Added support for _char\*_ input. ([#22](https://github.com/asmaloney/libE57Format/pull/22)) -- {cmake} Added fallback configuration for RelWithDebInfo and MinSizeRel. ([#29](https://github.com/asmaloney/libE57Format/pull/29)) -- {cmake} Added a proper install configuration. ([#28](https://github.com/asmaloney/libE57Format/pull/28)) - -### Changed - -- {cmake} Removed unused ICU requirement for Linux. - -### Fixed - -- {cmake} Marked xerces-c as required. - -### Other - -- {cmake} Various cleanups. -- Internal code cleanups. - -## [2.0.1](https://github.com/asmaloney/libE57Format/releases/tag/v2.0.1) - 2019-01-15 - -### Fixed - -- Writing files was broken and would produce the following error: - > Error: bad API function argument provided by user (E57_ERROR_BAD_API_ARGUMENT) (ImageFileImpl.cpp line 109) - -## [2.0.0](https://github.com/asmaloney/libE57Format/releases/tag/v2.0) - 2019-01-06 - -Forked from [E57RefImpl](https://sourceforge.net/projects/e57-3d-imgfmt/). - -### Added - -- Added a checksum policy (see _ReadChecksumPolicy_ in _E57Format.h_) so the library user can decide how frequently to check them. -- {win} Added cmake option ()`USING_STATIC_XERCES`) to tell the build if you are using a static Xerces lib. - -### Changed - -- Now requires C++11. -- Now requires cmake 3.1+. -- No longer uses BOOST. -- Turn off `E57_MAX_DEBUG` by default. - -### Removed - -- Removed all but the main sources for reading and writing E57 files. -- Removed "big endian" byte swap code (not sure it was working and no way to test). - -### Fixed - -- Multiple fixes for compilation on macOS. -- Fixed a couple of fallthrough bugs which would result in undefined behaviour. - -### Other - -- Improved file read times. -- Many, many code cleanups: - - Refactored the code into multiple files. - - Removed unused macros and code. - - Removed non-useful comments. - - Added proper initialization of class and struct members. - - Modernized using c++11. diff --git a/src/3rdParty/libE57Format/CMakeLists.txt b/src/3rdParty/libE57Format/CMakeLists.txt deleted file mode 100644 index 0e7678c244..0000000000 --- a/src/3rdParty/libE57Format/CMakeLists.txt +++ /dev/null @@ -1,206 +0,0 @@ -# This is a rewrite over time of the CMake file from the libe57 reference implementation -# https://en.wikipedia.org/wiki/Ship_of_Theseus -# -# Use git blame to see all the changes and who has contributed. -# -# Original work Copyright 2010-2012 Roland Schwarz, Riegl LMS GmbH -# Modified work Copyright 2018-2020 Andy Maloney -# -# Permission is hereby granted, free of charge, to any person or organization -# obtaining a copy of the software and accompanying documentation covered by -# this license (the "Software") to use, reproduce, display, distribute, -# execute, and transmit the Software, and to prepare derivative works of the -# Software, and to permit third-parties to whom the Software is furnished to -# do so, all subject to the following: -# -# The copyright notices in the Software and this entire statement, including -# the above license grant, this restriction and the following disclaimer, -# must be included in all copies of the Software, in whole or in part, and -# all derivative works of the Software, unless such copies or derivative -# works are solely in the form of machine-executable object code generated by -# a source language processor. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -# SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -# FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -cmake_minimum_required( VERSION 3.10.0 ) - -# Set a private module find path -set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/" ) - -project( E57Format - DESCRIPTION - "E57Format is a library to read and write E57 files" - LANGUAGES - CXX - VERSION - 2.2.1 -) - -include( Tags ) - -# Check if we are building ourself or being included and use this to set some defaults -if ( ${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME} ) - set( E57_BUILDING_SELF ON ) -endif() - -# propose a default installation directory -if ( E57_BUILDING_SELF ) - if( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT ) - string( REGEX REPLACE "/${PROJECT_NAME}" "" CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} ) - set( T_ ${PROJECT_NAME} ) - set( T_ ${T_}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} ) - set( T_ ${T_}-${${PROJECT_NAME}_BUILD_TAG} ) - set( CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/${T_} - CACHE PATH - "Install path prefix, prepended onto install directories." - FORCE - ) - endif() -endif() - -find_package( Threads REQUIRED ) -find_package( XercesC REQUIRED ) - -option( E57_BUILD_SHARED - "Compile E57Format as a shared library" - OFF -) - -if( BUILD_SHARED_LIBS ) - set( E57_BUILD_SHARED ON ) -endif() - -######################################################################################### - -# Various levels of cross checking and verification in the code. -# The extra code does not change the file contents. -# Recommend that E57_DEBUG remain defined even for production versions. - -option( E57_DEBUG "Compile library with minimal debug checking" ON ) -option( E57_MAX_DEBUG "Compile library with maximum debug checking" OFF ) - -# Various levels of printing to the console of what is going on in the code. -# Optional - -option( E57_VERBOSE "Compile library with verbose logging" OFF ) -option( E57_MAX_VERBOSE "Compile library with maximum verbose logging" OFF ) - -# Enable writing packets that are correct but will stress the reader. - -option( E57_WRITE_CRAZY_PACKET_MODE "Compile library to enable reader-stressing packets" OFF ) - -######################################################################################### - -set( revision_id "${PROJECT_NAME}-${PROJECT_VERSION}-${${PROJECT_NAME}_BUILD_TAG}" ) -message( STATUS "[E57] Revision ID: ${revision_id}" ) - -# Need to explicitly set the source files to add_library() -if(${CMAKE_VERSION} VERSION_LESS "3.11.0") - file(GLOB E57Format_SOURCES src/[^.]*.cpp) -endif() - -# Target -if ( E57_BUILD_SHARED ) - message( STATUS "[E57] Building shared library" ) - add_library( E57Format SHARED ${E57Format_SOURCES}) -else() - message( STATUS "[E57] Building static library" ) - add_library( E57Format STATIC ${E57Format_SOURCES}) -endif() - -include( E57ExportHeader ) - -# Main sources and includes -add_subdirectory( extern/CRCpp ) -add_subdirectory( include ) -add_subdirectory( src ) - -include( ClangFormat ) - -# Target properties -set_target_properties( E57Format - PROPERTIES - CXX_STANDARD 11 - CXX_STANDARD_REQUIRED YES - CXX_EXTENSIONS NO - DEBUG_POSTFIX "-d" - POSITION_INDEPENDENT_CODE ON -) - -# Target definitions -target_compile_definitions( E57Format - PRIVATE - CRCPP_USE_CPP11 - CRCPP_BRANCHLESS - REVISION_ID="${revision_id}" -) - -if ( E57_DEBUG ) - target_compile_definitions( E57Format PRIVATE E57_DEBUG ) -endif() - -if ( E57_MAX_DEBUG ) - target_compile_definitions( E57Format PRIVATE E57_MAX_DEBUG ) -endif() - -if ( E57_VERBOSE ) - target_compile_definitions( E57Format PRIVATE E57_VERBOSE ) -endif() - -if ( E57_MAX_VERBOSE ) - target_compile_definitions( E57Format PRIVATE E57_MAX_VERBOSE ) -endif() - -if ( E57_WRITE_CRAZY_PACKET_MODE ) - target_compile_definitions( E57Format PRIVATE E57_WRITE_CRAZY_PACKET_MODE ) -endif() - -if ( WIN32 ) - option( USING_STATIC_XERCES "Turn on if you are linking with Xerces as a static lib" OFF ) - if ( USING_STATIC_XERCES ) - target_compile_definitions( E57Format - PUBLIC - XERCES_STATIC_LIBRARY - ) - endif() -endif() - -# Suppress all warnings for this specific 3rd-party target -target_compile_options(E57Format PRIVATE - $<$:-w> - $<$:/w> -) - -# Target Libraries -target_link_libraries( E57Format PRIVATE XercesC::XercesC ) - -# Install -install( - TARGETS - E57Format - EXPORT - E57Format-export - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) - -# CMake package files -#install( -# EXPORT -# E57Format-export -# DESTINATION lib/cmake/E57Format -#) - -#install( -# FILES -# ${CMAKE_CURRENT_SOURCE_DIR}/cmake/e57format-config.cmake -# DESTINATION -# lib/cmake/E57Format -#) diff --git a/src/3rdParty/libE57Format/CONTRIBUTING.md b/src/3rdParty/libE57Format/CONTRIBUTING.md deleted file mode 100644 index d84c3e7e68..0000000000 --- a/src/3rdParty/libE57Format/CONTRIBUTING.md +++ /dev/null @@ -1,21 +0,0 @@ -# How To Contribute - -## Code Changes - -I am happy to review any [pull requests](https://github.com/asmaloney/libE57Format/pulls). Please keep them as short as possible. Each pull request should be atomic and only address one issue. This helps with the review process. - -### Formatting - -This project uses [clang-format](https://clang.llvm.org/docs/ClangFormat.html) to format the code. There is a cmake target (_format_) - which runs _clang-format_ on the source files. After changes have been made, and before you submit your pull request, please run the following: - -```sh -cmake --build . --target format -``` - -## Documentation - -The [documentation](https://github.com/asmaloney/libE57Format) is a bit old and could use some lovin'. You can submit changes over in the [libE57Format-docs](https://github.com/asmaloney/libE57Format-docs) repository. - -## Financial - -If you would like to support the project financially, you can use the **Sponsor** button at the top of the [libE57Format](https://github.com/asmaloney/libE57Format) repository page. diff --git a/src/3rdParty/libE57Format/LICENSE.md b/src/3rdParty/libE57Format/LICENSE.md deleted file mode 100644 index 36b7cd93cd..0000000000 --- a/src/3rdParty/libE57Format/LICENSE.md +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/src/3rdParty/libE57Format/README.md b/src/3rdParty/libE57Format/README.md deleted file mode 100644 index 2ce574f493..0000000000 --- a/src/3rdParty/libE57Format/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# libE57Format - -[![Build Status](https://travis-ci.org/asmaloney/libE57Format.svg?branch=master)](https://travis-ci.org/asmaloney/libE57Format) - -A library to provide read & write support for the E57 file format. - -This is a fork of [E57RefImpl](https://sourceforge.net/projects/e57-3d-imgfmt/) v1.1.332. The original source is from [E57RefImpl 1.1.332](https://sourceforge.net/projects/e57-3d-imgfmt/files/E57Refimpl-src/) and then everything was stripped out except the main implementation for reading and writing E57. - -This version also removes the dependency on [Boost](https://www.boost.org/) and requires C++11. - -Many, many other changes were made prior to the first release of this fork. See the [CHANGELOG](CHANGELOG.md) and git history for details. - -## Documentation - -The doxygen-generated documentation may be [found here](https://asmaloney.github.io/libE57Format-docs/). These docs are generated and saved in the [libE57Format-docs](https://github.com/asmaloney/libE57Format-docs) repo. - -## Contributing - -Please see [CONTRIBUTING](CONTRIBUTING.md). - -## Why Fork? - -The E57RefImpl code hasn't been touched in years and I wanted to make changes to compile this library with macOS. Forking it gives me a bit more freedom to update the code and make changes as required. - -I changed the name of the project so that it is not confused with the **E57RefImpl** project. - -I have also changed the main include file's name from `E57Foundation.h` to `E57Format.h` to make sure there is no inclusion confusion. - -Versions of **libE57Format** started at 2.0. - -### E57Simple API - -Since the original fork, [Jiri Hörner](https://github.com/ptc-jhoerner) has added the E57Simple API from the old reference implementation and updated it. - -### Tools - -[Ryan Baumann](https://github.com/ryanfb) has updated the `e57unpack` and `e57validate` tools to work with **libE57Format**. You can find them in the [e57tools](https://github.com/ryanfb/e57tools) repo. - -## License - -This project as a whole is licensed under the [**BSL-1.0**](https://opensource.org/licenses/BSL-1.0) license - see the [LICENSE](LICENSE.md) file for details. - -Individual source files may contain the following tag instead of the full license text: - - SPDX-License-Identifier: BSL-1.0 - -Some CMake files are licensed under the **MIT** license - see the [LICENSE-MIT](LICENSE-MIT.txt) file for details. - -These files contain the following tag instead of the full license text: - - SPDX-License-Identifier: MIT - -Using SPDX enables machine processing of license information based on the [SPDX License Identifiers](https://spdx.org/ids) and makes it easier for developers to see at a glance which license they are dealing with. diff --git a/src/3rdParty/libE57Format/cmake/Modules/ClangFormat.cmake b/src/3rdParty/libE57Format/cmake/Modules/ClangFormat.cmake deleted file mode 100644 index 6e793ecf0b..0000000000 --- a/src/3rdParty/libE57Format/cmake/Modules/ClangFormat.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: MIT -# Copyright 2020 Andy Maloney - -find_program( E57_CLANG_FORMAT_EXE NAMES clang-format ) - -if ( E57_CLANG_FORMAT_EXE ) - get_target_property( e57_sources ${PROJECT_NAME} SOURCES ) - - # Remove some files from the list - list( FILTER e57_sources EXCLUDE REGEX ".*/E57Export.h" ) - list( FILTER e57_sources EXCLUDE REGEX ".*/extern/.*" ) - - add_custom_target( format - COMMAND clang-format --style=file -i ${e57_sources} - COMMENT "Running clang-format..." - COMMAND_EXPAND_LISTS - VERBATIM - ) -endif() diff --git a/src/3rdParty/libE57Format/cmake/Modules/E57ExportHeader.cmake b/src/3rdParty/libE57Format/cmake/Modules/E57ExportHeader.cmake deleted file mode 100644 index b9eaa6ca94..0000000000 --- a/src/3rdParty/libE57Format/cmake/Modules/E57ExportHeader.cmake +++ /dev/null @@ -1,38 +0,0 @@ -# SPDX-License-Identifier: MIT -# Copyright 2020 Andy Maloney - -# Generate the export header file for E57Format - -include( GenerateExportHeader ) - -set( comment "// NOTE: This is a generated file. Any changes will be overwritten." ) - -generate_export_header( E57Format - EXPORT_FILE_NAME E57Export.h - EXPORT_MACRO_NAME E57_DLL - CUSTOM_CONTENT_FROM_VARIABLE comment -) - -unset( comment ) - -target_sources( E57Format - PRIVATE - ${CMAKE_CURRENT_BINARY_DIR}/E57Export.h -) - -target_include_directories( ${PROJECT_NAME} - PUBLIC - $ -) - -target_compile_definitions( E57Format - PRIVATE - $<$:E57Format_EXPORTS> -) - -install( - FILES - ${CMAKE_CURRENT_BINARY_DIR}/E57Export.h - DESTINATION - include/E57Format -) diff --git a/src/3rdParty/libE57Format/cmake/Modules/Tags.cmake b/src/3rdParty/libE57Format/cmake/Modules/Tags.cmake deleted file mode 100644 index 421cc70b0f..0000000000 --- a/src/3rdParty/libE57Format/cmake/Modules/Tags.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# This file defines the variables -# ${PROJECT_NAME}_BUILD_TAG - -# calculate the tag -set(T_ ${CMAKE_SYSTEM_PROCESSOR}) -if (CMAKE_CL_64) - set(T_ ${T_}_64) -endif (CMAKE_CL_64) -string(TOLOWER ${CMAKE_SYSTEM_NAME} T1_) -set(T_ ${T_}-${T1_}) -if (MSVC90) - set(T1_ "-vc90") -elseif (MSVC10) - set(T1_ "-vc100") -elseif (MSVC80) - set(T1_ "-vc80") -elseif (MSVC71) - set(T1_ "-vc711") -elseif (MSVC70) - set(T1_ "-vc7") -elseif (MINGW) - set(T1_ "-mgw") - exec_program(${CMAKE_CXX_COMPILER} - ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion - OUTPUT_VARIABLE T2_ - ) - string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2" T2_ ${T2_}) - set(T1_ ${T1_}${T2_}) -elseif (CMAKE_COMPILER_IS_GNUCXX) - set(T1_ "-gcc") - exec_program(${CMAKE_CXX_COMPILER} - ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion - OUTPUT_VARIABLE T2_ - ) - string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2" T2_ ${T2_}) - set(T1_ ${T1_}${T2_}) -else() - set(T1_) -endif() -set(T_ ${T_}${T1_}) -set(${PROJECT_NAME}_BUILD_TAG ${T_}) diff --git a/src/3rdParty/libE57Format/cmake/e57format-config.cmake b/src/3rdParty/libE57Format/cmake/e57format-config.cmake deleted file mode 100644 index 1460f46c8e..0000000000 --- a/src/3rdParty/libE57Format/cmake/e57format-config.cmake +++ /dev/null @@ -1,9 +0,0 @@ -include(CMakeFindDependencyMacro) - -find_dependency(XercesC REQUIRED) -include(${CMAKE_CURRENT_LIST_DIR}/E57Format-export.cmake) - -set_target_properties(E57Format PROPERTIES - MAP_IMPORTED_CONFIG_MINSIZEREL "MinSizeRel;Release" - MAP_IMPORTED_CONFIG_RELWITHDEBINFO "RelWithDebInfo;Release" -) diff --git a/src/3rdParty/libE57Format/extern/CRCpp/CMakeLists.txt b/src/3rdParty/libE57Format/extern/CRCpp/CMakeLists.txt deleted file mode 100644 index a96a4e1cda..0000000000 --- a/src/3rdParty/libE57Format/extern/CRCpp/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: MIT -# Copyright © Andy Maloney - -# CRCpp from here: https://github.com/d-bahr/CRCpp - -target_sources( ${PROJECT_NAME} - PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/inc/CRC.h -) - -target_include_directories( ${PROJECT_NAME} - PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/inc -) diff --git a/src/3rdParty/libE57Format/extern/CRCpp/LICENSE b/src/3rdParty/libE57Format/extern/CRCpp/LICENSE deleted file mode 100644 index 961d67f576..0000000000 --- a/src/3rdParty/libE57Format/extern/CRCpp/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -CRC++ -Copyright (c) 2016, Daniel Bahr -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. - -* Neither the name of CRC++ nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -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. diff --git a/src/3rdParty/libE57Format/extern/CRCpp/README.md b/src/3rdParty/libE57Format/extern/CRCpp/README.md deleted file mode 100644 index 6cde496e17..0000000000 --- a/src/3rdParty/libE57Format/extern/CRCpp/README.md +++ /dev/null @@ -1,154 +0,0 @@ -# CRC++ -Easy to use and fast C++ CRC library. - -Tired of writing CRC code over and over again? Don't want to include a dozen boost header files just for a little bit of functionality? CRC++ is a portable and extremely lightweight alternative that is incredibly simple, fast, and clean. - -### Features - -CRC++ supports bit-by-bit and byte-by-byte calculation of full and multipart CRCs. The algorithms used are highly optimized and can even be configured to be branchless (as always, be sure to profile your code to choose the most efficient option). CRC++ is a great option for embedded C++ projects with a need for efficiency. - -CRC++ consists of a single header file which can be included in any existing C++ application. No libraries, no boost, no mess, no fuss. - -Any CRC width is supported - even CRCs larger than 64 bits, provided there is an integer type large enough to contain it. Trying to compute a 57-bit CRC? Got you covered. - -Many common CRCs are provided out-of-the-box, such as CRC-32 (used in PKZip and Ethernet), CRC-XMODEM, and CRC-CCITT. - -CRC++ will compile with any reasonably compliant C++03 or C++11 compiler. Compiling with C++11 is recommended, as it allows a number of static computations to be performed at compile-time instead of runtime. - -All of the CRC++ code is well-documented. Unit tests are included in the repository (g++ Makefile and Visual Studio 2015 projects included). HTML documentation can also be produced via Doxygen (also included in the repository). - -### Comparison - -CRC++ boasts one of the fastest and most memory efficient generic CRC implementation available. The below table shows performance comparisons across multiple implementations and platforms. - -| Library | Speed, x64 platform (100 million iterations) | Speed, x86 platform (100 million iterations) | -| ------------- | -------------------------------------------- | -------------------------------------------- | -| CRC++ | 2050 milliseconds | 2200 milliseconds | -| boost | 2250 milliseconds | 2000 milliseconds | -| pycrc | 2050 milliseconds | 2240 milliseconds | -| mhash | 2250 milliseconds | 2400 milliseconds | - -Additionally, CRC++ has the most features of any library and the smallest code footprint: - -| Library | Number of include files | Header-only implemen-tation | Supports byte != 8 bits | Supports arbitrary CRC width | Custom type support | C++11 support | 40+ built-in CRC definitions | Branchless implemen-tation | -| ------------- | ----------------------- | --------------------------- | ----------------------- | ---------------------------- | ------------------- | ------------- | ---------------------------- | -------------------------- | -| CRC++ | 1 | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -| boost | 17 | Yes | Yes | Yes | Yes | Yes | No | No | -| pycrc | 2 per CRC algorithm | No | No | No | No | No | No | No | -| mhash | 6 | No | Yes | No | No | No | No | No | - -### Usage - -Computing a CRC is as simple as the following code: - -```cpp -#include "CRC.h" // Only need to include this header file! - // No libraries need to be included. No project settings need to be messed with. - -#include // Includes ::std::hex -#include // Includes ::std::cout -#include // Includes ::std::uint32_t - -int main(int argc, char ** argv) -{ - const char myString[] = { 'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D' }; - - std::uint32_t crc = CRC::Calculate(myString, sizeof(myString), CRC::CRC_32()); - - std::cout << std::hex << crc; - - return 0; -} -``` - -Multi-part CRCs are also supported: - -```cpp -int main(int argc, char ** argv) -{ - const char myHelloString[] = { 'H', 'E', 'L', 'L', 'O', ' ' }; - const char myWorldString[] = { 'W', 'O', 'R', 'L', 'D' }; - - std::uint32_t crc; - - crc = CRC::Calculate(myHelloString, sizeof(myHelloString), CRC::CRC_32()); - crc = CRC::Calculate(myWorldString, sizeof(myWorldString), CRC::CRC_32(), crc); - - std::cout << std::hex << crc; - - return 0; -} -``` - -This will return the same CRC as the first example. - -Both of the above examples compute a CRC bit-by-bit. However, CRC++ also supports lookup tables, as the following example demonstrates: - -```cpp -int main(int argc, char ** argv) -{ - const char myHelloString[] = { 'H', 'E', 'L', 'L', 'O', ' ' }; - const char myWorldString[] = { 'W', 'O', 'R', 'L', 'D' }; - - CRC::Table table(CRC::CRC_32()); - - std::uint32_t crc; - - crc = CRC::Calculate(myHelloString, sizeof(myHelloString), table); - crc = CRC::Calculate(myWorldString, sizeof(myWorldString), table, crc); - - std::cout << std::hex << crc; - - return 0; -} -``` - -Or, if you prefer using the `auto` keyword: - -```cpp -int main(int argc, char ** argv) -{ - const char myHelloString[] = { 'H', 'E', 'L', 'L', 'O', ' ' }; - const char myWorldString[] = { 'W', 'O', 'R', 'L', 'D' }; - - auto table = CRC::CRC_32().MakeTable(); - - std::uint32_t crc; - - crc = CRC::Calculate(myHelloString, sizeof(myHelloString), table); - crc = CRC::Calculate(myWorldString, sizeof(myWorldString), table, crc); - - std::cout << std::hex << crc; - - return 0; -} -``` - -Lookup tables are much faster than computing a CRC bit-by-bit, at the expense of extra memory usage. A lookup table can be reused for as many CRCs as desired until it goes out of scope. - -### Configuration - -CRC++ can be configured by setting various `#define`s before `#include`-ing the CRC++ header file: - -* `#define crcpp_uint8`
-Specifies the type used to store CRCs that have a width of 8 bits or less. This type is not used in CRC calculations. Defaults to ::std::uint8_t. -* `#define crcpp_uint16`
-Specifies the type used to store CRCs that have a width between 9 and 16 bits (inclusive). This type is not used in CRC calculations. Defaults to ::std::uint16_t. -* `#define crcpp_uint32`
-Specifies the type used to store CRCs that have a width between 17 and 32 bits (inclusive). This type is not used in CRC calculations. Defaults to ::std::uint32_t. -* `#define crcpp_uint64`
-Specifies the type used to store CRCs that have a width between 33 and 64 bits (inclusive). This type is not used in CRC calculations. Defaults to ::std::uint64_t. -* `#define crcpp_size`
-This type is used for loop iteration and function signatures only. Defaults to ::std::size_t. -* `#define CRCPP_USE_NAMESPACE`
-Define to place all CRC++ code within the ::CRCPP namespace. Not defined by default. -* `#define CRCPP_BRANCHLESS`
-Define to enable a branchless CRC implementation. The branchless implementation uses a single integer multiplication in the bit-by-bit calculation instead of a small conditional. The branchless implementation may be faster on processor architectures which support single-instruction integer multiplication. Not defined by default. -* `#define CRCPP_USE_CPP11` -Define to enables C++11 features (move semantics, constexpr, static_assert, etc.). Not defined by default. -* `#define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS` -Define to include definitions for little-used CRCs. Not defined by default. - -### License - -CRC++ is free to use and provided under a BSD license. diff --git a/src/3rdParty/libE57Format/extern/CRCpp/inc/CRC.h b/src/3rdParty/libE57Format/extern/CRCpp/inc/CRC.h deleted file mode 100644 index 1c41b29556..0000000000 --- a/src/3rdParty/libE57Format/extern/CRCpp/inc/CRC.h +++ /dev/null @@ -1,1703 +0,0 @@ -/** - @file CRC.h - @author Daniel Bahr - @version 0.2.0.6 - @copyright - @parblock - CRC++ - Copyright (c) 2016, Daniel Bahr - 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. - - * Neither the name of CRC++ nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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. - @endparblock -*/ - -/* - CRC++ can be configured by setting various #defines before #including this header file: - - #define crcpp_uint8 - Specifies the type used to store CRCs that have a width of 8 bits or less. - This type is not used in CRC calculations. Defaults to ::std::uint8_t. - #define crcpp_uint16 - Specifies the type used to store CRCs that have a width between 9 and 16 bits (inclusive). - This type is not used in CRC calculations. Defaults to ::std::uint16_t. - #define crcpp_uint32 - Specifies the type used to store CRCs that have a width between 17 and 32 bits (inclusive). - This type is not used in CRC calculations. Defaults to ::std::uint32_t. - #define crcpp_uint64 - Specifies the type used to store CRCs that have a width between 33 and 64 bits (inclusive). - This type is not used in CRC calculations. Defaults to ::std::uint64_t. - #define crcpp_size - This type is used for loop iteration and function signatures only. Defaults to ::std::size_t. - #define CRCPP_USE_NAMESPACE - Define to place all CRC++ code within the ::CRCPP namespace. - #define CRCPP_BRANCHLESS - Define to enable a branchless CRC implementation. The branchless implementation uses a single integer - multiplication in the bit-by-bit calculation instead of a small conditional. The branchless implementation - may be faster on processor architectures which support single-instruction integer multiplication. - #define CRCPP_USE_CPP11 - Define to enables C++11 features (move semantics, constexpr, static_assert, etc.). - #define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - Define to include definitions for little-used CRCs. -*/ - -#ifndef CRCPP_CRC_H_ -#define CRCPP_CRC_H_ - -#include // Includes CHAR_BIT -#ifdef CRCPP_USE_CPP11 -#include // Includes ::std::size_t -#include // Includes ::std::uint8_t, ::std::uint16_t, ::std::uint32_t, ::std::uint64_t -#else -#include // Includes size_t -#include // Includes uint8_t, uint16_t, uint32_t, uint64_t -#endif -#include // Includes ::std::numeric_limits -#include // Includes ::std::move - -#ifndef crcpp_uint8 -# ifdef CRCPP_USE_CPP11 - /// @brief Unsigned 8-bit integer definition, used primarily for parameter definitions. -# define crcpp_uint8 ::std::uint8_t -# else - /// @brief Unsigned 8-bit integer definition, used primarily for parameter definitions. -# define crcpp_uint8 uint8_t -# endif -#endif - -#ifndef crcpp_uint16 -# ifdef CRCPP_USE_CPP11 - /// @brief Unsigned 16-bit integer definition, used primarily for parameter definitions. -# define crcpp_uint16 ::std::uint16_t -# else - /// @brief Unsigned 16-bit integer definition, used primarily for parameter definitions. -# define crcpp_uint16 uint16_t -# endif -#endif - -#ifndef crcpp_uint32 -# ifdef CRCPP_USE_CPP11 - /// @brief Unsigned 32-bit integer definition, used primarily for parameter definitions. -# define crcpp_uint32 ::std::uint32_t -# else - /// @brief Unsigned 32-bit integer definition, used primarily for parameter definitions. -# define crcpp_uint32 uint32_t -# endif -#endif - -#ifndef crcpp_uint64 -# ifdef CRCPP_USE_CPP11 - /// @brief Unsigned 64-bit integer definition, used primarily for parameter definitions. -# define crcpp_uint64 ::std::uint64_t -# else - /// @brief Unsigned 64-bit integer definition, used primarily for parameter definitions. -# define crcpp_uint64 uint64_t -# endif -#endif - -#ifndef crcpp_size -# ifdef CRCPP_USE_CPP11 - /// @brief Unsigned size definition, used for specifying data sizes. -# define crcpp_size ::std::size_t -# else - /// @brief Unsigned size definition, used for specifying data sizes. -# define crcpp_size size_t -# endif -#endif - -#ifdef CRCPP_USE_CPP11 - /// @brief Compile-time expression definition. -# define crcpp_constexpr constexpr -#else - /// @brief Compile-time expression definition. -# define crcpp_constexpr const -#endif - -#ifdef CRCPP_USE_NAMESPACE -namespace CRCPP -{ -#endif - -/** - @brief Static class for computing CRCs. - @note This class supports computation of full and multi-part CRCs, using a bit-by-bit algorithm or a - byte-by-byte lookup table. The CRCs are calculated using as many optimizations as is reasonable. - If compiling with C++11, the constexpr keyword is used liberally so that many calculations are - performed at compile-time instead of at runtime. -*/ -class CRC -{ -public: - // Forward declaration - template - struct Table; - - /** - @brief CRC parameters. - */ - template - struct Parameters - { - CRCType polynomial; ///< CRC polynomial - CRCType initialValue; ///< Initial CRC value - CRCType finalXOR; ///< Value to XOR with the final CRC - bool reflectInput; ///< true to reflect all input bytes - bool reflectOutput; ///< true to reflect the output CRC (reflection occurs before the final XOR) - - Table MakeTable() const; - }; - - /** - @brief CRC lookup table. After construction, the CRC parameters are fixed. - @note A CRC table can be used for multiple CRC calculations. - */ - template - struct Table - { - // Constructors are intentionally NOT marked explicit. - Table(const Parameters & parameters); - -#ifdef CRCPP_USE_CPP11 - Table(Parameters && parameters); -#endif - - const Parameters & GetParameters() const; - - const CRCType * GetTable() const; - - CRCType operator[](unsigned char index) const; - - private: - void InitTable(); - - Parameters parameters; ///< CRC parameters used to construct the table - CRCType table[1 << CHAR_BIT]; ///< CRC lookup table - }; - - // The number of bits in CRCType must be at least as large as CRCWidth. - // CRCType must be an unsigned integer type or a custom type with operator overloads. - template - static CRCType Calculate(const void * data, crcpp_size size, const Parameters & parameters); - - template - static CRCType Calculate(const void * data, crcpp_size size, const Parameters & parameters, CRCType crc); - - template - static CRCType Calculate(const void * data, crcpp_size size, const Table & lookupTable); - - template - static CRCType Calculate(const void * data, crcpp_size size, const Table & lookupTable, CRCType crc); - - // Common CRCs up to 64 bits. - // Note: Check values are the computed CRCs when given an ASCII input of "123456789" (without null terminator) -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - static const Parameters< crcpp_uint8, 4> & CRC_4_ITU(); - static const Parameters< crcpp_uint8, 5> & CRC_5_EPC(); - static const Parameters< crcpp_uint8, 5> & CRC_5_ITU(); - static const Parameters< crcpp_uint8, 5> & CRC_5_USB(); - static const Parameters< crcpp_uint8, 6> & CRC_6_CDMA2000A(); - static const Parameters< crcpp_uint8, 6> & CRC_6_CDMA2000B(); - static const Parameters< crcpp_uint8, 6> & CRC_6_ITU(); - static const Parameters< crcpp_uint8, 7> & CRC_7(); -#endif - static const Parameters< crcpp_uint8, 8> & CRC_8(); -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - static const Parameters< crcpp_uint8, 8> & CRC_8_EBU(); - static const Parameters< crcpp_uint8, 8> & CRC_8_MAXIM(); - static const Parameters< crcpp_uint8, 8> & CRC_8_WCDMA(); - static const Parameters & CRC_10(); - static const Parameters & CRC_10_CDMA2000(); - static const Parameters & CRC_11(); - static const Parameters & CRC_12_CDMA2000(); - static const Parameters & CRC_12_DECT(); - static const Parameters & CRC_12_UMTS(); - static const Parameters & CRC_13_BBC(); - static const Parameters & CRC_15(); - static const Parameters & CRC_15_MPT1327(); -#endif - static const Parameters & CRC_16_ARC(); - static const Parameters & CRC_16_BUYPASS(); - static const Parameters & CRC_16_CCITTFALSE(); -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - static const Parameters & CRC_16_CDMA2000(); - static const Parameters & CRC_16_DECTR(); - static const Parameters & CRC_16_DECTX(); - static const Parameters & CRC_16_DNP(); -#endif - static const Parameters & CRC_16_GENIBUS(); - static const Parameters & CRC_16_KERMIT(); -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - static const Parameters & CRC_16_MAXIM(); - static const Parameters & CRC_16_MODBUS(); - static const Parameters & CRC_16_T10DIF(); - static const Parameters & CRC_16_USB(); -#endif - static const Parameters & CRC_16_X25(); - static const Parameters & CRC_16_XMODEM(); -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - static const Parameters & CRC_17_CAN(); - static const Parameters & CRC_21_CAN(); - static const Parameters & CRC_24(); - static const Parameters & CRC_24_FLEXRAYA(); - static const Parameters & CRC_24_FLEXRAYB(); - static const Parameters & CRC_30(); -#endif - static const Parameters & CRC_32(); - static const Parameters & CRC_32_BZIP2(); -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - static const Parameters & CRC_32_C(); -#endif - static const Parameters & CRC_32_MPEG2(); - static const Parameters & CRC_32_POSIX(); -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - static const Parameters & CRC_32_Q(); - static const Parameters & CRC_40_GSM(); - static const Parameters & CRC_64(); -#endif - -#ifdef CRCPP_USE_CPP11 - CRC() = delete; - CRC(const CRC & other) = delete; - CRC & operator=(const CRC & other) = delete; - CRC(CRC && other) = delete; - CRC & operator=(CRC && other) = delete; -#endif - -private: -#ifndef CRCPP_USE_CPP11 - CRC(); - CRC(const CRC & other); - CRC & operator=(const CRC & other); -#endif - - template - static IntegerType Reflect(IntegerType value, crcpp_uint16 numBits); - - template - static CRCType Finalize(CRCType remainder, CRCType finalXOR, bool reflectOutput); - - template - static CRCType UndoFinalize(CRCType remainder, CRCType finalXOR, bool reflectOutput); - - template - static CRCType CalculateRemainder(const void * data, crcpp_size size, const Parameters & parameters, CRCType remainder); - - template - static CRCType CalculateRemainder(const void * data, crcpp_size size, const Table & lookupTable, CRCType remainder); - - template - static crcpp_constexpr IntegerType BoundedConstexprValue(IntegerType x); -}; - -/** - @brief Returns a CRC lookup table construct using these CRC parameters. - @note This function primarily exists to allow use of the auto keyword instead of instantiating - a table directly, since template parameters are not inferred in constructors. - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return CRC lookup table -*/ -template -inline CRC::Table CRC::Parameters::MakeTable() const -{ - // This should take advantage of RVO and optimize out the copy. - return CRC::Table(*this); -} - -/** - @brief Constructs a CRC table from a set of CRC parameters - @param[in] parameters CRC parameters - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC -*/ -template -inline CRC::Table::Table(const Parameters & parameters) : - parameters(parameters) -{ - InitTable(); -} - -#ifdef CRCPP_USE_CPP11 -/** - @brief Constructs a CRC table from a set of CRC parameters - @param[in] parameters CRC parameters - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC -*/ -template -inline CRC::Table::Table(Parameters && parameters) : - parameters(::std::move(parameters)) -{ - InitTable(); -} -#endif - -/** - @brief Gets the CRC parameters used to construct the CRC table - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return CRC parameters -*/ -template -inline const CRC::Parameters & CRC::Table::GetParameters() const -{ - return parameters; -} - -/** - @brief Gets the CRC table - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return CRC table -*/ -template -inline const CRCType * CRC::Table::GetTable() const -{ - return table; -} - -/** - @brief Gets an entry in the CRC table - @param[in] index Index into the CRC table - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return CRC table entry -*/ -template -inline CRCType CRC::Table::operator[](unsigned char index) const -{ - return table[index]; -} - -/** - @brief Initializes a CRC table. - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC -*/ -template -inline void CRC::Table::InitTable() -{ - // For masking off the bits for the CRC (in the event that the number of bits in CRCType is larger than CRCWidth) - static crcpp_constexpr CRCType BIT_MASK((CRCType(1) << (CRCWidth - CRCType(1))) | - ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1))); - - static crcpp_constexpr CRCType SHIFT(CRC::BoundedConstexprValue(CHAR_BIT - CRCWidth)); - - CRCType crc; - unsigned char byte = 0; - - // Loop over each dividend (each possible number storable in an unsigned char) - do - { - crc = CRC::CalculateRemainder(&byte, sizeof(byte), parameters, CRCType(0)); - - // This mask might not be necessary; all unit tests pass with this line commented out, - // but that might just be a coincidence based on the CRC parameters used for testing. - // In any case, this is harmless to leave in and only adds a single machine instruction per loop iteration. - crc &= BIT_MASK; - - if (!parameters.reflectInput && CRCWidth < CHAR_BIT) - { - // Undo the special operation at the end of the CalculateRemainder() - // function for non-reflected CRCs < CHAR_BIT. - crc <<= SHIFT; - } - - table[byte] = crc; - } - while (++byte); -} - -/** - @brief Computes a CRC. - @param[in] data Data over which CRC will be computed - @param[in] size Size of the data - @param[in] parameters CRC parameters - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return CRC -*/ -template -inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Parameters & parameters) -{ - CRCType remainder = CalculateRemainder(data, size, parameters, parameters.initialValue); - - // No need to mask the remainder here; the mask will be applied in the Finalize() function. - - return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); -} -/** - @brief Appends additional data to a previous CRC calculation. - @note This function can be used to compute multi-part CRCs. - @param[in] data Data over which CRC will be computed - @param[in] size Size of the data - @param[in] parameters CRC parameters - @param[in] crc CRC from a previous calculation - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return CRC -*/ -template -inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Parameters & parameters, CRCType crc) -{ - CRCType remainder = UndoFinalize(crc, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); - - remainder = CalculateRemainder(data, size, parameters, remainder); - - // No need to mask the remainder here; the mask will be applied in the Finalize() function. - - return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); -} - -/** - @brief Computes a CRC via a lookup table. - @param[in] data Data over which CRC will be computed - @param[in] size Size of the data - @param[in] lookupTable CRC lookup table - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return CRC -*/ -template -inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Table & lookupTable) -{ - const Parameters & parameters = lookupTable.GetParameters(); - - CRCType remainder = CalculateRemainder(data, size, lookupTable, parameters.initialValue); - - // No need to mask the remainder here; the mask will be applied in the Finalize() function. - - return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); -} - -/** - @brief Appends additional data to a previous CRC calculation using a lookup table. - @note This function can be used to compute multi-part CRCs. - @param[in] data Data over which CRC will be computed - @param[in] size Size of the data - @param[in] lookupTable CRC lookup table - @param[in] crc CRC from a previous calculation - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return CRC -*/ -template -inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Table & lookupTable, CRCType crc) -{ - const Parameters & parameters = lookupTable.GetParameters(); - - CRCType remainder = UndoFinalize(crc, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); - - remainder = CalculateRemainder(data, size, lookupTable, remainder); - - // No need to mask the remainder here; the mask will be applied in the Finalize() function. - - return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); -} - -/** - @brief Reflects (i.e. reverses the bits within) an integer value. - @param[in] value Value to reflect - @param[in] numBits Number of bits in the integer which will be reflected - @tparam IntegerType Integer type of the value being reflected - @return Reflected value -*/ -template -inline IntegerType CRC::Reflect(IntegerType value, crcpp_uint16 numBits) -{ - IntegerType reversedValue(0); - - for (crcpp_uint16 i = 0; i < numBits; ++i) - { - reversedValue = (reversedValue << 1) | (value & 1); - value >>= 1; - } - - return reversedValue; -} - -/** - @brief Computes the final reflection and XOR of a CRC remainder. - @param[in] remainder CRC remainder to reflect and XOR - @param[in] finalXOR Final value to XOR with the remainder - @param[in] reflectOutput true to reflect each byte of the remainder before the XOR - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return Final CRC -*/ -template -inline CRCType CRC::Finalize(CRCType remainder, CRCType finalXOR, bool reflectOutput) -{ - // For masking off the bits for the CRC (in the event that the number of bits in CRCType is larger than CRCWidth) - static crcpp_constexpr CRCType BIT_MASK = (CRCType(1) << (CRCWidth - CRCType(1))) | - ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1)); - - if (reflectOutput) - { - remainder = Reflect(remainder, CRCWidth); - } - - return (remainder ^ finalXOR) & BIT_MASK; -} - -/** - @brief Undoes the process of computing the final reflection and XOR of a CRC remainder. - @note This function allows for computation of multi-part CRCs - @note Calling UndoFinalize() followed by Finalize() (or vice versa) will always return the original remainder value: - - CRCType x = ...; - CRCType y = Finalize(x, finalXOR, reflectOutput); - CRCType z = UndoFinalize(y, finalXOR, reflectOutput); - assert(x == z); - - @param[in] crc Reflected and XORed CRC - @param[in] finalXOR Final value XORed with the remainder - @param[in] reflectOutput true if the remainder is to be reflected - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return Un-finalized CRC remainder -*/ -template -inline CRCType CRC::UndoFinalize(CRCType crc, CRCType finalXOR, bool reflectOutput) -{ - // For masking off the bits for the CRC (in the event that the number of bits in CRCType is larger than CRCWidth) - static crcpp_constexpr CRCType BIT_MASK = (CRCType(1) << (CRCWidth - CRCType(1))) | - ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1)); - - crc = (crc & BIT_MASK) ^ finalXOR; - - if (reflectOutput) - { - crc = Reflect(crc, CRCWidth); - } - - return crc; -} - -/** - @brief Computes a CRC remainder. - @param[in] data Data over which the remainder will be computed - @param[in] size Size of the data - @param[in] parameters CRC parameters - @param[in] remainder Running CRC remainder. Can be an initial value or the result of a previous CRC remainder calculation. - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return CRC remainder -*/ -template -inline CRCType CRC::CalculateRemainder(const void * data, crcpp_size size, const Parameters & parameters, CRCType remainder) -{ -#ifdef CRCPP_USE_CPP11 - // This static_assert is put here because this function will always be compiled in no matter what - // the template parameters are and whether or not a table lookup or bit-by-bit algorithm is used. - static_assert(::std::numeric_limits::digits >= CRCWidth, "CRCType is too small to contain a CRC of width CRCWidth."); -#else - // Catching this compile-time error is very important. Sadly, the compiler error will be very cryptic, but it's - // better than nothing. - enum { static_assert_failed_CRCType_is_too_small_to_contain_a_CRC_of_width_CRCWidth = 1 / (::std::numeric_limits::digits >= CRCWidth ? 1 : 0) }; -#endif - - const unsigned char * current = reinterpret_cast(data); - - // Slightly different implementations based on the parameters. The current implementations try to eliminate as much - // computation from the inner loop (looping over each bit) as possible. - if (parameters.reflectInput) - { - CRCType polynomial = CRC::Reflect(parameters.polynomial, CRCWidth); - while (size--) - { - remainder ^= *current++; - - // An optimizing compiler might choose to unroll this loop. - for (crcpp_size i = 0; i < CHAR_BIT; ++i) - { -#ifdef CRCPP_BRANCHLESS - // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: - // if (remainder & 1) - // remainder = (remainder >> 1) ^ polynomial; - // else - // remainder >>= 1; - remainder = (remainder >> 1) ^ ((remainder & 1) * polynomial); -#else - remainder = (remainder & 1) ? ((remainder >> 1) ^ polynomial) : (remainder >> 1); -#endif - } - } - } - else if (CRCWidth >= CHAR_BIT) - { - static crcpp_constexpr CRCType CRC_WIDTH_MINUS_ONE(CRCWidth - CRCType(1)); -#ifndef CRCPP_BRANCHLESS - static crcpp_constexpr CRCType CRC_HIGHEST_BIT_MASK(CRCType(1) << CRC_WIDTH_MINUS_ONE); -#endif - static crcpp_constexpr CRCType SHIFT(BoundedConstexprValue(CRCWidth - CHAR_BIT)); - - while (size--) - { - remainder ^= (static_cast(*current++) << SHIFT); - - // An optimizing compiler might choose to unroll this loop. - for (crcpp_size i = 0; i < CHAR_BIT; ++i) - { -#ifdef CRCPP_BRANCHLESS - // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: - // if (remainder & CRC_HIGHEST_BIT_MASK) - // remainder = (remainder << 1) ^ parameters.polynomial; - // else - // remainder <<= 1; - remainder = (remainder << 1) ^ (((remainder >> CRC_WIDTH_MINUS_ONE) & 1) * parameters.polynomial); -#else - remainder = (remainder & CRC_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ parameters.polynomial) : (remainder << 1); -#endif - } - } - } - else - { - static crcpp_constexpr CRCType CHAR_BIT_MINUS_ONE(CHAR_BIT - 1); -#ifndef CRCPP_BRANCHLESS - static crcpp_constexpr CRCType CHAR_BIT_HIGHEST_BIT_MASK(CRCType(1) << CHAR_BIT_MINUS_ONE); -#endif - static crcpp_constexpr CRCType SHIFT(BoundedConstexprValue(CHAR_BIT - CRCWidth)); - - CRCType polynomial = parameters.polynomial << SHIFT; - remainder <<= SHIFT; - - while (size--) - { - remainder ^= *current++; - - // An optimizing compiler might choose to unroll this loop. - for (crcpp_size i = 0; i < CHAR_BIT; ++i) - { -#ifdef CRCPP_BRANCHLESS - // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: - // if (remainder & CHAR_BIT_HIGHEST_BIT_MASK) - // remainder = (remainder << 1) ^ polynomial; - // else - // remainder <<= 1; - remainder = (remainder << 1) ^ (((remainder >> CHAR_BIT_MINUS_ONE) & 1) * polynomial); -#else - remainder = (remainder & CHAR_BIT_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ polynomial) : (remainder << 1); -#endif - } - } - - remainder >>= SHIFT; - } - - return remainder; -} - -/** - @brief Computes a CRC remainder using lookup table. - @param[in] data Data over which the remainder will be computed - @param[in] size Size of the data - @param[in] lookupTable CRC lookup table - @param[in] remainder Running CRC remainder. Can be an initial value or the result of a previous CRC remainder calculation. - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return CRC remainder -*/ -template -inline CRCType CRC::CalculateRemainder(const void * data, crcpp_size size, const Table & lookupTable, CRCType remainder) -{ - const unsigned char * current = reinterpret_cast(data); - - if (lookupTable.GetParameters().reflectInput) - { - while (size--) - { -#if defined(WIN32) || defined(_WIN32) || defined(WINCE) - // Disable warning about data loss when doing (remainder >> CHAR_BIT) when - // remainder is one byte long. The algorithm is still correct in this case, - // though it's possible that one additional machine instruction will be executed. -# if defined(_MSC_VER) -# pragma warning (push) -# pragma warning (disable : 4333) -# endif -#endif - remainder = (remainder >> CHAR_BIT) ^ lookupTable[static_cast(remainder ^ *current++)]; -#if defined(WIN32) || defined(_WIN32) || defined(WINCE) -# if defined(_MSC_VER) -# pragma warning (pop) -# endif -#endif - } - } - else if (CRCWidth >= CHAR_BIT) - { - static crcpp_constexpr CRCType SHIFT(BoundedConstexprValue(CRCWidth - CHAR_BIT)); - - while (size--) - { - remainder = (remainder << CHAR_BIT) ^ lookupTable[static_cast((remainder >> SHIFT) ^ *current++)]; - } - } - else - { - static crcpp_constexpr CRCType SHIFT(BoundedConstexprValue(CHAR_BIT - CRCWidth)); - - remainder <<= SHIFT; - - while (size--) - { - // Note: no need to mask here since remainder is guaranteed to fit in a single byte. - remainder = lookupTable[static_cast(remainder ^ *current++)]; - } - - remainder >>= SHIFT; - } - - return remainder; -} - -/** - @brief Function to force a compile-time expression to be >= 0. - @note This function is used to avoid compiler warnings because all constexpr values are evaluated - in a function even in a branch will never be executed. This also means we don't need pragmas - to get rid of warnings, but it still can be computed at compile-time. Win-win! - @param[in] x Compile-time expression to bound - @tparam CRCType Integer type for storing the CRC result - @tparam CRCWidth Number of bits in the CRC - @return Non-negative compile-time expression -*/ -template -inline crcpp_constexpr IntegerType CRC::BoundedConstexprValue(IntegerType x) -{ - return (x < IntegerType(0)) ? IntegerType(0) : x; -} - -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS -/** - @brief Returns a set of parameters for CRC-4 ITU. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-4 ITU has the following parameters and check value: - - polynomial = 0x3 - - initial value = 0x0 - - final XOR = 0x0 - - reflect input = true - - reflect output = true - - check value = 0x7 - @return CRC-4 ITU parameters -*/ -inline const CRC::Parameters & CRC::CRC_4_ITU() -{ - static const Parameters parameters = { 0x3, 0x0, 0x0, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-5 EPC. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-5 EPC has the following parameters and check value: - - polynomial = 0x09 - - initial value = 0x09 - - final XOR = 0x00 - - reflect input = false - - reflect output = false - - check value = 0x00 - @return CRC-5 EPC parameters -*/ -inline const CRC::Parameters & CRC::CRC_5_EPC() -{ - static const Parameters parameters = { 0x09, 0x09, 0x00, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-5 ITU. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-5 ITU has the following parameters and check value: - - polynomial = 0x15 - - initial value = 0x00 - - final XOR = 0x00 - - reflect input = true - - reflect output = true - - check value = 0x07 - @return CRC-5 ITU parameters -*/ -inline const CRC::Parameters & CRC::CRC_5_ITU() -{ - static const Parameters parameters = { 0x15, 0x00, 0x00, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-5 USB. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-5 USB has the following parameters and check value: - - polynomial = 0x05 - - initial value = 0x1F - - final XOR = 0x1F - - reflect input = true - - reflect output = true - - check value = 0x19 - @return CRC-5 USB parameters -*/ -inline const CRC::Parameters & CRC::CRC_5_USB() -{ - static const Parameters parameters = { 0x05, 0x1F, 0x1F, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-6 CDMA2000-A. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-6 CDMA2000-A has the following parameters and check value: - - polynomial = 0x27 - - initial value = 0x3F - - final XOR = 0x00 - - reflect input = false - - reflect output = false - - check value = 0x0D - @return CRC-6 CDMA2000-A parameters -*/ -inline const CRC::Parameters & CRC::CRC_6_CDMA2000A() -{ - static const Parameters parameters = { 0x27, 0x3F, 0x00, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-6 CDMA2000-B. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-6 CDMA2000-A has the following parameters and check value: - - polynomial = 0x07 - - initial value = 0x3F - - final XOR = 0x00 - - reflect input = false - - reflect output = false - - check value = 0x3B - @return CRC-6 CDMA2000-B parameters -*/ -inline const CRC::Parameters & CRC::CRC_6_CDMA2000B() -{ - static const Parameters parameters = { 0x07, 0x3F, 0x00, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-6 ITU. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-6 ITU has the following parameters and check value: - - polynomial = 0x03 - - initial value = 0x00 - - final XOR = 0x00 - - reflect input = true - - reflect output = true - - check value = 0x06 - @return CRC-6 ITU parameters -*/ -inline const CRC::Parameters & CRC::CRC_6_ITU() -{ - static const Parameters parameters = { 0x03, 0x00, 0x00, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-7 JEDEC. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-7 JEDEC has the following parameters and check value: - - polynomial = 0x09 - - initial value = 0x00 - - final XOR = 0x00 - - reflect input = false - - reflect output = false - - check value = 0x75 - @return CRC-7 JEDEC parameters -*/ -inline const CRC::Parameters & CRC::CRC_7() -{ - static const Parameters parameters = { 0x09, 0x00, 0x00, false, false }; - return parameters; -} -#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - -/** - @brief Returns a set of parameters for CRC-8 SMBus. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-8 SMBus has the following parameters and check value: - - polynomial = 0x07 - - initial value = 0x00 - - final XOR = 0x00 - - reflect input = false - - reflect output = false - - check value = 0xF4 - @return CRC-8 SMBus parameters -*/ -inline const CRC::Parameters & CRC::CRC_8() -{ - static const Parameters parameters = { 0x07, 0x00, 0x00, false, false }; - return parameters; -} - -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS -/** - @brief Returns a set of parameters for CRC-8 EBU (aka CRC-8 AES). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-8 EBU has the following parameters and check value: - - polynomial = 0x1D - - initial value = 0xFF - - final XOR = 0x00 - - reflect input = true - - reflect output = true - - check value = 0x97 - @return CRC-8 EBU parameters -*/ -inline const CRC::Parameters & CRC::CRC_8_EBU() -{ - static const Parameters parameters = { 0x1D, 0xFF, 0x00, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-8 MAXIM (aka CRC-8 DOW-CRC). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-8 MAXIM has the following parameters and check value: - - polynomial = 0x31 - - initial value = 0x00 - - final XOR = 0x00 - - reflect input = true - - reflect output = true - - check value = 0xA1 - @return CRC-8 MAXIM parameters -*/ -inline const CRC::Parameters & CRC::CRC_8_MAXIM() -{ - static const Parameters parameters = { 0x31, 0x00, 0x00, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-8 WCDMA. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-8 WCDMA has the following parameters and check value: - - polynomial = 0x9B - - initial value = 0x00 - - final XOR = 0x00 - - reflect input = true - - reflect output = true - - check value = 0x25 - @return CRC-8 WCDMA parameters -*/ -inline const CRC::Parameters & CRC::CRC_8_WCDMA() -{ - static const Parameters parameters = { 0x9B, 0x00, 0x00, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-10 ITU. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-10 ITU has the following parameters and check value: - - polynomial = 0x233 - - initial value = 0x000 - - final XOR = 0x000 - - reflect input = false - - reflect output = false - - check value = 0x199 - @return CRC-10 ITU parameters -*/ -inline const CRC::Parameters & CRC::CRC_10() -{ - static const Parameters parameters = { 0x233, 0x000, 0x000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-10 CDMA2000. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-10 CDMA2000 has the following parameters and check value: - - polynomial = 0x3D9 - - initial value = 0x3FF - - final XOR = 0x000 - - reflect input = false - - reflect output = false - - check value = 0x233 - @return CRC-10 CDMA2000 parameters -*/ -inline const CRC::Parameters & CRC::CRC_10_CDMA2000() -{ - static const Parameters parameters = { 0x3D9, 0x3FF, 0x000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-11 FlexRay. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-11 FlexRay has the following parameters and check value: - - polynomial = 0x385 - - initial value = 0x01A - - final XOR = 0x000 - - reflect input = false - - reflect output = false - - check value = 0x5A3 - @return CRC-11 FlexRay parameters -*/ -inline const CRC::Parameters & CRC::CRC_11() -{ - static const Parameters parameters = { 0x385, 0x01A, 0x000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-12 CDMA2000. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-12 CDMA2000 has the following parameters and check value: - - polynomial = 0xF13 - - initial value = 0xFFF - - final XOR = 0x000 - - reflect input = false - - reflect output = false - - check value = 0xD4D - @return CRC-12 CDMA2000 parameters -*/ -inline const CRC::Parameters & CRC::CRC_12_CDMA2000() -{ - static const Parameters parameters = { 0xF13, 0xFFF, 0x000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-12 DECT (aka CRC-12 X-CRC). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-12 DECT has the following parameters and check value: - - polynomial = 0x80F - - initial value = 0x000 - - final XOR = 0x000 - - reflect input = false - - reflect output = false - - check value = 0xF5B - @return CRC-12 DECT parameters -*/ -inline const CRC::Parameters & CRC::CRC_12_DECT() -{ - static const Parameters parameters = { 0x80F, 0x000, 0x000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-12 UMTS (aka CRC-12 3GPP). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-12 UMTS has the following parameters and check value: - - polynomial = 0x80F - - initial value = 0x000 - - final XOR = 0x000 - - reflect input = false - - reflect output = true - - check value = 0xDAF - @return CRC-12 UMTS parameters -*/ -inline const CRC::Parameters & CRC::CRC_12_UMTS() -{ - static const Parameters parameters = { 0x80F, 0x000, 0x000, false, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-13 BBC. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-13 BBC has the following parameters and check value: - - polynomial = 0x1CF5 - - initial value = 0x0000 - - final XOR = 0x0000 - - reflect input = false - - reflect output = false - - check value = 0x04FA - @return CRC-13 BBC parameters -*/ -inline const CRC::Parameters & CRC::CRC_13_BBC() -{ - static const Parameters parameters = { 0x1CF5, 0x0000, 0x0000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-15 CAN. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-15 CAN has the following parameters and check value: - - polynomial = 0x4599 - - initial value = 0x0000 - - final XOR = 0x0000 - - reflect input = false - - reflect output = false - - check value = 0x059E - @return CRC-15 CAN parameters -*/ -inline const CRC::Parameters & CRC::CRC_15() -{ - static const Parameters parameters = { 0x4599, 0x0000, 0x0000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-15 MPT1327. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-15 MPT1327 has the following parameters and check value: - - polynomial = 0x6815 - - initial value = 0x0000 - - final XOR = 0x0001 - - reflect input = false - - reflect output = false - - check value = 0x2566 - @return CRC-15 MPT1327 parameters -*/ -inline const CRC::Parameters & CRC::CRC_15_MPT1327() -{ - static const Parameters parameters = { 0x6815, 0x0000, 0x0001, false, false }; - return parameters; -} -#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - -/** - @brief Returns a set of parameters for CRC-16 ARC (aka CRC-16 IBM, CRC-16 LHA). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 ARC has the following parameters and check value: - - polynomial = 0x8005 - - initial value = 0x0000 - - final XOR = 0x0000 - - reflect input = true - - reflect output = true - - check value = 0xBB3D - @return CRC-16 ARC parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_ARC() -{ - static const Parameters parameters = { 0x8005, 0x0000, 0x0000, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-16 BUYPASS (aka CRC-16 VERIFONE, CRC-16 UMTS). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 BUYPASS has the following parameters and check value: - - polynomial = 0x8005 - - initial value = 0x0000 - - final XOR = 0x0000 - - reflect input = false - - reflect output = false - - check value = 0xFEE8 - @return CRC-16 BUYPASS parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_BUYPASS() -{ - static const Parameters parameters = { 0x8005, 0x0000, 0x0000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-16 CCITT FALSE. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 CCITT FALSE has the following parameters and check value: - - polynomial = 0x1021 - - initial value = 0xFFFF - - final XOR = 0x0000 - - reflect input = false - - reflect output = false - - check value = 0x29B1 - @return CRC-16 CCITT FALSE parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_CCITTFALSE() -{ - static const Parameters parameters = { 0x1021, 0xFFFF, 0x0000, false, false }; - return parameters; -} - -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS -/** - @brief Returns a set of parameters for CRC-16 CDMA2000. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 CDMA2000 has the following parameters and check value: - - polynomial = 0xC867 - - initial value = 0xFFFF - - final XOR = 0x0000 - - reflect input = false - - reflect output = false - - check value = 0x4C06 - @return CRC-16 CDMA2000 parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_CDMA2000() -{ - static const Parameters parameters = { 0xC867, 0xFFFF, 0x0000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-16 DECT-R (aka CRC-16 R-CRC). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 DECT-R has the following parameters and check value: - - polynomial = 0x0589 - - initial value = 0x0000 - - final XOR = 0x0001 - - reflect input = false - - reflect output = false - - check value = 0x007E - @return CRC-16 DECT-R parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_DECTR() -{ - static const Parameters parameters = { 0x0589, 0x0000, 0x0001, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-16 DECT-X (aka CRC-16 X-CRC). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 DECT-X has the following parameters and check value: - - polynomial = 0x0589 - - initial value = 0x0000 - - final XOR = 0x0000 - - reflect input = false - - reflect output = false - - check value = 0x007F - @return CRC-16 DECT-X parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_DECTX() -{ - static const Parameters parameters = { 0x0589, 0x0000, 0x0000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-16 DNP. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 DNP has the following parameters and check value: - - polynomial = 0x3D65 - - initial value = 0x0000 - - final XOR = 0xFFFF - - reflect input = true - - reflect output = true - - check value = 0xEA82 - @return CRC-16 DNP parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_DNP() -{ - static const Parameters parameters = { 0x3D65, 0x0000, 0xFFFF, true, true }; - return parameters; -} -#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - -/** - @brief Returns a set of parameters for CRC-16 GENIBUS (aka CRC-16 EPC, CRC-16 I-CODE, CRC-16 DARC). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 GENIBUS has the following parameters and check value: - - polynomial = 0x1021 - - initial value = 0xFFFF - - final XOR = 0xFFFF - - reflect input = false - - reflect output = false - - check value = 0xD64E - @return CRC-16 GENIBUS parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_GENIBUS() -{ - static const Parameters parameters = { 0x1021, 0xFFFF, 0xFFFF, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-16 KERMIT (aka CRC-16 CCITT, CRC-16 CCITT-TRUE). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 KERMIT has the following parameters and check value: - - polynomial = 0x1021 - - initial value = 0x0000 - - final XOR = 0x0000 - - reflect input = true - - reflect output = true - - check value = 0x2189 - @return CRC-16 KERMIT parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_KERMIT() -{ - static const Parameters parameters = { 0x1021, 0x0000, 0x0000, true, true }; - return parameters; -} - -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS -/** - @brief Returns a set of parameters for CRC-16 MAXIM. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 MAXIM has the following parameters and check value: - - polynomial = 0x8005 - - initial value = 0x0000 - - final XOR = 0xFFFF - - reflect input = true - - reflect output = true - - check value = 0x44C2 - @return CRC-16 MAXIM parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_MAXIM() -{ - static const Parameters parameters = { 0x8005, 0x0000, 0xFFFF, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-16 MODBUS. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 MODBUS has the following parameters and check value: - - polynomial = 0x8005 - - initial value = 0xFFFF - - final XOR = 0x0000 - - reflect input = true - - reflect output = true - - check value = 0x4B37 - @return CRC-16 MODBUS parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_MODBUS() -{ - static const Parameters parameters = { 0x8005, 0xFFFF, 0x0000, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-16 T10-DIF. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 T10-DIF has the following parameters and check value: - - polynomial = 0x8BB7 - - initial value = 0x0000 - - final XOR = 0x0000 - - reflect input = false - - reflect output = false - - check value = 0xD0DB - @return CRC-16 T10-DIF parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_T10DIF() -{ - static const Parameters parameters = { 0x8BB7, 0x0000, 0x0000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-16 USB. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 USB has the following parameters and check value: - - polynomial = 0x8005 - - initial value = 0xFFFF - - final XOR = 0xFFFF - - reflect input = true - - reflect output = true - - check value = 0xB4C8 - @return CRC-16 USB parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_USB() -{ - static const Parameters parameters = { 0x8005, 0xFFFF, 0xFFFF, true, true }; - return parameters; -} -#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - -/** - @brief Returns a set of parameters for CRC-16 X-25 (aka CRC-16 IBM-SDLC, CRC-16 ISO-HDLC, CRC-16 B). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 X-25 has the following parameters and check value: - - polynomial = 0x1021 - - initial value = 0xFFFF - - final XOR = 0xFFFF - - reflect input = true - - reflect output = true - - check value = 0x906E - @return CRC-16 X-25 parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_X25() -{ - static const Parameters parameters = { 0x1021, 0xFFFF, 0xFFFF, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-16 XMODEM (aka CRC-16 ZMODEM, CRC-16 ACORN, CRC-16 LTE). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-16 XMODEM has the following parameters and check value: - - polynomial = 0x1021 - - initial value = 0x0000 - - final XOR = 0x0000 - - reflect input = false - - reflect output = false - - check value = 0x31C3 - @return CRC-16 XMODEM parameters -*/ -inline const CRC::Parameters & CRC::CRC_16_XMODEM() -{ - static const Parameters parameters = { 0x1021, 0x0000, 0x0000, false, false }; - return parameters; -} - -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS -/** - @brief Returns a set of parameters for CRC-17 CAN. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-17 CAN has the following parameters and check value: - - polynomial = 0x1685B - - initial value = 0x00000 - - final XOR = 0x00000 - - reflect input = false - - reflect output = false - - check value = 0x04F03 - @return CRC-17 CAN parameters -*/ -inline const CRC::Parameters & CRC::CRC_17_CAN() -{ - static const Parameters parameters = { 0x1685B, 0x00000, 0x00000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-21 CAN. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-21 CAN has the following parameters and check value: - - polynomial = 0x102899 - - initial value = 0x000000 - - final XOR = 0x000000 - - reflect input = false - - reflect output = false - - check value = 0x0ED841 - @return CRC-21 CAN parameters -*/ -inline const CRC::Parameters & CRC::CRC_21_CAN() -{ - static const Parameters parameters = { 0x102899, 0x000000, 0x000000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-24 OPENPGP. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-24 OPENPGP has the following parameters and check value: - - polynomial = 0x864CFB - - initial value = 0xB704CE - - final XOR = 0x000000 - - reflect input = false - - reflect output = false - - check value = 0x21CF02 - @return CRC-24 OPENPGP parameters -*/ -inline const CRC::Parameters & CRC::CRC_24() -{ - static const Parameters parameters = { 0x864CFB, 0xB704CE, 0x000000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-24 FlexRay-A. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-24 FlexRay-A has the following parameters and check value: - - polynomial = 0x5D6DCB - - initial value = 0xFEDCBA - - final XOR = 0x000000 - - reflect input = false - - reflect output = false - - check value = 0x7979BD - @return CRC-24 FlexRay-A parameters -*/ -inline const CRC::Parameters & CRC::CRC_24_FLEXRAYA() -{ - static const Parameters parameters = { 0x5D6DCB, 0xFEDCBA, 0x000000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-24 FlexRay-B. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-24 FlexRay-B has the following parameters and check value: - - polynomial = 0x5D6DCB - - initial value = 0xABCDEF - - final XOR = 0x000000 - - reflect input = false - - reflect output = false - - check value = 0x1F23B8 - @return CRC-24 FlexRay-B parameters -*/ -inline const CRC::Parameters & CRC::CRC_24_FLEXRAYB() -{ - static const Parameters parameters = { 0x5D6DCB, 0xABCDEF, 0x000000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-30 CDMA. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-30 CDMA has the following parameters and check value: - - polynomial = 0x2030B9C7 - - initial value = 0x3FFFFFFF - - final XOR = 0x00000000 - - reflect input = false - - reflect output = false - - check value = 0x3B3CB540 - @return CRC-30 CDMA parameters -*/ -inline const CRC::Parameters & CRC::CRC_30() -{ - static const Parameters parameters = { 0x2030B9C7, 0x3FFFFFFF, 0x00000000, false, false }; - return parameters; -} -#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - -/** - @brief Returns a set of parameters for CRC-32 (aka CRC-32 ADCCP, CRC-32 PKZip). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-32 has the following parameters and check value: - - polynomial = 0x04C11DB7 - - initial value = 0xFFFFFFFF - - final XOR = 0xFFFFFFFF - - reflect input = true - - reflect output = true - - check value = 0xCBF43926 - @return CRC-32 parameters -*/ -inline const CRC::Parameters & CRC::CRC_32() -{ - static const Parameters parameters = { 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-32 BZIP2 (aka CRC-32 AAL5, CRC-32 DECT-B, CRC-32 B-CRC). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-32 BZIP2 has the following parameters and check value: - - polynomial = 0x04C11DB7 - - initial value = 0xFFFFFFFF - - final XOR = 0xFFFFFFFF - - reflect input = false - - reflect output = false - - check value = 0xFC891918 - @return CRC-32 BZIP2 parameters -*/ -inline const CRC::Parameters & CRC::CRC_32_BZIP2() -{ - static const Parameters parameters = { 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, false, false }; - return parameters; -} - -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS -/** - @brief Returns a set of parameters for CRC-32 C (aka CRC-32 ISCSI, CRC-32 Castagnoli, CRC-32 Interlaken). - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-32 C has the following parameters and check value: - - polynomial = 0x1EDC6F41 - - initial value = 0xFFFFFFFF - - final XOR = 0xFFFFFFFF - - reflect input = true - - reflect output = true - - check value = 0xE3069283 - @return CRC-32 C parameters -*/ -inline const CRC::Parameters & CRC::CRC_32_C() -{ - static const Parameters parameters = { 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, true, true }; - return parameters; -} -#endif - -/** - @brief Returns a set of parameters for CRC-32 MPEG-2. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-32 MPEG-2 has the following parameters and check value: - - polynomial = 0x04C11DB7 - - initial value = 0xFFFFFFFF - - final XOR = 0x00000000 - - reflect input = false - - reflect output = false - - check value = 0x0376E6E7 - @return CRC-32 MPEG-2 parameters -*/ -inline const CRC::Parameters & CRC::CRC_32_MPEG2() -{ - static const Parameters parameters = { 0x04C11DB7, 0xFFFFFFFF, 0x00000000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-32 POSIX. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-32 POSIX has the following parameters and check value: - - polynomial = 0x04C11DB7 - - initial value = 0x00000000 - - final XOR = 0xFFFFFFFF - - reflect input = false - - reflect output = false - - check value = 0x765E7680 - @return CRC-32 POSIX parameters -*/ -inline const CRC::Parameters & CRC::CRC_32_POSIX() -{ - static const Parameters parameters = { 0x04C11DB7, 0x00000000, 0xFFFFFFFF, false, false }; - return parameters; -} - -#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS -/** - @brief Returns a set of parameters for CRC-32 Q. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-32 Q has the following parameters and check value: - - polynomial = 0x814141AB - - initial value = 0x00000000 - - final XOR = 0x00000000 - - reflect input = false - - reflect output = false - - check value = 0x3010BF7F - @return CRC-32 Q parameters -*/ -inline const CRC::Parameters & CRC::CRC_32_Q() -{ - static const Parameters parameters = { 0x814141AB, 0x00000000, 0x00000000, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-40 GSM. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-40 GSM has the following parameters and check value: - - polynomial = 0x0004820009 - - initial value = 0x0000000000 - - final XOR = 0xFFFFFFFFFF - - reflect input = false - - reflect output = false - - check value = 0xD4164FC646 - @return CRC-40 GSM parameters -*/ -inline const CRC::Parameters & CRC::CRC_40_GSM() -{ - static const Parameters parameters = { 0x0004820009, 0x0000000000, 0xFFFFFFFFFF, false, false }; - return parameters; -} - -/** - @brief Returns a set of parameters for CRC-64 ECMA. - @note The parameters are static and are delayed-constructed to reduce memory footprint. - @note CRC-64 ECMA has the following parameters and check value: - - polynomial = 0x42F0E1EBA9EA3693 - - initial value = 0x0000000000000000 - - final XOR = 0x0000000000000000 - - reflect input = false - - reflect output = false - - check value = 0x6C40DF5F0B497347 - @return CRC-64 ECMA parameters -*/ -inline const CRC::Parameters & CRC::CRC_64() -{ - static const Parameters parameters = { 0x42F0E1EBA9EA3693, 0x0000000000000000, 0x0000000000000000, false, false }; - return parameters; -} -#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - -#ifdef CRCPP_USE_NAMESPACE -} -#endif - -#endif // CRCPP_CRC_H_ diff --git a/src/3rdParty/libE57Format/include/CMakeLists.txt b/src/3rdParty/libE57Format/include/CMakeLists.txt deleted file mode 100644 index b637ddb098..0000000000 --- a/src/3rdParty/libE57Format/include/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-License-Identifier: MIT -# Copyright 2020 Andy Maloney - -target_sources( ${PROJECT_NAME} - PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/E57Exception.h - ${CMAKE_CURRENT_LIST_DIR}/E57Format.h - ${CMAKE_CURRENT_LIST_DIR}/E57SimpleData.h - ${CMAKE_CURRENT_LIST_DIR}/E57SimpleReader.h - ${CMAKE_CURRENT_LIST_DIR}/E57SimpleWriter.h -) - -#install( -# FILES -# E57Format.h -# E57Exception.h -# E57SimpleData.h -# E57SimpleReader.h -# E57SimpleWriter.h -# DESTINATION -# include/E57Format -#) - -target_include_directories( ${PROJECT_NAME} - SYSTEM PUBLIC - $ - $ -) diff --git a/src/3rdParty/libE57Format/include/E57Exception.h b/src/3rdParty/libE57Format/include/E57Exception.h deleted file mode 100644 index 7f25a016af..0000000000 --- a/src/3rdParty/libE57Format/include/E57Exception.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include -#include -#include - -#include "E57Export.h" - -namespace e57 -{ - //! @brief Numeric error identifiers used in E57Exception - enum ErrorCode - { - // N.B. *** When changing error strings here, remember to update the error - // strings in E57Exception.cpp **** - E57_SUCCESS = 0, //!< operation was successful - E57_ERROR_BAD_CV_HEADER = 1, //!< a CompressedVector binary header was bad - E57_ERROR_BAD_CV_PACKET = 2, //!< a CompressedVector binary packet was bad - E57_ERROR_CHILD_INDEX_OUT_OF_BOUNDS = 3, //!< a numerical index identifying a child was out of bounds - E57_ERROR_SET_TWICE = 4, //!< attempted to set an existing child element to a new value - E57_ERROR_HOMOGENEOUS_VIOLATION = 5, //!< attempted to add an E57 Element that would have made the children - //!< of a homogeneous Vector have different types - E57_ERROR_VALUE_NOT_REPRESENTABLE = 6, //!< a value could not be represented in the requested type - E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE = 7, //!< after scaling the result could not be represented in the - //!< requested type - E57_ERROR_REAL64_TOO_LARGE = 8, //!< a 64 bit IEEE float was too large to store in a 32 bit IEEE float - E57_ERROR_EXPECTING_NUMERIC = 9, //!< Expecting numeric representation in user's buffer, found ustring - E57_ERROR_EXPECTING_USTRING = 10, //!< Expecting string representation in user's buffer, found numeric - E57_ERROR_INTERNAL = 11, //!< An unrecoverable inconsistent internal state was detected - E57_ERROR_BAD_XML_FORMAT = 12, //!< E57 primitive not encoded in XML correctly - E57_ERROR_XML_PARSER = 13, //!< XML not well formed - E57_ERROR_BAD_API_ARGUMENT = 14, //!< bad API function argument provided by user - E57_ERROR_FILE_IS_READ_ONLY = 15, //!< can't modify read only file - E57_ERROR_BAD_CHECKSUM = 16, //!< checksum mismatch, file is corrupted - E57_ERROR_OPEN_FAILED = 17, //!< open() failed - E57_ERROR_CLOSE_FAILED = 18, //!< close() failed - E57_ERROR_READ_FAILED = 19, //!< read() failed - E57_ERROR_WRITE_FAILED = 20, //!< write() failed - E57_ERROR_LSEEK_FAILED = 21, //!< lseek() failed - E57_ERROR_PATH_UNDEFINED = 22, //!< E57 element path well formed but not defined - E57_ERROR_BAD_BUFFER = 23, //!< bad SourceDestBuffer - E57_ERROR_NO_BUFFER_FOR_ELEMENT = 24, //!< no buffer specified for an element in CompressedVectorNode during - //!< write - E57_ERROR_BUFFER_SIZE_MISMATCH = 25, //!< SourceDestBuffers not all same size - E57_ERROR_BUFFER_DUPLICATE_PATHNAME = 26, //!< duplicate pathname in CompressedVectorNode read/write - E57_ERROR_BAD_FILE_SIGNATURE = 27, //!< file signature not "ASTM-E57" - E57_ERROR_UNKNOWN_FILE_VERSION = 28, //!< incompatible file version - E57_ERROR_BAD_FILE_LENGTH = 29, //!< size in file header not same as actual - E57_ERROR_XML_PARSER_INIT = 30, //!< XML parser failed to initialize - E57_ERROR_DUPLICATE_NAMESPACE_PREFIX = 31, //!< namespace prefix already defined - E57_ERROR_DUPLICATE_NAMESPACE_URI = 32, //!< namespace URI already defined - E57_ERROR_BAD_PROTOTYPE = 33, //!< bad prototype in CompressedVectorNode - E57_ERROR_BAD_CODECS = 34, //!< bad codecs in CompressedVectorNode - E57_ERROR_VALUE_OUT_OF_BOUNDS = 35, //!< element value out of min/max bounds - E57_ERROR_CONVERSION_REQUIRED = 36, //!< conversion required to assign element value, but not requested - E57_ERROR_BAD_PATH_NAME = 37, //!< E57 path name is not well formed - E57_ERROR_NOT_IMPLEMENTED = 38, //!< functionality not implemented - E57_ERROR_BAD_NODE_DOWNCAST = 39, //!< bad downcast from Node to specific node type - E57_ERROR_WRITER_NOT_OPEN = 40, //!< CompressedVectorWriter is no longer open - E57_ERROR_READER_NOT_OPEN = 41, //!< CompressedVectorReader is no longer open - E57_ERROR_NODE_UNATTACHED = 42, //!< node is not yet attached to tree of ImageFile - E57_ERROR_ALREADY_HAS_PARENT = 43, //!< node already has a parent - E57_ERROR_DIFFERENT_DEST_IMAGEFILE = 44, //!< nodes were constructed with different destImageFiles - E57_ERROR_IMAGEFILE_NOT_OPEN = 45, //!< destImageFile is no longer open - E57_ERROR_BUFFERS_NOT_COMPATIBLE = 46, //!< SourceDestBuffers not compatible with previously given ones - E57_ERROR_TOO_MANY_WRITERS = 47, //!< too many open CompressedVectorWriters of an ImageFile - E57_ERROR_TOO_MANY_READERS = 48, //!< too many open CompressedVectorReaders of an ImageFile - E57_ERROR_BAD_CONFIGURATION = 49, //!< bad configuration string - E57_ERROR_INVARIANCE_VIOLATION = 50 //!< class invariance constraint violation in debug mode - }; - - class E57_DLL E57Exception : public std::exception - { - public: - void report( const char *reportingFileName = nullptr, int reportingLineNumber = 0, - const char *reportingFunctionName = nullptr, std::ostream &os = std::cout ) const; - ErrorCode errorCode() const; - std::string context() const; - const char *what() const noexcept override; - - // For debugging purposes: - const char *sourceFileName() const; - const char *sourceFunctionName() const; - int sourceLineNumber() const; - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - E57Exception() = delete; - E57Exception( ErrorCode ecode, const std::string &context, const std::string &srcFileName = nullptr, - int srcLineNumber = 0, const char *srcFunctionName = nullptr ); - ~E57Exception() noexcept override = default; - - protected: - ErrorCode errorCode_; - std::string context_; - std::string sourceFileName_; - const char *sourceFunctionName_; - int sourceLineNumber_; - //! \endcond - }; - - namespace Utilities - { - // Get latest version of ASTM standard supported, and library id string - E57_DLL void getVersions( int &astmMajor, int &astmMinor, std::string &libraryId ); - - E57_DLL std::string errorCodeToString( ErrorCode ecode ); - } -} diff --git a/src/3rdParty/libE57Format/include/E57Format.h b/src/3rdParty/libE57Format/include/E57Format.h deleted file mode 100644 index a622910534..0000000000 --- a/src/3rdParty/libE57Format/include/E57Format.h +++ /dev/null @@ -1,697 +0,0 @@ -/* - * E57Format.h - public header of E57 API for reading/writing .e57 files. - * - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -//! @file E57Format.h header file for the E57 API - -#include -#include -#include -#include - -#include "E57Exception.h" - -namespace e57 -{ - using std::int16_t; - using std::int32_t; - using std::int64_t; - using std::int8_t; - using std::uint16_t; - using std::uint32_t; - using std::uint64_t; - using std::uint8_t; - - // Shorthand for unicode string - //! @brief UTF-8 encodeded Unicode string - using ustring = std::string; - - //! @brief Identifiers for types of E57 elements - enum NodeType - { - E57_STRUCTURE = 1, //!< StructureNode class - E57_VECTOR = 2, //!< VectorNode class - E57_COMPRESSED_VECTOR = 3, //!< CompressedVectorNode class - E57_INTEGER = 4, //!< IntegerNode class - E57_SCALED_INTEGER = 5, //!< ScaledIntegerNode class - E57_FLOAT = 6, //!< FloatNode class - E57_STRING = 7, //!< StringNode class - E57_BLOB = 8 //!< BlobNode class - }; - - //! @brief The IEEE floating point number precisions supported - enum FloatPrecision - { - E57_SINGLE = 1, //!< 32 bit IEEE floating point number format - E57_DOUBLE = 2 //!< 64 bit IEEE floating point number format - }; - - //! @brief Identifies the representations of memory elements API can transfer - //! data to/from - enum MemoryRepresentation - { - E57_INT8 = 1, //!< 8 bit signed integer - E57_UINT8 = 2, //!< 8 bit unsigned integer - E57_INT16 = 3, //!< 16 bit signed integer - E57_UINT16 = 4, //!< 16 bit unsigned integer - E57_INT32 = 5, //!< 32 bit signed integer - E57_UINT32 = 6, //!< 32 bit unsigned integer - E57_INT64 = 7, //!< 64 bit signed integer - E57_BOOL = 8, //!< C++ boolean type - E57_REAL32 = 9, //!< C++ float type - E57_REAL64 = 10, //!< C++ double type - E57_USTRING = 11 //!< Unicode UTF-8 std::string - }; - - //! @brief Specifies the percentage of checksums which are verified when reading - //! an ImageFile (0-100%). - using ReadChecksumPolicy = int; - - //! Do not verify the checksums. (fast) - constexpr ReadChecksumPolicy CHECKSUM_POLICY_NONE = 0; - //! Only verify 25% of the checksums. The last block is always verified. - constexpr ReadChecksumPolicy CHECKSUM_POLICY_SPARSE = 25; - //! Only verify 50% of the checksums. The last block is always verified. - constexpr ReadChecksumPolicy CHECKSUM_POLICY_HALF = 50; - //! Verify all checksums. This is the default. (slow) - constexpr ReadChecksumPolicy CHECKSUM_POLICY_ALL = 100; - - //! @brief The URI of ASTM E57 v1.0 standard XML namespace - //! Note that even though this URI does not point to a valid document, the standard (section 8.4.2.3) - //! says that this is the required namespace. - constexpr char E57_V1_0_URI[] = "http://www.astm.org/COMMIT/E57/2010-e57-v1.0"; - - //! @cond documentNonPublic The following aren't documented - // Minimum and maximum values for integers - constexpr int8_t E57_INT8_MIN = -128; - constexpr int8_t E57_INT8_MAX = 127; - constexpr int16_t E57_INT16_MIN = -32768; - constexpr int16_t E57_INT16_MAX = 32767; - constexpr int32_t E57_INT32_MIN = -2147483647 - 1; - constexpr int32_t E57_INT32_MAX = 2147483647; - constexpr int64_t E57_INT64_MIN = -9223372036854775807LL - 1; - constexpr int64_t E57_INT64_MAX = 9223372036854775807LL; - constexpr uint8_t E57_UINT8_MIN = 0U; - constexpr uint8_t E57_UINT8_MAX = 0xffU; /* 255U */ - constexpr uint16_t E57_UINT16_MIN = 0U; - constexpr uint16_t E57_UINT16_MAX = 0xffffU; /* 65535U */ - constexpr uint32_t E57_UINT32_MIN = 0U; - constexpr uint32_t E57_UINT32_MAX = 0xffffffffU; /* 4294967295U */ - constexpr uint64_t E57_UINT64_MIN = 0ULL; - constexpr uint64_t E57_UINT64_MAX = 0xffffffffffffffffULL; /* 18446744073709551615ULL */ - - constexpr float E57_FLOAT_MIN = -FLT_MAX; - constexpr float E57_FLOAT_MAX = FLT_MAX; - constexpr double E57_DOUBLE_MIN = -DBL_MAX; - constexpr double E57_DOUBLE_MAX = DBL_MAX; -//! @endcond - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -// Internal implementation files should include E57FormatImpl.h first which -// defines symbol E57_INTERNAL_IMPLEMENTATION_ENABLE. Normal API users should -// not define this symbol. Basically the internal version allows access to the -// pointer to the implementation (impl_) -#ifdef E57_INTERNAL_IMPLEMENTATION_ENABLE -#define E57_OBJECT_IMPLEMENTATION( T ) \ -public: \ - std::shared_ptr impl() const \ - { \ - return ( impl_ ); \ - } \ - \ -protected: \ - std::shared_ptr impl_; -#else -#define E57_OBJECT_IMPLEMENTATION( T ) \ -protected: \ - std::shared_ptr impl_; -#endif - //! @endcond - - class BlobNode; - class BlobNodeImpl; - class CompressedVectorNode; - class CompressedVectorNodeImpl; - class CompressedVectorReader; - class CompressedVectorReaderImpl; - class CompressedVectorWriter; - class CompressedVectorWriterImpl; - class FloatNode; - class FloatNodeImpl; - class ImageFile; - class ImageFileImpl; - class IntegerNode; - class IntegerNodeImpl; - class Node; - class NodeImpl; - class ScaledIntegerNode; - class ScaledIntegerNodeImpl; - class SourceDestBuffer; - class SourceDestBufferImpl; - class StringNode; - class StringNodeImpl; - class StructureNode; - class StructureNodeImpl; - class VectorNode; - class VectorNodeImpl; - - class E57_DLL Node - { - public: - Node() = delete; - - NodeType type() const; - bool isRoot() const; - Node parent() const; - ustring pathName() const; - ustring elementName() const; - ImageFile destImageFile() const; - bool isAttached() const; - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true, bool doDowncast = true ); - bool operator==( Node n2 ) const; - bool operator!=( Node n2 ) const; - -//! \cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -#ifdef E57_INTERNAL_IMPLEMENTATION_ENABLE - explicit Node( std::shared_ptr ); // internal use only -#endif - - private: - friend class NodeImpl; - - E57_OBJECT_IMPLEMENTATION( Node ) // Internal implementation details, not - // part of API, must be last in object - //! \endcond - }; - - class E57_DLL StructureNode - { - public: - StructureNode() = delete; - StructureNode( ImageFile destImageFile ); - - int64_t childCount() const; - bool isDefined( const ustring &pathName ) const; - Node get( int64_t index ) const; - Node get( const ustring &pathName ) const; - void set( const ustring &pathName, const Node &n ); - - // Up/Down cast conversion - operator Node() const; - explicit StructureNode( const Node &n ); - - // Common generic Node functions - bool isRoot() const; - Node parent() const; - ustring pathName() const; - ustring elementName() const; - ImageFile destImageFile() const; - bool isAttached() const; - - // Diagnostic functions: - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true, bool doUpcast = true ); - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - friend class ImageFile; - - StructureNode( std::shared_ptr ni ); // internal use only - StructureNode( std::weak_ptr fileParent ); // internal use only - - E57_OBJECT_IMPLEMENTATION( StructureNode ) // Internal implementation details, not part of API, must - // be last in object - //! \endcond - }; - - class E57_DLL VectorNode - { - public: - VectorNode() = delete; - explicit VectorNode( ImageFile destImageFile, bool allowHeteroChildren = false ); - - bool allowHeteroChildren() const; - - int64_t childCount() const; - bool isDefined( const ustring &pathName ) const; - Node get( int64_t index ) const; - Node get( const ustring &pathName ) const; - void append( const Node &n ); - - // Up/Down cast conversion - operator Node() const; - explicit VectorNode( const Node &n ); - - // Common generic Node functions - bool isRoot() const; - Node parent() const; - ustring pathName() const; - ustring elementName() const; - ImageFile destImageFile() const; - bool isAttached() const; - - // Diagnostic functions: - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true, bool doUpcast = true ); - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - friend class CompressedVectorNode; - - VectorNode( std::shared_ptr ni ); // internal use only - - E57_OBJECT_IMPLEMENTATION( VectorNode ) // Internal implementation details, not part of API, must be - // last in object - //! \endcond - }; - - class E57_DLL SourceDestBuffer - { - public: - SourceDestBuffer() = delete; - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, int8_t *b, const size_t capacity, - bool doConversion = false, bool doScaling = false, size_t stride = sizeof( int8_t ) ); - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, uint8_t *b, const size_t capacity, - bool doConversion = false, bool doScaling = false, size_t stride = sizeof( uint8_t ) ); - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, int16_t *b, const size_t capacity, - bool doConversion = false, bool doScaling = false, size_t stride = sizeof( int16_t ) ); - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, uint16_t *b, const size_t capacity, - bool doConversion = false, bool doScaling = false, size_t stride = sizeof( uint16_t ) ); - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, int32_t *b, const size_t capacity, - bool doConversion = false, bool doScaling = false, size_t stride = sizeof( int32_t ) ); - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, uint32_t *b, const size_t capacity, - bool doConversion = false, bool doScaling = false, size_t stride = sizeof( uint32_t ) ); - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, int64_t *b, const size_t capacity, - bool doConversion = false, bool doScaling = false, size_t stride = sizeof( int64_t ) ); - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, bool *b, const size_t capacity, - bool doConversion = false, bool doScaling = false, size_t stride = sizeof( bool ) ); - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, float *b, const size_t capacity, - bool doConversion = false, bool doScaling = false, size_t stride = sizeof( float ) ); - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, double *b, const size_t capacity, - bool doConversion = false, bool doScaling = false, size_t stride = sizeof( double ) ); - SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, std::vector *b ); - - ustring pathName() const; - enum MemoryRepresentation memoryRepresentation() const; - size_t capacity() const; - bool doConversion() const; - bool doScaling() const; - size_t stride() const; - - // Diagnostic functions: - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true ) const; - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - E57_OBJECT_IMPLEMENTATION( SourceDestBuffer ) // Internal implementation details, not part of - // API, must be last in object - //! \endcond - }; - - class E57_DLL CompressedVectorReader - { - public: - CompressedVectorReader() = delete; - - unsigned read(); - unsigned read( std::vector &dbufs ); - void seek( int64_t recordNumber ); // !!! not implemented yet - void close(); - bool isOpen(); - CompressedVectorNode compressedVectorNode() const; - - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true ); - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - friend class CompressedVectorNode; - - CompressedVectorReader( std::shared_ptr ni ); - - E57_OBJECT_IMPLEMENTATION( CompressedVectorReader ) // Internal implementation details, not - // part of API, must be last in object - //! \endcond - }; - - class E57_DLL CompressedVectorWriter - { - public: - CompressedVectorWriter() = delete; - - void write( const size_t recordCount ); - void write( std::vector &sbufs, const size_t recordCount ); - void close(); - bool isOpen(); - CompressedVectorNode compressedVectorNode() const; - - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true ); - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - friend class CompressedVectorNode; - - CompressedVectorWriter( std::shared_ptr ni ); - - E57_OBJECT_IMPLEMENTATION( CompressedVectorWriter ) // Internal implementation details, not - // part of API, must be last in object - //! \endcond - }; - - class E57_DLL CompressedVectorNode - { - public: - CompressedVectorNode() = delete; - explicit CompressedVectorNode( ImageFile destImageFile, const Node &prototype, const VectorNode &codecs ); - - int64_t childCount() const; - Node prototype() const; - VectorNode codecs() const; - - // Iterators - CompressedVectorWriter writer( std::vector &sbufs ); - CompressedVectorReader reader( const std::vector &dbufs ); - - // Up/Down cast conversion - operator Node() const; - explicit CompressedVectorNode( const Node &n ); - - // Common generic Node functions - bool isRoot() const; - Node parent() const; - ustring pathName() const; - ustring elementName() const; - ImageFile destImageFile() const; - bool isAttached() const; - - // Diagnostic functions: - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true, bool doUpcast = true ); - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - friend class CompressedVectorReader; - friend class CompressedVectorWriter; - friend class E57XmlParser; - - CompressedVectorNode( std::shared_ptr ni ); // internal use only - - E57_OBJECT_IMPLEMENTATION( CompressedVectorNode ) // Internal implementation details, not part - // of API, must be last in object - //! \endcond - }; - - class E57_DLL IntegerNode - { - public: - IntegerNode() = delete; - explicit IntegerNode( ImageFile destImageFile, int64_t value = 0, int64_t minimum = E57_INT64_MIN, - int64_t maximum = E57_INT64_MAX ); - - int64_t value() const; - int64_t minimum() const; - int64_t maximum() const; - - // Up/Down cast conversion - operator Node() const; - explicit IntegerNode( const Node &n ); - - // Common generic Node functions - bool isRoot() const; - Node parent() const; - ustring pathName() const; - ustring elementName() const; - ImageFile destImageFile() const; - bool isAttached() const; - - // Diagnostic functions: - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true, bool doUpcast = true ); - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - IntegerNode( std::shared_ptr ni ); // internal use only - - E57_OBJECT_IMPLEMENTATION( IntegerNode ) // Internal implementation details, not part of API, must be - // last in object - //! \endcond - }; - - class E57_DLL ScaledIntegerNode - { - public: - ScaledIntegerNode() = delete; - explicit ScaledIntegerNode( ImageFile destImageFile, int64_t rawValue, int64_t minimum, int64_t maximum, - double scale = 1.0, double offset = 0.0 ); - explicit ScaledIntegerNode( ImageFile destImageFile, int rawValue, int64_t minimum, int64_t maximum, - double scale = 1.0, double offset = 0.0 ); - explicit ScaledIntegerNode( ImageFile destImageFile, int rawValue, int minimum, int maximum, double scale = 1.0, - double offset = 0.0 ); - explicit ScaledIntegerNode( ImageFile destImageFile, double scaledValue, double scaledMinimum, - double scaledMaximum, double scale = 1.0, double offset = 0.0 ); - - int64_t rawValue() const; - double scaledValue() const; - int64_t minimum() const; - double scaledMinimum() const; - int64_t maximum() const; - double scaledMaximum() const; - double scale() const; - double offset() const; - - // Up/Down cast conversion - operator Node() const; - explicit ScaledIntegerNode( const Node &n ); - - // Common generic Node functions - bool isRoot() const; - Node parent() const; - ustring pathName() const; - ustring elementName() const; - ImageFile destImageFile() const; - bool isAttached() const; - - // Diagnostic functions: - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true, bool doUpcast = true ); - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - ScaledIntegerNode( std::shared_ptr ni ); // internal use only - - E57_OBJECT_IMPLEMENTATION( ScaledIntegerNode ) // Internal implementation details, not part of - // API, must be last in object - //! \endcond - }; - - class E57_DLL FloatNode - { - public: - FloatNode() = delete; - explicit FloatNode( ImageFile destImageFile, double value = 0.0, FloatPrecision precision = E57_DOUBLE, - double minimum = E57_DOUBLE_MIN, double maximum = E57_DOUBLE_MAX ); - - double value() const; - FloatPrecision precision() const; - double minimum() const; - double maximum() const; - - // Up/Down cast conversion - operator Node() const; - explicit FloatNode( const Node &n ); - - // Common generic Node functions - bool isRoot() const; - Node parent() const; - ustring pathName() const; - ustring elementName() const; - ImageFile destImageFile() const; - bool isAttached() const; - - // Diagnostic functions: - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true, bool doUpcast = true ); - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - FloatNode( std::shared_ptr ni ); // internal use only - - E57_OBJECT_IMPLEMENTATION( FloatNode ) // Internal implementation details, not part of API, must be - // last in object - //! \endcond - }; - - class E57_DLL StringNode - { - public: - StringNode() = delete; - explicit StringNode( ImageFile destImageFile, const ustring &value = "" ); - - ustring value() const; - - // Up/Down cast conversion - operator Node() const; - explicit StringNode( const Node &n ); - - // Common generic Node functions - bool isRoot() const; - Node parent() const; - ustring pathName() const; - ustring elementName() const; - ImageFile destImageFile() const; - bool isAttached() const; - - // Diagnostic functions: - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true, bool doUpcast = true ); - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - friend class StringNodeImpl; - StringNode( std::shared_ptr ni ); // internal use only - - E57_OBJECT_IMPLEMENTATION( StringNode ) // Internal implementation details, not part of API, must be - // last in object - //! \endcond - }; - - class E57_DLL BlobNode - { - public: - BlobNode() = delete; - explicit BlobNode( ImageFile destImageFile, int64_t byteCount ); - - int64_t byteCount() const; - void read( uint8_t *buf, int64_t start, size_t count ); - void write( uint8_t *buf, int64_t start, size_t count ); - - // Up/Down cast conversion - operator Node() const; - explicit BlobNode( const Node &n ); - - // Common generic Node functions - bool isRoot() const; - Node parent() const; - ustring pathName() const; - ustring elementName() const; - ImageFile destImageFile() const; - bool isAttached() const; - - // Diagnostic functions: - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true, bool doUpcast = true ); - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - friend class E57XmlParser; - - BlobNode( std::shared_ptr ni ); // internal use only - - // Internal use only, create blob already in a file - BlobNode( ImageFile destImageFile, int64_t fileOffset, int64_t length ); - - E57_OBJECT_IMPLEMENTATION( BlobNode ) // Internal implementation details, not - // part of API, must be last in object - //! \endcond - }; - - class E57_DLL ImageFile - { - public: - ImageFile() = delete; - ImageFile( const ustring &fname, const ustring &mode, ReadChecksumPolicy checksumPolicy = CHECKSUM_POLICY_ALL ); - ImageFile( const char *input, const uint64_t size, ReadChecksumPolicy checksumPolicy = CHECKSUM_POLICY_ALL ); - - StructureNode root() const; - void close(); - void cancel(); - bool isOpen() const; - bool isWritable() const; - ustring fileName() const; - int writerCount() const; - int readerCount() const; - - // Manipulate registered extensions in the file - void extensionsAdd( const ustring &prefix, const ustring &uri ); - bool extensionsLookupPrefix( const ustring &prefix, ustring &uri ) const; - bool extensionsLookupUri( const ustring &uri, ustring &prefix ) const; - size_t extensionsCount() const; - ustring extensionsPrefix( const size_t index ) const; - ustring extensionsUri( const size_t index ) const; - - // Field name functions: - bool isElementNameExtended( const ustring &elementName ) const; - void elementNameParse( const ustring &elementName, ustring &prefix, ustring &localPart ) const; - - // Diagnostic functions: - void dump( int indent = 0, std::ostream &os = std::cout ) const; - void checkInvariant( bool doRecurse = true ) const; - bool operator==( ImageFile imf2 ) const; - bool operator!=( ImageFile imf2 ) const; - - //! \cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - private: - ImageFile( double ); // Give a second dummy constructor, better error msg - // for: ImageFile(0) - - friend class Node; - friend class StructureNode; - friend class VectorNode; - friend class CompressedVectorNode; - friend class IntegerNode; - friend class ScaledIntegerNode; - friend class FloatNode; - friend class StringNode; - friend class BlobNode; - - ImageFile( std::shared_ptr imfi ); // internal use only - - E57_OBJECT_IMPLEMENTATION( ImageFile ) // Internal implementation details, not part of API, must be - // last in object - //! \endcond - }; -} diff --git a/src/3rdParty/libE57Format/include/E57SimpleData.h b/src/3rdParty/libE57Format/include/E57SimpleData.h deleted file mode 100644 index 47eb35e357..0000000000 --- a/src/3rdParty/libE57Format/include/E57SimpleData.h +++ /dev/null @@ -1,653 +0,0 @@ -/* - * E57Simple - public header of E57 Simple API for reading/writing .e57 files. - * - * Copyright (c) 2010 Stan Coleby (scoleby@intelisum.com) - * Copyright (c) 2020 PTC Inc. - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -//! @file E57SimpleData.h Data structures for E57 Simple API - -#include "E57Format.h" - -namespace e57 -{ - - //! Indicates to use FloatNode instead of ScaledIntegerNode in fields that can use both. - constexpr double E57_NOT_SCALED_USE_FLOAT = 0.; - //! Indicates to use ScaledIntegerNode instead of FloatNode in fields that can use both. - constexpr double E57_NOT_SCALED_USE_INTEGER = -1.; - - //! @cond documentNonPublic The following isn't part of the API, and isn't documented. - class ReaderImpl; - class WriterImpl; - //! @endcond - - //! @brief Defines a rigid body translation in Cartesian coordinates. - struct E57_DLL Translation - { - double x{ 0. }; //!< The X coordinate of the translation (in meters) - double y{ 0. }; //!< The Y coordinate of the translation (in meters) - double z{ 0. }; //!< The Z coordinate of the translation (in meters) - - bool operator==( const Translation &rhs ) const - { - return ( x == rhs.x ) && ( y == rhs.y ) && ( z == rhs.z ); - } - bool operator!=( const Translation &rhs ) const - { - return !operator==( rhs ); - } - - static Translation identity() - { - return {}; - } - }; - - //! @brief Represents a rigid body rotation. - struct E57_DLL Quaternion - { - double w{ 0. }; //!< The real part of the quaternion. Shall be nonnegative - double x{ 0. }; //!< The i coefficient of the quaternion - double y{ 0. }; //!< The j coefficient of the quaternion - double z{ 0. }; //!< The k coefficient of the quaternion - - bool operator==( const Quaternion &rhs ) const - { - return ( w == rhs.w ) && ( x == rhs.x ) && ( y == rhs.y ) && ( z == rhs.z ); - } - bool operator!=( const Quaternion &rhs ) const - { - return !operator==( rhs ); - } - - static Quaternion identity() - { - Quaternion identity; - identity.w = 1.; - return identity; - } - }; - - //! @brief Defines a rigid body transform in cartesian coordinates. - struct E57_DLL RigidBodyTransform - { - Quaternion rotation; //!< A unit quaternion representing the rotation, R, of the transform - Translation translation; //!< The translation point vector, t, of the transform - - bool operator==( const RigidBodyTransform &rhs ) const - { - return ( rotation == rhs.rotation ) && ( translation == rhs.translation ); - } - bool operator!=( const RigidBodyTransform &rhs ) const - { - return !operator==( rhs ); - } - - static RigidBodyTransform identity() - { - return { Quaternion::identity(), Translation::identity() }; - } - }; - - //! @brief Specifies an axis-aligned box in local cartesian coordinates. - struct E57_DLL CartesianBounds - { - double xMinimum{ -E57_DOUBLE_MAX }; //!< The minimum extent of the bounding box in the X direction - double xMaximum{ E57_DOUBLE_MAX }; //!< The maximum extent of the bounding box in the X direction - double yMinimum{ -E57_DOUBLE_MAX }; //!< The minimum extent of the bounding box in the Y direction - double yMaximum{ E57_DOUBLE_MAX }; //!< The maximum extent of the bounding box in the Y direction - double zMinimum{ -E57_DOUBLE_MAX }; //!< The minimum extent of the bounding box in the Z direction - double zMaximum{ E57_DOUBLE_MAX }; //!< The maximum extent of the bounding box in the Z direction - - bool operator==( const CartesianBounds &rhs ) const - { - return ( xMinimum == rhs.xMinimum ) && ( xMaximum == rhs.xMaximum ) && ( yMinimum == rhs.yMinimum ) && - ( yMaximum == rhs.yMaximum ) && ( zMinimum == rhs.zMinimum ) && ( zMaximum == rhs.zMaximum ); - } - bool operator!=( const CartesianBounds &rhs ) const - { - return !operator==( rhs ); - } - }; - - //! @brief Stores the bounds of some data in spherical coordinates. - struct E57_DLL SphericalBounds - { - SphericalBounds(); // constructor in the cpp to avoid exposing M_PI - double rangeMinimum; //!< The minimum extent of the bounding region in the r direction - double rangeMaximum; //!< The maximum extent of the bounding region in the r direction - double elevationMinimum; //!< The minimum extent of the bounding region from the horizontal plane - double elevationMaximum; //!< The maximum extent of the bounding region from the horizontal plane - double azimuthStart; //!< The starting azimuth angle defining the extent of the bounding region around the z axis - double azimuthEnd; //!< The ending azimuth angle defining the extent of the bounding region around the z axis - - bool operator==( const SphericalBounds &rhs ) const - { - return ( rangeMinimum == rhs.rangeMinimum ) && ( rangeMaximum == rhs.rangeMaximum ) && - ( elevationMinimum == rhs.elevationMinimum ) && ( elevationMaximum == rhs.elevationMaximum ) && - ( azimuthStart == rhs.azimuthStart ) && ( azimuthEnd == rhs.azimuthEnd ); - } - bool operator!=( const SphericalBounds &rhs ) const - { - return !operator==( rhs ); - } - }; - - //! @brief Stores the minimum and maximum of rowIndex, columnIndex, and returnIndex fields for a set of points. - struct E57_DLL IndexBounds - { - int64_t rowMinimum{ 0 }; //!< The minimum rowIndex value of any point represented by this IndexBounds object. - int64_t rowMaximum{ 0 }; //!< The maximum rowIndex value of any point represented by this IndexBounds object. - int64_t columnMinimum{ - 0 - }; //!< The minimum columnIndex value of any point represented by this IndexBounds object. - int64_t columnMaximum{ - 0 - }; //!< The maximum columnIndex value of any point represented by this IndexBounds object. - int64_t returnMinimum{ - 0 - }; //!< The minimum returnIndex value of any point represented by this IndexBounds object. - int64_t returnMaximum{ - 0 - }; //!< The maximum returnIndex value of any point represented by this IndexBounds object. - - bool operator==( const IndexBounds &rhs ) const - { - return ( rowMinimum == rhs.rowMinimum ) && ( rowMaximum == rhs.rowMaximum ) && - ( columnMinimum == rhs.columnMinimum ) && ( columnMaximum == rhs.columnMaximum ) && - ( returnMinimum == rhs.returnMinimum ) && ( returnMaximum == rhs.returnMaximum ); - } - bool operator!=( const IndexBounds &rhs ) const - { - return !operator==( rhs ); - } - }; - - //! @brief Specifies the limits for the value of signal intensity that a sensor is capable of producing - struct E57_DLL IntensityLimits - { - double intensityMinimum{ 0. }; //!< The minimum producible intensity value. Unit is unspecified. - double intensityMaximum{ 0. }; //!< The maximum producible intensity value. Unit is unspecified. - - bool operator==( const IntensityLimits &rhs ) const - { - return ( intensityMinimum == rhs.intensityMinimum ) && ( intensityMaximum == rhs.intensityMaximum ); - } - bool operator!=( const IntensityLimits &rhs ) const - { - return !operator==( rhs ); - } - }; - - //! @brief Specifies the limits for the value of red, green, and blue color that a sensor is capable of producing. - struct E57_DLL ColorLimits - { - double colorRedMinimum{ 0. }; //!< The minimum producible red color value. Unit is unspecified. - double colorRedMaximum{ 0. }; //!< The maximum producible red color value. Unit is unspecified. - double colorGreenMinimum{ 0. }; //!< The minimum producible green color value. Unit is unspecified. - double colorGreenMaximum{ 0. }; //!< The maximum producible green color value. Unit is unspecified. - double colorBlueMinimum{ 0. }; //!< The minimum producible blue color value. Unit is unspecified. - double colorBlueMaximum{ 0. }; //!< The maximum producible blue color value. Unit is unspecified. - - bool operator==( const ColorLimits &rhs ) const - { - return ( colorRedMinimum == rhs.colorRedMinimum ) && ( colorRedMaximum == rhs.colorRedMaximum ) && - ( colorGreenMinimum == rhs.colorGreenMinimum ) && ( colorGreenMaximum == rhs.colorGreenMaximum ) && - ( colorBlueMinimum == rhs.colorBlueMinimum ) && ( colorBlueMaximum == rhs.colorBlueMaximum ); - } - bool operator!=( const ColorLimits &rhs ) const - { - return !operator==( rhs ); - } - }; - - //! @brief Encodes date and time. - //! @details The date and time is encoded using a single floating point number, stored as an E57 Float element which - //! is based on the Global Positioning - //! System (GPS) time scale. - struct E57_DLL DateTime - { - double dateTimeValue{ - 0. - }; //!< The time, in seconds, since GPS time was zero. This time specification may include fractions of a second. - int32_t isAtomicClockReferenced{ - 0 - }; //!< This element should be present, and its value set to 1 if, and only if, the time stored in the - //!< dateTimeValue element is obtained from an atomic clock time source. Shall be either 0 or 1. - - bool operator==( const DateTime &rhs ) const - { - return ( dateTimeValue == rhs.dateTimeValue ) && ( isAtomicClockReferenced == rhs.isAtomicClockReferenced ); - } - bool operator!=( const DateTime &rhs ) const - { - return !operator==( rhs ); - } - }; - - //! @brief Stores the top-level information for the XML section of the file. - struct E57_DLL E57Root - { - ustring formatName; //!< Contains the string "ASTM E57 3D Image File" - ustring guid; //!< A globally unique identification string for the current version of the file - uint32_t versionMajor{ 1 }; //!< Major version number, should be 1 - uint32_t versionMinor{ 0 }; //!< Minor version number, should be 0 - ustring e57LibraryVersion; //!< The version identifier for the E57 file format library that wrote the file. - DateTime creationDateTime; //!< Date/time that the file was created - int64_t data3DSize{ 0 }; //!< Size of the Data3D vector for storing 3D imaging data - int64_t images2DSize{ 0 }; //!< Size of the A heterogeneous Vector of Images2D Structures for storing 2D images - //!< from a camera or similar device. - ustring coordinateMetadata; //!< Information describing the Coordinate Reference System to be used for the file - }; - - //! @brief Stores information about a single group of points in a row or column - struct E57_DLL LineGroupRecord - { - int64_t idElementValue{ - 0 - }; //!< The value of the identifying element of all members in this group. Shall be in the interval [0, 2^63). - int64_t startPointIndex{ - 0 - }; //!< The record number of the first point in the continuous interval. Shall be in the interval [0, 2^63). - int64_t pointCount{ - 0 - }; //!< The number of PointRecords in the group. Shall be in the interval [1, 2^63). May be zero. - CartesianBounds cartesianBounds; //!< The bounding box (in Cartesian coordinates) of all points in the group - //!< (in the local coordinate system of the points). - SphericalBounds sphericalBounds; //!< The bounding region (in spherical coordinates) of all the points in the - //!< group (in the local coordinate system of the points). - }; - - //! @brief Stores a set of point groups organized by the rowIndex or columnIndex attribute of the PointRecord - struct E57_DLL GroupingByLine - { - ustring idElementName; //!< The name of the PointRecord element that identifies which group the point is in. The - //!< value of this string must be "rowIndex" or "columnIndex" - int64_t groupsSize{ 0 }; //!< Size of the groups compressedVector of LineGroupRecord structures - int64_t pointCountSize{ 0 }; //!< This is the size value for the LineGroupRecord::pointCount. - }; - - //! @brief Supports the division of points within an Data3D into logical groupings - struct E57_DLL PointGroupingSchemes - { - GroupingByLine groupingByLine; //!< Grouping information by row or column index - }; - - //! @brief Used to interrogate if standardized fields are available - struct E57_DLL PointStandardizedFieldsAvailable - { - bool cartesianXField{ false }; //!< Indicates that the PointRecord cartesianX field is active - bool cartesianYField{ false }; //!< Indicates that the PointRecord cartesianY field is active - bool cartesianZField{ false }; //!< Indicates that the PointRecord cartesianZ field is active - bool cartesianInvalidStateField{ - false - }; //!< Indicates that the PointRecord cartesianInvalidState field is active - - bool sphericalRangeField{ false }; //!< Indicates that the PointRecord sphericalRange field is active - bool sphericalAzimuthField{ false }; //!< Indicates that the PointRecord sphericalAzimuth field is active - bool sphericalElevationField{ false }; //!< Indicates that the PointRecord sphericalElevation field is active - bool sphericalInvalidStateField{ - false - }; //!< Indicates that the PointRecord sphericalInvalidState field is active - - double pointRangeMinimum{ - E57_FLOAT_MIN - }; //!< Indicates that the PointRecord cartesian and range fields should be configured with this minimum value - //!< -E57_FLOAT_MAX or -E57_DOUBLE_MAX. If using a ScaledIntegerNode then this needs to be a minimum range - //!< value. - double pointRangeMaximum{ - E57_FLOAT_MAX - }; //!< Indicates that the PointRecord cartesian and range fields should be configured with this maximum value - //!< E57_FLOAT_MAX or E57_DOUBLE_MAX. If using a ScaledIntegerNode then this needs to be a maximum range value. - double pointRangeScaledInteger{ - E57_NOT_SCALED_USE_FLOAT - }; //!< Indicates that the PointRecord cartesain and range fields should be configured as a ScaledIntegerNode with - //!< this scale setting. If 0. then use FloatNode. - - double angleMinimum{ - E57_FLOAT_MIN - }; //!< Indicates that the PointRecord angle fields should be configured with this minimum value -E57_FLOAT_MAX or - //!< -E57_DOUBLE_MAX. If using a ScaledIntegerNode then this needs to be a minimum angle value. - double angleMaximum{ - E57_FLOAT_MAX - }; //!< Indicates that the PointRecord angle fields should be configured with this maximum value E57_FLOAT_MAX or - //!< E57_DOUBLE_MAX. If using a ScaledIntegerNode then this needs to be a maximum angle value. - double angleScaledInteger{ - E57_NOT_SCALED_USE_FLOAT - }; //!< Indicates that the PointRecord angle fields should be configured as a ScaledIntegerNode with this scale - //!< setting. If 0. then use FloatNode. - - bool rowIndexField{ false }; //!< Indicates that the PointRecord rowIndex field is active - uint32_t rowIndexMaximum{ E57_UINT32_MAX }; //!< Indicates that the PointRecord index fields should be configured - //!< with this maximum value where the minimum will be set to 0. - bool columnIndexField{ false }; //!< Indicates that the PointRecord columnIndex field is active - uint32_t columnIndexMaximum{ - E57_UINT32_MAX - }; //!< Indicates that the PointRecord index fields should be configured with this maximum value where the minimum - //!< will be set to 0. - - bool returnIndexField{ false }; //!< Indicates that the PointRecord returnIndex field is active - bool returnCountField{ false }; //!< Indicates that the PointRecord returnCount field is active - uint8_t returnMaximum{ E57_UINT8_MAX }; //!< Indicates that the PointRecord return fields should be configured - //!< with this maximum value where the minimum will be set to 0. - - bool timeStampField{ false }; //!< Indicates that the PointRecord timeStamp field is active - bool isTimeStampInvalidField{ false }; //!< Indicates that the PointRecord isTimeStampInvalid field is active - double timeMaximum{ - E57_DOUBLE_MAX - }; //!< Indicates that the PointRecord timeStamp fields should be configured with this maximum value. like - //!< E57_UINT32_MAX, E57_FLOAT_MAX or E57_DOUBLE_MAX - double timeMinimum{ E57_DOUBLE_MIN }; //!< Indicates that the PointRecord timeStamp fields should be configured - //!< with this minimum value -E57_FLOAT_MAX or -E57_DOUBLE_MAX. If using a - //!< ScaledIntegerNode then this needs to be a minimum time value. - double timeScaledInteger{ - E57_NOT_SCALED_USE_FLOAT - }; //!< Indicates that the PointRecord timeStamp fields should be configured as a ScaledIntegerNode with this - //!< scale setting. If 0. then use FloatNode, if -1. use IntegerNode. - - bool intensityField{ false }; //!< Indicates that the PointRecord intensity field is active - bool isIntensityInvalidField{ false }; //!< Indicates that the PointRecord isIntensityInvalid field is active - double intensityScaledInteger{ - E57_NOT_SCALED_USE_INTEGER - }; //!< Indicates that the PointRecord intensity fields should be configured as a ScaledIntegerNode with this - //!< setting. If 0. then use FloatNode, if -1. use IntegerNode - - bool colorRedField{ false }; //!< indicates that the PointRecord colorRed field is active - bool colorGreenField{ false }; //!< indicates that the PointRecord colorGreen field is active - bool colorBlueField{ false }; //!< indicates that the PointRecord colorBlue field is active - bool isColorInvalidField{ false }; //!< Indicates that the PointRecord isColorInvalid field is active - - bool normalX{ false }; //!< Indicates that the PointRecord nor:normalX field is active - bool normalY{ false }; //!< Indicates that the PointRecord nor:normalY field is active - bool normalZ{ false }; //!< Indicates that the PointRecord nor:normalZ field is active - }; - - //! @brief Stores the top-level information for a single lidar scan - struct E57_DLL Data3D - { - ustring name; //!< A user-defined name for the Data3D. - ustring guid; //!< A globally unique identification string for the current version of the Data3D object - std::vector originalGuids; //!< A vector of globally unique identification Strings from which the points - //!< in this Data3D originated. - ustring description; //!< A user-defined description of the Image - - ustring sensorVendor; //!< The name of the manufacturer for the sensor used to collect the points in this Data3D. - ustring sensorModel; //!< The model name or number for the sensor. - ustring sensorSerialNumber; //!< The serial number for the sensor. - ustring sensorHardwareVersion; //!< The version number for the sensor hardware at the time of data collection. - ustring sensorSoftwareVersion; //!< The version number for the software used for the data collection. - ustring sensorFirmwareVersion; //!< The version number for the firmware installed in the sensor at the time of - //!< data collection. - - float temperature{ E57_FLOAT_MAX }; //!< The ambient temperature, measured at the sensor, at the time of data - //!< collection (in degrees Celsius). - float relativeHumidity{ E57_FLOAT_MAX }; //!< The percentage relative humidity, measured at the sensor, at the - //!< time of data collection. Shall be in the interval [0, 100]. - float atmosphericPressure{ E57_FLOAT_MAX }; //!< The atmospheric pressure, measured at the sensor, at the time of - //!< data collection (in Pascals). Shall be positive. - - DateTime acquisitionStart; //!< The start date and time that the data was acquired. - DateTime acquisitionEnd; //!< The end date and time that the data was acquired. - - RigidBodyTransform pose; //!< A rigid body transform that describes the coordinate frame of the 3D imaging - //!< system origin in the file-level coordinate system. - IndexBounds indexBounds; //!< The bounds of the row, column, and return number of all the points in this Data3D. - CartesianBounds cartesianBounds; //!< The bounding region (in cartesian coordinates) of all the points in - //!< this Data3D (in the local coordinate system of the points). - SphericalBounds sphericalBounds; //!< The bounding region (in spherical coordinates) of all the points in - //!< this Data3D (in the local coordinate system of the points). - IntensityLimits - intensityLimits; //!< The limits for the value of signal intensity that the sensor is capable of producing. - ColorLimits colorLimits; //!< The limits for the value of red, green, and blue color that the sensor is - //!< capable of producing. - - PointGroupingSchemes pointGroupingSchemes; //!< The defined schemes that group points in different ways - PointStandardizedFieldsAvailable - pointFields; //!< This defines the active fields used in the WritePoints function. - - int64_t pointsSize{ 0 }; //!< Total size of the compressed vector of PointRecord structures referring to the - //!< binary data that actually stores the point data - }; - - //! @brief Stores pointers to user-provided buffers - template struct Data3DPointsData_t - { - COORDTYPE *cartesianX{ - nullptr - }; //!< pointer to a buffer with the X coordinate (in meters) of the point in Cartesian coordinates - COORDTYPE *cartesianY{ - nullptr - }; //!< pointer to a buffer with the Y coordinate (in meters) of the point in Cartesian coordinates - COORDTYPE *cartesianZ{ - nullptr - }; //!< pointer to a buffer with the Z coordinate (in meters) of the point in Cartesian coordinates - int8_t *cartesianInvalidState{ nullptr }; //!< Value = 0 if the point is considered valid, 1 otherwise - - float *intensity{ nullptr }; //!< pointer to a buffer with the Point response intensity. Unit is unspecified - int8_t *isIntensityInvalid{ nullptr }; //!< Value = 0 if the intensity is considered valid, 1 otherwise - - uint8_t *colorRed{ nullptr }; //!< pointer to a buffer with the Red color coefficient. Unit is unspecified - uint8_t *colorGreen{ nullptr }; //!< pointer to a buffer with the Green color coefficient. Unit is unspecified - uint8_t *colorBlue{ nullptr }; //!< pointer to a buffer with the Blue color coefficient. Unit is unspecified - int8_t *isColorInvalid{ nullptr }; //!< Value = 0 if the color is considered valid, 1 otherwise - - COORDTYPE *sphericalRange{ - nullptr - }; //!< pointer to a buffer with the range (in meters) of points in spherical coordinates. Shall be non-negative - COORDTYPE *sphericalAzimuth{ - nullptr - }; //!< pointer to a buffer with the Azimuth angle (in radians) of point in spherical coordinates - COORDTYPE *sphericalElevation{ - nullptr - }; //!< pointer to a buffer with the Elevation angle (in radians) of point in spherical coordinates - int8_t *sphericalInvalidState{ nullptr }; //!< Value = 0 if the range is considered valid, 1 otherwise - - int32_t *rowIndex{ nullptr }; //!< pointer to a buffer with the row number of point (zero based). This is useful - //!< for data that is stored in a regular grid. Shall be in the interval (0, 2^31). - int32_t *columnIndex{ - nullptr - }; //!< pointer to a buffer with the column number of point (zero based). This is useful for data that is stored - //!< in a regular grid. Shall be in the interval (0, 2^31). - int8_t *returnIndex{ - nullptr - }; //!< pointer to a buffer with the number of this return (zero based). That is, 0 is the first return, 1 is the - //!< second, and so on. Shall be in the interval (0, returnCount). Only for multi-return sensors. - int8_t *returnCount{ - nullptr - }; //!< pointer to a buffer with the total number of returns for the pulse that this corresponds to. Shall be in - //!< the interval (0, 2^7). Only for multi-return sensors. - - double *timeStamp{ - nullptr - }; //!< pointer to a buffer with the time (in seconds) since the start time for the data, which is given by - //!< acquisitionStart in the parent Data3D Structure. Shall be non-negative - int8_t *isTimeStampInvalid{ nullptr }; //!< Value = 0 if the timeStamp is considered valid, 1 otherwise - - // E57_EXT_surface_normals - float *normalX{ nullptr }; //!< The X component of a surface normal vector (E57_EXT_surface_normals). - float *normalY{ nullptr }; //!< The Y component of a surface normal vector (E57_EXT_surface_normals). - float *normalZ{ nullptr }; //!< The Z component of a surface normal vector (E57_EXT_surface_normals). - }; - - typedef Data3DPointsData_t Data3DPointsData; - typedef Data3DPointsData_t Data3DPointsData_d; - - //! @brief Stores an image that is to be used only as a visual reference. - struct E57_DLL VisualReferenceRepresentation - { - int64_t jpegImageSize{ 0 }; //!< Size of JPEG format image data in BlobNode. - int64_t pngImageSize{ 0 }; //!< Size of PNG format image data in BlobNode. - int64_t imageMaskSize{ 0 }; //!< Size of PNG format image mask in BlobNode. - int32_t imageWidth{ 0 }; //!< The image width (in pixels). Shall be positive - int32_t imageHeight{ 0 }; //!< The image height (in pixels). Shall be positive - - bool operator==( const VisualReferenceRepresentation &rhs ) const - { - return ( jpegImageSize == rhs.jpegImageSize ) && ( pngImageSize == rhs.pngImageSize ) && - ( imageMaskSize == rhs.imageMaskSize ) && ( imageWidth == rhs.imageWidth ) && - ( imageHeight == rhs.imageHeight ); - } - bool operator!=( const VisualReferenceRepresentation &rhs ) const - { - return !operator==( rhs ); - } - }; - - //! @brief Stores an image that is mapped from 3D using the pinhole camera projection model. - struct E57_DLL PinholeRepresentation - { - int64_t jpegImageSize{ 0 }; //!< Size of JPEG format image data in BlobNode. - int64_t pngImageSize{ 0 }; //!< Size of PNG format image data in BlobNode. - int64_t imageMaskSize{ 0 }; //!< Size of PNG format image mask in BlobNode. - int32_t imageWidth{ 0 }; //!< The image width (in pixels). Shall be positive - int32_t imageHeight{ 0 }; //!< The image height (in pixels). Shall be positive - double focalLength{ 0. }; //!< The camera's focal length (in meters). Shall be positive - double pixelWidth{ 0. }; //!< The width of the pixels in the camera (in meters). Shall be positive - double pixelHeight{ 0. }; //!< The height of the pixels in the camera (in meters). Shall be positive - double principalPointX{ - 0. - }; //!< The X coordinate in the image of the principal point, (in pixels). The principal point is the intersection - //!< of the z axis of the camera coordinate frame with the image plane. - double principalPointY{ 0. }; //!< The Y coordinate in the image of the principal point (in pixels). - - bool operator==( const PinholeRepresentation &rhs ) const - { - return ( jpegImageSize == rhs.jpegImageSize ) && ( pngImageSize == rhs.pngImageSize ) && - ( imageMaskSize == rhs.imageMaskSize ) && ( imageWidth == rhs.imageWidth ) && - ( imageHeight == rhs.imageHeight ) && ( focalLength == rhs.focalLength ) && - ( pixelWidth == rhs.pixelWidth ) && ( pixelHeight == rhs.pixelHeight ) && - ( principalPointX == rhs.principalPointX ) && ( principalPointY == rhs.principalPointY ); - } - bool operator!=( const PinholeRepresentation &rhs ) const - { - return !operator==( rhs ); - } - }; - - //! @brief Stores an image that is mapped from 3D using a spherical projection model - struct E57_DLL SphericalRepresentation - { - int64_t jpegImageSize{ 0 }; //!< Size of JPEG format image data in BlobNode. - int64_t pngImageSize{ 0 }; //!< Size of PNG format image data in BlobNode. - int64_t imageMaskSize{ 0 }; //!< Size of PNG format image mask in BlobNode. - int32_t imageWidth{ 0 }; //!< The image width (in pixels). Shall be positive - int32_t imageHeight{ 0 }; //!< The image height (in pixels). Shall be positive - double pixelWidth{ 0. }; //!< The width of a pixel in the image (in radians). Shall be positive - double pixelHeight{ 0. }; //!< The height of a pixel in the image (in radians). Shall be positive. - - bool operator==( const SphericalRepresentation &rhs ) const - { - return ( jpegImageSize == rhs.jpegImageSize ) && ( pngImageSize == rhs.pngImageSize ) && - ( imageMaskSize == rhs.imageMaskSize ) && ( imageWidth == rhs.imageWidth ) && - ( imageHeight == rhs.imageHeight ) && ( pixelWidth == rhs.pixelWidth ) && - ( pixelHeight == rhs.pixelHeight ); - } - bool operator!=( const SphericalRepresentation &rhs ) const - { - return !operator==( rhs ); - } - }; - - //! @brief Stores an image that is mapped from 3D using a cylindrical projection model. - struct E57_DLL CylindricalRepresentation - { - int64_t jpegImageSize{ 0 }; //!< Size of JPEG format image data in Blob. - int64_t pngImageSize{ 0 }; //!< Size of PNG format image data in Blob. - int64_t imageMaskSize{ 0 }; //!< Size of PNG format image mask in Blob. - int32_t imageWidth{ 0 }; //!< The image width (in pixels). Shall be positive - int32_t imageHeight{ 0 }; //!< The image height (in pixels). Shall be positive - double pixelWidth{ 0. }; //!< The width of a pixel in the image (in radians). Shall be positive - double pixelHeight{ 0. }; //!< The height of a pixel in the image (in meters). Shall be positive - double radius{ 0. }; //!< The closest distance from the cylindrical image surface to the center of projection - //!< (that is, the radius of the cylinder) (in meters). Shall be non-negative - double principalPointY{ 0. }; //!< The Y coordinate in the image of the principal point (in pixels). This is the - //!< intersection of the z = 0 plane with the image - - bool operator==( const CylindricalRepresentation &rhs ) const - { - return ( jpegImageSize == rhs.jpegImageSize ) && ( pngImageSize == rhs.pngImageSize ) && - ( imageMaskSize == rhs.imageMaskSize ) && ( imageWidth == rhs.imageWidth ) && - ( imageHeight == rhs.imageHeight ) && ( pixelWidth == rhs.pixelWidth ) && - ( pixelHeight == rhs.pixelHeight ) && ( radius == rhs.radius ) && - ( principalPointY == rhs.principalPointY ); - } - bool operator!=( const CylindricalRepresentation &rhs ) const - { - return !operator==( rhs ); - } - }; - - //! @brief Stores an image from a camera - struct E57_DLL Image2D - { - ustring name; //!< A user-defined name for the Image2D. - ustring guid; //!< A globally unique identification string for the current version of the Image2D object - ustring description; //!< A user-defined description of the Image2D - DateTime acquisitionDateTime; //!< The date and time that the image was taken - - ustring associatedData3DGuid; //!< The globally unique identification string (guid element) for the Data3D that - //!< was being acquired when the picture was taken - - ustring sensorVendor; //!< The name of the manufacturer for the sensor used to collect the points in this Data3D. - ustring sensorModel; //!< The model name or number for the sensor. - ustring sensorSerialNumber; //!< The serial number for the sensor. - - RigidBodyTransform pose; //!< A rigid body transform that describes the coordinate frame of the camera in the - //!< file-level coordinate system - - VisualReferenceRepresentation - visualReferenceRepresentation; //!< Representation for an image that does not define any camera projection - //!< model. The image is to be used for visual reference only - PinholeRepresentation - pinholeRepresentation; //!< Representation for an image using the pinhole camera projection model - SphericalRepresentation - sphericalRepresentation; //!< Representation for an image using the spherical camera projection model. - CylindricalRepresentation - cylindricalRepresentation; //!< Representation for an image using the cylindrical camera projection model - }; - - //! @brief Identifies the format representation for the image data - enum Image2DType - { - E57_NO_IMAGE = 0, //!< No image data - E57_JPEG_IMAGE = 1, //!< JPEG format image data. - E57_PNG_IMAGE = 2, //!< PNG format image data. - E57_PNG_IMAGE_MASK = 3 //!< PNG format image mask. - }; - - //! @brief Identifies the representation for the image data - enum Image2DProjection - { - E57_NO_PROJECTION = 0, //!< No representation for the image data is present - E57_VISUAL = 1, //!< VisualReferenceRepresentation for the image data - E57_PINHOLE = 2, //!< PinholeRepresentation for the image data - E57_SPHERICAL = 3, //!< SphericalRepresentation for the image data - E57_CYLINDRICAL = 4 //!< CylindricalRepresentation for the image data - }; - -} // end namespace e57 diff --git a/src/3rdParty/libE57Format/include/E57SimpleReader.h b/src/3rdParty/libE57Format/include/E57SimpleReader.h deleted file mode 100644 index a79afb9a39..0000000000 --- a/src/3rdParty/libE57Format/include/E57SimpleReader.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * E57Simple - public header of E57 Simple API for reading/writing .e57 files. - * - * Copyright (c) 2010 Stan Coleby (scoleby@intelisum.com) - * Copyright (c) 2020 PTC Inc. - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -//! @file E57SimpleReader.h E57 Simple API for reading E57 - -#include "E57SimpleData.h" - -namespace e57 -{ - - //! @brief Used for reading of the E57 file with E57 Simple API - class E57_DLL Reader - { - public: - //! @brief This function is the constructor for the reader class - //! @param [in] filePath file path to E57 file - Reader( const ustring &filePath ); - //! @brief This function returns true if the file is open - bool IsOpen() const; - - //! @brief This function closes the file - bool Close(); - - //! @name File information - //!@{ - - //! @brief This function returns the file header information - //! @param [out] fileHeader is the main header information - //! @return Returns true if successful - bool GetE57Root( E57Root &fileHeader ) const; - - //!@} - - //! @name Image2D - //!@{ - - //! @brief This function returns the total number of Picture Blocks - //! @return Returns the number of Image2D blocks - int64_t GetImage2DCount() const; - - //! @brief This function returns the image2D header and positions the cursor - //! @param [in] imageIndex This in the index into the image2D vector - //! @param [out] image2DHeader pointer to the Image2D structure to receive the picture information - //! @return Returns true if successful - bool ReadImage2D( int64_t imageIndex, Image2D &image2DHeader ) const; - - //! @brief This function returns the size of the image data - //! @param [in] imageIndex This in the index into the image2D vector - //! @param [out] imageProjection identifies the projection in the image2D. - //! @param [out] imageType identifies the image format of the projection. - //! @param [out] imageWidth The image width (in pixels). - //! @param [out] imageHeight The image height (in pixels). - //! @param [out] imageSize This is the total number of bytes for the image blob. - //! @param [out] imageMaskType This is E57_PNG_IMAGE_MASK if "imageMask" is defined in the projection - //! @param [out] imageVisualType This is image type of the VisualReferenceRepresentation if given. - //! @return Returns true if successful - bool GetImage2DSizes( int64_t imageIndex, Image2DProjection &imageProjection, Image2DType &imageType, - int64_t &imageWidth, int64_t &imageHeight, int64_t &imageSize, Image2DType &imageMaskType, - Image2DType &imageVisualType ) const; - - //! @brief This function reads an image - //! @param [in] imageIndex index of the image. Must be less than GetImage2DCount() - //! @param [in] imageProjection identifies the projection desired. - //! @param [in] imageType identifies the image format desired. - //! @param [out] buffer pointer the raw image buffer - //! @param [in] start position in the block to start reading - //! @param [in] count size of desired chuck or buffer size - //! @return Returns the number of bytes transferred. - int64_t ReadImage2DData( int64_t imageIndex, Image2DProjection imageProjection, Image2DType imageType, - void *buffer, int64_t start, int64_t count ) const; - - //!@} - - //! @name Data3D - //!@{ - - //! @brief This function returns the total number of Data3D Blocks - //! @return Returns number of Data3D blocks. - int64_t GetData3DCount() const; - - //! @brief This function returns the Data3D header - //! @param [in] dataIndex This in the index into the images3D vector. Must be less than GetData3DCount(). - //! @param [out] data3DHeader Data3D header - //! @return Returns true if successful - bool ReadData3D( int64_t dataIndex, Data3D &data3DHeader ) const; - - //! @brief This function returns the size of the point data - //! @param [in] dataIndex This in the index into the images3D vector. Must be less than GetData3DCount(). - //! @param [out] rowMax This is the maximum row size - //! @param [out] columnMax This is the maximum column size - //! @param [out] pointsSize This is the total number of point records - //! @param [out] groupsSize This is the total number of group reocrds - //! @param [out] countSize This is the maximum point count per group - //! @param [out] columnIndex This indicates that the idElementName is "columnIndex" - //! @return Return true if successful, false otherwise - bool GetData3DSizes( int64_t dataIndex, int64_t &rowMax, int64_t &columnMax, int64_t &pointsSize, - int64_t &groupsSize, int64_t &countSize, bool &columnIndex ) const; - - //! @brief This function reads the group data into the provided buffers. - //! @param [in] dataIndex This in the index into the images3D vector. Must be less than GetData3DCount(). - //! @param [in] groupCount size of each of the buffers given - //! @param [out] idElementValue pointer to the buffer holding indices index for this group - //! @param [out] startPointIndex pointer to the buffer holding Starting index in to the "points" data vector for - //! the groups - //! @param [out] pointCount pointer to the buffer holding size of the groups given - //! @return Return true if successful, false otherwise - bool ReadData3DGroupsData( int64_t dataIndex, int64_t groupCount, int64_t *idElementValue, - int64_t *startPointIndex, int64_t *pointCount ) const; - - //! @brief Use this function to read the actual 3D data - //! @details All the non-NULL buffers in buffers have number of elements = pointCount. - //! Call the CompressedVectorReader::read() until all data is read. - //! @param [in] dataIndex data block index given by the NewData3D - //! @param [in] pointCount size of each element buffer. - //! @param [in] buffers pointers to user-provided buffers - //! @return vector reader setup to read the selected data into the provided buffers - CompressedVectorReader SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData &buffers ) const; - - //! @brief Use this function to read the actual 3D data - //! @details All the non-NULL buffers in buffers have number of elements = pointCount. - //! Call the CompressedVectorReader::read() until all data is read. - //! @param [in] dataIndex data block index given by the NewData3D - //! @param [in] pointCount size of each element buffer. - //! @param [in] buffers pointers to user-provided buffers - //! @return vector reader setup to read the selected data into the provided buffers - CompressedVectorReader SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData_d &buffers ) const; - - //!@} - - //! @name Foundation API file information - //!@{ - - //! @brief Returns the file raw E57Root Structure Node - StructureNode GetRawE57Root() const; - - //! @brief Returns the raw Data3D Vector Node - VectorNode GetRawData3D() const; - - //! @brief Returns the raw Image2D Vector Node - VectorNode GetRawImages2D() const; - - //! @brief Returns the ram ImageFile Node which is need to add enhancements - ImageFile GetRawIMF() const; - - //!@} - - //! @cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - protected: - friend class ReaderImpl; - - E57_OBJECT_IMPLEMENTATION( Reader ) // Internal implementation details, not part of API, must be last in object - //! @endcond - }; // end Reader class - -} // end namespace e57 diff --git a/src/3rdParty/libE57Format/include/E57SimpleWriter.h b/src/3rdParty/libE57Format/include/E57SimpleWriter.h deleted file mode 100644 index 32c5a0a2a6..0000000000 --- a/src/3rdParty/libE57Format/include/E57SimpleWriter.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * E57Simple - public header of E57 Simple API for reading/writing .e57 files. - * - * Copyright (c) 2010 Stan Coleby (scoleby@intelisum.com) - * Copyright (c) 2020 PTC Inc. - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -//! @file E57SimpleWriter.h E57 Simple API for writing E57 - -#include "E57SimpleData.h" - -namespace e57 -{ - - //! @brief Used for writing of the E57 file with E57 Simple API - class E57_DLL Writer - { - public: - //! @brief This function is the constructor for the writer class - //! @param [in] filePath file path to E57 file - //! @param [in] coordinateMetaData Information describing the Coordinate Reference System to be used for the file - Writer( const ustring &filePath, const ustring &coordinateMetaData = {} ); - - //! @brief This function returns true if the file is open - bool IsOpen() const; - - //! @brief This function closes the file - bool Close(); - - //! @name Image2D - //!@{ - - //! @brief This function writes a new Image2D header - //! @details The user needs to config a Image2D structure with all the camera information before making this call. - //! @param [in,out] image2DHeader header metadata - //! @return Returns the image2D index - int64_t NewImage2D( Image2D &image2DHeader ); - - //! @brief This function writes the actual image data - //! @param [in] imageIndex picture block index given by the NewImage2D - //! @param [in] imageType identifies the image format desired. - //! @param [in] imageProjection identifies the projection desired. - //! @param [in] buffer pointer the buffer - //! @param [in] start position in the block to start writing - //! @param [in] count size of desired chuck or buffer size - //! @return Returns the number of bytes written - int64_t WriteImage2DData( int64_t imageIndex, Image2DType imageType, Image2DProjection imageProjection, - void *buffer, int64_t start, int64_t count ); - - //!@} - - //! @name Data3D - //!@{ - - //! @brief This function writes new Data3D header - //! @details The user needs to config a Data3D structure with all the scanning information before making this - //! call. - //! @param [in,out] data3DHeader scan metadata - //! @return Returns the index of the new scan's data3D block. - int64_t NewData3D( Data3D &data3DHeader ); - - //! @brief This function setups a writer to write the actual scan data - //! @param [in] dataIndex index returned by NewData3D - //! @param [in] pointCount Number of points to write (number of elements in each of the buffers) - //! @param [in] buffers pointers to user-provided buffers - //! @return returns a vector writer setup to write the selected scan data - CompressedVectorWriter SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData &buffers ); - - //! @brief This function setups a writer to write the actual scan data - //! @param [in] dataIndex index returned by NewData3D - //! @param [in] pointCount Number of points to write (number of elements in each of the buffers) - //! @param [in] buffers pointers to user-provided buffers - //! @return returns a vector writer setup to write the selected scan data - CompressedVectorWriter SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData_d &buffers ); - - //! @brief This function writes out the group data - //! @param [in] dataIndex data block index given by the NewData3D - //! @param [in] groupCount size of each of the buffers given - //! @param [in] buffer of idElementValue index for this group - //! @param [in] startPointIndex buffer with starting indices in to the "points" data vector for the groups - //! @param [in] pointCount buffer with sizes of the groups given - //! @return Return true if successful, false otherwise - bool WriteData3DGroupsData( int64_t dataIndex, int64_t groupCount, int64_t *idElementValue, - int64_t *startPointIndex, int64_t *pointCount ); - - //!@} - - //! @name Foundation API file information - //!@{ - - //! @brief This function returns the file raw E57Root Structure Node - StructureNode GetRawE57Root(); - //! @brief This function returns the raw Data3D Vector Node - VectorNode GetRawData3D(); - //! @brief This function returns the raw Image2D Vector Node - VectorNode GetRawImages2D(); - //! @brief This function returns the ram ImageFile Node which is need to add enhancements - ImageFile GetRawIMF(); - - //!@} - - //! @cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - protected: - friend class WriterImpl; - - E57_OBJECT_IMPLEMENTATION( Writer ) // Internal implementation details, not part of API, must be last in object - //! @endcond - }; // end Writer class - -} // end namespace e57 diff --git a/src/3rdParty/libE57Format/src/BlobNodeImpl.cpp b/src/3rdParty/libE57Format/src/BlobNodeImpl.cpp deleted file mode 100644 index e3187310d6..0000000000 --- a/src/3rdParty/libE57Format/src/BlobNodeImpl.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "BlobNodeImpl.h" -#include "CheckedFile.h" -#include "ImageFileImpl.h" -#include "SectionHeaders.h" - -namespace e57 -{ - BlobNodeImpl::BlobNodeImpl( ImageFileImplWeakPtr destImageFile, int64_t byteCount ) : NodeImpl( destImageFile ) - { - // don't checkImageFileOpen, NodeImpl() will do it - - ImageFileImplSharedPtr imf( destImageFile ); - - /// This what caller thinks blob length is - blobLogicalLength_ = byteCount; - - /// Round segment length up to multiple of 4 bytes - binarySectionLogicalLength_ = sizeof( BlobSectionHeader ) + blobLogicalLength_; - unsigned remainder = binarySectionLogicalLength_ % 4; - if ( remainder > 0 ) - { - binarySectionLogicalLength_ += 4 - remainder; - } - - /// Reserve space for blob in file, extend with zeros since writes will - /// happen at later time by caller - binarySectionLogicalStart_ = imf->allocateSpace( binarySectionLogicalLength_, true ); - - /// Prepare BlobSectionHeader - BlobSectionHeader header; - header.sectionLogicalLength = binarySectionLogicalLength_; -#ifdef E57_MAX_VERBOSE - header.dump(); //??? -#endif - - /// Write header at beginning of section - imf->file_->seek( binarySectionLogicalStart_ ); - imf->file_->write( reinterpret_cast( &header ), sizeof( header ) ); - } - - BlobNodeImpl::BlobNodeImpl( ImageFileImplWeakPtr destImageFile, int64_t fileOffset, int64_t length ) : - NodeImpl( destImageFile ) - { - /// Init blob object that already exists in E57 file currently reading. - - // don't checkImageFileOpen, NodeImpl() will do it - - ImageFileImplSharedPtr imf( destImageFile ); - - /// Init state from values read from XML - blobLogicalLength_ = length; - binarySectionLogicalStart_ = imf->file_->physicalToLogical( fileOffset ); - binarySectionLogicalLength_ = sizeof( BlobSectionHeader ) + blobLogicalLength_; - } - - bool BlobNodeImpl::isTypeEquivalent( NodeImplSharedPtr ni ) - { - // don't checkImageFileOpen, NodeImpl() will do it - - /// Same node type? - if ( ni->type() != E57_BLOB ) - { - return ( false ); - } - - /// Downcast to shared_ptr - std::shared_ptr bi( std::static_pointer_cast( ni ) ); - - /// blob lengths must match - if ( blobLogicalLength_ != bi->blobLogicalLength_ ) - { - return ( false ); - } - - /// ignore blob contents, doesn't have to match - - /// Types match - return ( true ); - } - - bool BlobNodeImpl::isDefined( const ustring &pathName ) - { - // don't checkImageFileOpen, NodeImpl() will do it - - /// We have no sub-structure, so if path not empty return false - return pathName.empty(); - } - - int64_t BlobNodeImpl::byteCount() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( blobLogicalLength_ ); - } - - void BlobNodeImpl::read( uint8_t *buf, int64_t start, size_t count ) - { - //??? check start not negative - - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - if ( static_cast( start ) + count > blobLogicalLength_ ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_API_ARGUMENT, - "this->pathName=" + this->pathName() + " start=" + toString( start ) + - " count=" + toString( count ) + " length=" + toString( blobLogicalLength_ ) ); - } - - ImageFileImplSharedPtr imf( destImageFile_ ); - imf->file_->seek( binarySectionLogicalStart_ + sizeof( BlobSectionHeader ) + start ); - imf->file_->read( reinterpret_cast( buf ), - static_cast( count ) ); //??? arg1 void* ? - } - - void BlobNodeImpl::write( uint8_t *buf, int64_t start, size_t count ) - { - //??? check start not negative - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - ImageFileImplSharedPtr destImageFile( destImageFile_ ); - - if ( !destImageFile->isWriter() ) - { - throw E57_EXCEPTION2( E57_ERROR_FILE_IS_READ_ONLY, "fileName=" + destImageFile->fileName() ); - } - if ( !isAttached() ) - { - throw E57_EXCEPTION2( E57_ERROR_NODE_UNATTACHED, "fileName=" + destImageFile->fileName() ); - } - - if ( static_cast( start ) + count > blobLogicalLength_ ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_API_ARGUMENT, - "this->pathName=" + this->pathName() + " start=" + toString( start ) + - " count=" + toString( count ) + " length=" + toString( blobLogicalLength_ ) ); - } - - ImageFileImplSharedPtr imf( destImageFile_ ); - imf->file_->seek( binarySectionLogicalStart_ + sizeof( BlobSectionHeader ) + start ); - imf->file_->write( reinterpret_cast( buf ), - static_cast( count ) ); //??? arg1 void* ? - } - - void BlobNodeImpl::checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) - { - // don't checkImageFileOpen - - /// We are a leaf node, so verify that we are listed in set. ???true for - /// blobs? what exception get if try blob in compressedvector? - if ( pathNames.find( relativePathName( origin ) ) == pathNames.end() ) - { - throw E57_EXCEPTION2( E57_ERROR_NO_BUFFER_FOR_ELEMENT, "this->pathName=" + this->pathName() ); - } - } - - void BlobNodeImpl::writeXml( ImageFileImplSharedPtr /*imf*/, CheckedFile &cf, int indent, - const char *forcedFieldName ) - { - // don't checkImageFileOpen - - ustring fieldName; - if ( forcedFieldName ) - { - fieldName = forcedFieldName; - } - else - { - fieldName = elementName_; - } - - //??? need to implement - //??? Type --> type - //??? need to have length?, check same as in section header? - uint64_t physicalOffset = cf.logicalToPhysical( binarySectionLogicalStart_ ); - cf << space( indent ) << "<" << fieldName << " type=\"Blob\" fileOffset=\"" << physicalOffset << "\" length=\"" - << blobLogicalLength_ << "\"/>\n"; - } - -#ifdef E57_DEBUG - void BlobNodeImpl::dump( int indent, std::ostream &os ) const - { - // don't checkImageFileOpen - os << space( indent ) << "type: Blob" - << " (" << type() << ")" << std::endl; - NodeImpl::dump( indent, os ); - os << space( indent ) << "blobLogicalLength_: " << blobLogicalLength_ << std::endl; - os << space( indent ) << "binarySectionLogicalStart: " << binarySectionLogicalStart_ << std::endl; - os << space( indent ) << "binarySectionLogicalLength: " << binarySectionLogicalLength_ << std::endl; - // size_t i; - // for (i = 0; i < blobLogicalLength_ && i < 10; i++) { - // uint8_t b; - // read(&b, i, 1); - // os << space(indent) << "data[" << i << "]: "<< static_cast(b) - // << std::endl; - // } - // if (i < blobLogicalLength_) - // os << space(indent) << "more data unprinted..." << std::endl; - } -#endif - -} diff --git a/src/3rdParty/libE57Format/src/BlobNodeImpl.h b/src/3rdParty/libE57Format/src/BlobNodeImpl.h deleted file mode 100644 index 8364d9fb0a..0000000000 --- a/src/3rdParty/libE57Format/src/BlobNodeImpl.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "NodeImpl.h" - -namespace e57 -{ - class BlobNodeImpl : public NodeImpl - { - public: - BlobNodeImpl( ImageFileImplWeakPtr destImageFile, int64_t byteCount ); - BlobNodeImpl( ImageFileImplWeakPtr destImageFile, int64_t fileOffset, int64_t length ); - ~BlobNodeImpl() override = default; - - NodeType type() const override - { - return E57_BLOB; - } - bool isTypeEquivalent( NodeImplSharedPtr ni ) override; - bool isDefined( const ustring &pathName ) override; - - int64_t byteCount(); - void read( uint8_t *buf, int64_t start, size_t count ); - void write( uint8_t *buf, int64_t start, size_t count ); - - void checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) override; - - void writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, - const char *forcedFieldName = nullptr ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - - private: - uint64_t blobLogicalLength_; - uint64_t binarySectionLogicalStart_; - uint64_t binarySectionLogicalLength_; - }; -} diff --git a/src/3rdParty/libE57Format/src/CMakeLists.txt b/src/3rdParty/libE57Format/src/CMakeLists.txt deleted file mode 100644 index b9b8d2bb16..0000000000 --- a/src/3rdParty/libE57Format/src/CMakeLists.txt +++ /dev/null @@ -1,63 +0,0 @@ -# SPDX-License-Identifier: MIT -# Copyright 2020 Andy Maloney - -target_sources( E57Format - PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/BlobNodeImpl.h - ${CMAKE_CURRENT_LIST_DIR}/BlobNodeImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/CheckedFile.h - ${CMAKE_CURRENT_LIST_DIR}/CheckedFile.cpp - ${CMAKE_CURRENT_LIST_DIR}/Common.h - ${CMAKE_CURRENT_LIST_DIR}/Common.cpp - ${CMAKE_CURRENT_LIST_DIR}/CompressedVectorNodeImpl.h - ${CMAKE_CURRENT_LIST_DIR}/CompressedVectorNodeImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/CompressedVectorReaderImpl.h - ${CMAKE_CURRENT_LIST_DIR}/CompressedVectorReaderImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/CompressedVectorWriterImpl.h - ${CMAKE_CURRENT_LIST_DIR}/CompressedVectorWriterImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/DecodeChannel.h - ${CMAKE_CURRENT_LIST_DIR}/DecodeChannel.cpp - ${CMAKE_CURRENT_LIST_DIR}/Decoder.h - ${CMAKE_CURRENT_LIST_DIR}/Decoder.cpp - ${CMAKE_CURRENT_LIST_DIR}/Encoder.h - ${CMAKE_CURRENT_LIST_DIR}/Encoder.cpp - ${CMAKE_CURRENT_LIST_DIR}/FloatNodeImpl.h - ${CMAKE_CURRENT_LIST_DIR}/FloatNodeImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/IntegerNodeImpl.h - ${CMAKE_CURRENT_LIST_DIR}/IntegerNodeImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/NodeImpl.h - ${CMAKE_CURRENT_LIST_DIR}/NodeImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/Packet.h - ${CMAKE_CURRENT_LIST_DIR}/Packet.cpp - ${CMAKE_CURRENT_LIST_DIR}/ImageFileImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/ImageFileImpl.h - ${CMAKE_CURRENT_LIST_DIR}/ReaderImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/ReaderImpl.h - ${CMAKE_CURRENT_LIST_DIR}/ScaledIntegerNodeImpl.h - ${CMAKE_CURRENT_LIST_DIR}/ScaledIntegerNodeImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/SectionHeaders.h - ${CMAKE_CURRENT_LIST_DIR}/SectionHeaders.cpp - ${CMAKE_CURRENT_LIST_DIR}/SourceDestBufferImpl.h - ${CMAKE_CURRENT_LIST_DIR}/SourceDestBufferImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/StringNodeImpl.h - ${CMAKE_CURRENT_LIST_DIR}/StringNodeImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/StructureNodeImpl.h - ${CMAKE_CURRENT_LIST_DIR}/StructureNodeImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/VectorNodeImpl.h - ${CMAKE_CURRENT_LIST_DIR}/VectorNodeImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/WriterImpl.cpp - ${CMAKE_CURRENT_LIST_DIR}/WriterImpl.h - ${CMAKE_CURRENT_LIST_DIR}/E57Exception.cpp - ${CMAKE_CURRENT_LIST_DIR}/E57Format.cpp - ${CMAKE_CURRENT_LIST_DIR}/E57SimpleData.cpp - ${CMAKE_CURRENT_LIST_DIR}/E57SimpleReader.cpp - ${CMAKE_CURRENT_LIST_DIR}/E57SimpleWriter.cpp - ${CMAKE_CURRENT_LIST_DIR}/E57Version.h - ${CMAKE_CURRENT_LIST_DIR}/E57XmlParser.cpp - ${CMAKE_CURRENT_LIST_DIR}/E57XmlParser.h -) - -target_include_directories( E57Format - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} -) diff --git a/src/3rdParty/libE57Format/src/CheckedFile.cpp b/src/3rdParty/libE57Format/src/CheckedFile.cpp deleted file mode 100644 index 857167623c..0000000000 --- a/src/3rdParty/libE57Format/src/CheckedFile.cpp +++ /dev/null @@ -1,803 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -// convenience for all the BSDs -#if defined( __FreeBSD__) || defined( __NetBSD__) || defined( __OpenBSD__) -#define __BSD -#endif - -#if defined( _WIN32 ) -#if defined( _MSC_VER ) -#include -#include -#elif defined( __GNUC__ ) -#define _LARGEFILE64_SOURCE -#define __LARGE64_FILES -#include -#include -#include -#else -#error "no supported compiler defined" -#endif -#elif defined( __linux__ ) -#define _LARGEFILE64_SOURCE -#define __LARGE64_FILES -#include -#include -#include -#elif defined(__BSD) -#include -#include -#include -#elif defined( __APPLE__ ) -#include -#include -#else -#error "no supported OS platform defined" -#endif - -#include -#include -#include -#include - -#include "CRC.h" - -#include "CheckedFile.h" - -//#define E57_CHECK_FILE_DEBUG -#ifdef E57_CHECK_FILE_DEBUG -#include -#endif - -#ifndef O_BINARY -constexpr int O_BINARY = 0; -#endif - -using namespace e57; - -// These extra definitions are required in C++11. -// In C++17, "static constexpr" is implicitly inline, so these are not required. -constexpr size_t CheckedFile::physicalPageSizeLog2; -constexpr size_t CheckedFile::physicalPageSize; -constexpr uint64_t CheckedFile::physicalPageSizeMask; -constexpr size_t CheckedFile::logicalPageSize; - -/// Tool class to read buffer efficiently without -/// multiplying copy operations. -/// -/// WARNING: pointer input is handled by user! -class e57::BufferView -{ -public: - /// @param[IN] input: filled buffer owned by caller. - /// @param[IN] size: size of input - BufferView( const char *input, uint64_t size ) : streamSize_( size ), stream_( input ) - { - } - - uint64_t pos() const - { - return cursorStream_; - } - - bool seek( uint64_t offset, int whence ) - { - if ( whence == SEEK_CUR ) - { - cursorStream_ += offset; - } - else if ( whence == SEEK_SET ) - { - cursorStream_ = offset; - } - else if ( whence == SEEK_END ) - { - cursorStream_ = streamSize_ - offset; - } - - if ( cursorStream_ > streamSize_ ) - { - cursorStream_ = streamSize_; - return false; - } - - return true; - } - - void read( char *buffer, uint64_t count ) - { - const uint64_t start = cursorStream_; - for ( uint64_t i = 0; i < count; ++i ) - { - buffer[i] = stream_[start + i]; - ++cursorStream_; - } - } - -private: - const uint64_t streamSize_; - uint64_t cursorStream_ = 0; - const char *stream_; -}; - -CheckedFile::CheckedFile( const ustring &fileName, Mode mode, ReadChecksumPolicy policy ) : - fileName_( fileName ), checkSumPolicy_( policy ) -{ - switch ( mode ) - { - case ReadOnly: - fd_ = open64( fileName_, O_RDONLY | O_BINARY, 0 ); - - readOnly_ = true; - - physicalLength_ = lseek64( 0LL, SEEK_END ); - lseek64( 0, SEEK_SET ); - - logicalLength_ = physicalToLogical( physicalLength_ ); - break; - - case WriteCreate: - /// File truncated to zero length if already exists - fd_ = open64( fileName_, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IWRITE | S_IREAD ); - break; - - case WriteExisting: - fd_ = open64( fileName_, O_RDWR | O_BINARY, 0 ); - - logicalLength_ = physicalToLogical( length( Physical ) ); //??? - break; - } -} - -CheckedFile::CheckedFile( const char *input, uint64_t size, ReadChecksumPolicy policy ) : - fileName_( "" ), checkSumPolicy_( policy ) -{ - bufView_ = new BufferView( input, size ); - - readOnly_ = true; - - physicalLength_ = lseek64( 0LL, SEEK_END ); - lseek64( 0, SEEK_SET ); - - logicalLength_ = physicalToLogical( physicalLength_ ); -} - -int CheckedFile::open64( const ustring &fileName, int flags, int mode ) -{ -#if defined( _MSC_VER ) - // Handle UTF-8 file names - Windows requires conversion to UTF-16 - std::wstring_convert> converter; - std::wstring widePath = converter.from_bytes( fileName ); - - int handle; - int err = _wsopen_s( &handle, widePath.c_str(), flags, _SH_DENYNO, mode ); - if ( handle < 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_OPEN_FAILED, "err=" + toString( err ) + " fileName=" + fileName + - " flags=" + toString( flags ) + " mode=" + toString( mode ) ); - } - return handle; -#elif defined( __GNUC__ ) - int result = ::open( fileName_.c_str(), flags, mode ); - if ( result < 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_OPEN_FAILED, "result=" + toString( result ) + " fileName=" + fileName + - " flags=" + toString( flags ) + " mode=" + toString( mode ) ); - } - return result; -#else -#error "no supported compiler defined" -#endif -} - -CheckedFile::~CheckedFile() -{ - try - { - close(); ///??? what if already closed? - } - catch ( ... ) - { - //??? report? - } -} - -void CheckedFile::read( char *buf, size_t nRead, size_t /*bufSize*/ ) -{ - //??? what if read past logical end?, or physical end? - //??? need to keep track of logical length? - //??? check bufSize OK - - const uint64_t end = position( Logical ) + nRead; - const uint64_t logicalLength = length( Logical ); - - if ( end > logicalLength ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "fileName=" + fileName_ + " end=" + toString( end ) + - " length=" + toString( logicalLength ) ); - } - - uint64_t page = 0; - size_t pageOffset = 0; - - getCurrentPageAndOffset( page, pageOffset ); - - size_t n = std::min( nRead, logicalPageSize - pageOffset ); - - /// Allocate temp page buffer - std::vector page_buffer_v( physicalPageSize ); - char *page_buffer = &page_buffer_v[0]; - - const auto checksumMod = static_cast( std::nearbyint( 100.0 / checkSumPolicy_ ) ); - - while ( nRead > 0 ) - { - readPhysicalPage( page_buffer, page ); - - switch ( checkSumPolicy_ ) - { - case CHECKSUM_POLICY_NONE: - break; - - case CHECKSUM_POLICY_ALL: - verifyChecksum( page_buffer, page ); - break; - - default: - if ( !( page % checksumMod ) || ( nRead < physicalPageSize ) ) - { - verifyChecksum( page_buffer, page ); - } - break; - } - - memcpy( buf, page_buffer + pageOffset, n ); - - buf += n; - nRead -= n; - pageOffset = 0; - ++page; - - n = std::min( nRead, logicalPageSize ); - } - - /// When done, leave cursor just past end of last byte read - seek( end, Logical ); -} - -void CheckedFile::write( const char *buf, size_t nWrite ) -{ -#ifdef E57_MAX_VERBOSE - // cout << "write nWrite=" << nWrite << " position()="<< position() << std::endl; - // //??? -#endif - if ( readOnly_ ) - { - throw E57_EXCEPTION2( E57_ERROR_FILE_IS_READ_ONLY, "fileName=" + fileName_ ); - } - - uint64_t end = position( Logical ) + nWrite; - - uint64_t page = 0; - size_t pageOffset = 0; - - getCurrentPageAndOffset( page, pageOffset ); - - size_t n = std::min( nWrite, logicalPageSize - pageOffset ); - - /// Allocate temp page buffer - std::vector page_buffer_v( physicalPageSize ); - char *page_buffer = &page_buffer_v[0]; - - while ( nWrite > 0 ) - { - const uint64_t physicalLength = length( Physical ); - - if ( page * physicalPageSize < physicalLength ) - { - readPhysicalPage( page_buffer, page ); - } - -#ifdef E57_MAX_VERBOSE - // cout << " page_buffer[0] read: '" << page_buffer[0] << "'" << std::endl; - // cout << "copy " << n << "bytes to page=" << page << " pageOffset=" << - // pageOffset << " buf='"; //??? for (size_t i=0; i < n; i++) cout << - // buf[i]; cout << "'" << std::endl; -#endif - memcpy( page_buffer + pageOffset, buf, n ); - writePhysicalPage( page_buffer, page ); -#ifdef E57_MAX_VERBOSE - // cout << " page_buffer[0] after write: '" << page_buffer[0] << "'" << - // std::endl; //??? -#endif - buf += n; - nWrite -= n; - pageOffset = 0; - page++; - n = std::min( nWrite, logicalPageSize ); - } - - if ( end > logicalLength_ ) - { - logicalLength_ = end; - } - - /// When done, leave cursor just past end of buf - seek( end, Logical ); -} - -CheckedFile &CheckedFile::operator<<( const ustring &s ) -{ - write( s.c_str(), s.length() ); //??? should be times size of uchar? - return ( *this ); -} - -CheckedFile &CheckedFile::operator<<( int64_t i ) -{ - std::stringstream ss; - ss << i; - return ( *this << ss.str() ); -} - -CheckedFile &CheckedFile::operator<<( uint64_t i ) -{ - std::stringstream ss; - ss << i; - return ( *this << ss.str() ); -} - -CheckedFile &CheckedFile::operator<<( float f ) -{ - //??? is 7 digits right number? - return writeFloatingPoint( f, 7 ); -} - -CheckedFile &CheckedFile::operator<<( double d ) -{ - //??? is 17 digits right number? - return writeFloatingPoint( d, 17 ); -} - -template CheckedFile &CheckedFile::writeFloatingPoint( FTYPE value, int precision ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "CheckedFile::writeFloatingPoint, value=" << value << " precision=" << precision << std::endl; -#endif - - std::stringstream ss; - ss << std::scientific << std::setprecision( precision ) << value; - - /// Try to remove trailing zeroes and decimal point - /// E.g. 1.23456000000000000e+005 ==> 1.23456e+005 - /// E.g. 2.00000000000000000e+005 ==> 2e+005 - - ustring s = ss.str(); - const size_t len = s.length(); - -#ifdef E57_MAX_DEBUG - ustring old_s = s; -#endif - - /// Split into mantissa and exponent - /// E.g. 1.23456000000000000e+005 ==> "1.23456000000000000" + "e+005" - ustring mantissa = s.substr( 0, len - 5 ); - ustring exponent = s.substr( len - 5, 5 ); - - /// Double check that we understand the formatting - if ( exponent[0] == 'e' ) - { - /// Trim of any trailing zeros in mantissa - while ( mantissa[mantissa.length() - 1] == '0' ) - { - mantissa = mantissa.substr( 0, mantissa.length() - 1 ); - } - - /// Make one attempt to trim off trailing decimal point - if ( mantissa[mantissa.length() - 1] == '.' ) - { - mantissa = mantissa.substr( 0, mantissa.length() - 1 ); - } - - /// Reassemble whole floating point number - /// Check if can drop exponent. - if ( exponent == "e+000" ) - { - s = mantissa; - } - else - { - s = mantissa + exponent; - } - } - - // Disable these checks because they compare floats using "!=" which is - // invalid -#if 0 // E57_MAX_DEBUG - /// Double check same value - FTYPE old_value = static_cast(atof(old_s.c_str())); - FTYPE new_value = static_cast(atof(s.c_str())); - if (old_value != new_value) - throw E57_EXCEPTION2(E57_ERROR_INTERNAL, "fileName=" + fileName_ + " oldValue=" + toString(old_value) + " newValue=" + toString(new_value)); - if (new_value != value) - throw E57_EXCEPTION2(E57_ERROR_INTERNAL, "fileName=" + fileName_ + " newValue=" + toString(new_value) + " value=" + toString(value)); -#endif - - return ( *this << s ); -} - -void CheckedFile::seek( uint64_t offset, OffsetMode omode ) -{ - //??? check for seek beyond logicalLength_ - const auto pos = static_cast( omode == Physical ? offset : logicalToPhysical( offset ) ); - -#ifdef E57_MAX_VERBOSE - // cout << "seek offset=" << offset << " omode=" << omode << " pos=" << pos - // << std::endl; //??? -#endif - lseek64( pos, SEEK_SET ); -} - -uint64_t CheckedFile::lseek64( int64_t offset, int whence ) -{ - if ( ( fd_ < 0 ) && bufView_ ) - { - const auto uoffset = static_cast( offset ); - - if ( bufView_->seek( uoffset, whence ) ) - { - return bufView_->pos(); - } - - throw E57_EXCEPTION2( E57_ERROR_LSEEK_FAILED, "fileName=" + fileName_ + " offset=" + toString( offset ) + - " whence=" + toString( whence ) ); - } - -#if defined( _WIN32 ) -#if defined( _MSC_VER ) || defined( __MINGW32__ ) // mingw _is_ WIN32! - __int64 result = _lseeki64( fd_, offset, whence ); -#elif defined( __GNUC__ ) // this most likely will not get - // triggered (cygwin != WIN32)? -#ifdef E57_MAX_DEBUG - if ( sizeof( off_t ) != sizeof( offset ) ) - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "sizeof(off_t)=" + toString( sizeof( off_t ) ) ); -#endif - int64_t result = ::lseek( fd_, offset, whence ); -#else -#error "no supported compiler defined" -#endif -#elif defined( __linux__ ) - int64_t result = ::lseek64( fd_, offset, whence ); -#elif defined( __APPLE__ ) || defined(__BSD) - int64_t result = ::lseek( fd_, offset, whence ); -#else -#error "no supported OS platform defined" -#endif - - if ( result < 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_LSEEK_FAILED, "fileName=" + fileName_ + " offset=" + toString( offset ) + - " whence=" + toString( whence ) + - " result=" + toString( result ) ); - } - - return static_cast( result ); -} - -uint64_t CheckedFile::position( OffsetMode omode ) -{ - /// Get current file cursor position - const uint64_t pos = lseek64( 0LL, SEEK_CUR ); - - if ( omode == Physical ) - { - return pos; - } - - return physicalToLogical( pos ); -} - -uint64_t CheckedFile::length( OffsetMode omode ) -{ - if ( omode == Physical ) - { - if ( readOnly_ ) - { - return physicalLength_; - } - - // Current file position - uint64_t original_pos = lseek64( 0LL, SEEK_CUR ); - - // End file position - uint64_t end_pos = lseek64( 0LL, SEEK_END ); - - // Restore original position - lseek64( original_pos, SEEK_SET ); - - return end_pos; - } - - return logicalLength_; -} - -void CheckedFile::extend( uint64_t newLength, OffsetMode omode ) -{ -#ifdef E57_MAX_VERBOSE - // cout << "extend newLength=" << newLength << " omode="<< omode << std::endl; - // //??? -#endif - if ( readOnly_ ) - { - throw E57_EXCEPTION2( E57_ERROR_FILE_IS_READ_ONLY, "fileName=" + fileName_ ); - } - - uint64_t newLogicalLength = 0; - - if ( omode == Physical ) - { - newLogicalLength = physicalToLogical( newLength ); - } - else - { - newLogicalLength = newLength; - } - - uint64_t currentLogicalLength = length( Logical ); - - /// Make sure we are trying to make file longer - if ( newLogicalLength < currentLogicalLength ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "fileName=" + fileName_ + " newLength=" + toString( newLogicalLength ) + - " currentLength=" + toString( currentLogicalLength ) ); - } - - /// Calc how may zero bytes we have to add to end - uint64_t nWrite = newLogicalLength - currentLogicalLength; - - /// Seek to current end of file - seek( currentLogicalLength, Logical ); - - uint64_t page = 0; - size_t pageOffset = 0; - - getCurrentPageAndOffset( page, pageOffset ); - - /// Calc first write size (may be partial page) - /// Watch out for different int sizes here. - size_t n = 0; - - if ( nWrite < logicalPageSize - pageOffset ) - { - n = static_cast( nWrite ); - } - else - { - n = logicalPageSize - pageOffset; - } - - /// Allocate temp page buffer - std::vector page_buffer_v( physicalPageSize ); - char *page_buffer = &page_buffer_v[0]; - - while ( nWrite > 0 ) - { - const uint64_t physicalLength = length( Physical ); - - if ( page * physicalPageSize < physicalLength ) - { - readPhysicalPage( page_buffer, page ); - } - -#ifdef E57_MAX_VERBOSE - // cout << "extend " << n << "bytes on page=" << page << " pageOffset=" << - // pageOffset << std::endl; - // //??? -#endif - memset( page_buffer + pageOffset, 0, n ); - writePhysicalPage( page_buffer, page ); - - nWrite -= n; - pageOffset = 0; - ++page; - - if ( nWrite < logicalPageSize ) - { - n = static_cast( nWrite ); - } - else - { - n = logicalPageSize; - } - } - - //??? what if loop above throws, logicalLength_ may be wrong - logicalLength_ = newLogicalLength; - - /// When done, leave cursor at end of file - seek( newLogicalLength, Logical ); -} - -void CheckedFile::close() -{ - if ( fd_ >= 0 ) - { -#if defined( _MSC_VER ) - int result = ::_close( fd_ ); -#elif defined( __GNUC__ ) - int result = ::close( fd_ ); -#else -#error "no supported compiler defined" -#endif - if ( result < 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_CLOSE_FAILED, "fileName=" + fileName_ + " result=" + toString( result ) ); - } - - fd_ = -1; - } - - if ( bufView_ ) - { - delete bufView_; - bufView_ = nullptr; - - // WARNING: do NOT delete buffer of bufView_ because - // pointer is handled by user !! - } -} - -void CheckedFile::unlink() -{ - close(); - - /// Try to remove the file, don't report a failure - int result = std::remove( fileName_.c_str() ); //??? unicode support here - (void)result; // this maybe unused -#ifdef E57_MAX_VERBOSE - if ( result < 0 ) - { - std::cout << "std::remove() failed, result=" << result << std::endl; - } -#endif -} - -inline uint32_t swap_uint32( uint32_t val ) -{ - val = ( ( val << 8 ) & 0xFF00FF00 ) | ( ( val >> 8 ) & 0xFF00FF ); - - return ( val << 16 ) | ( val >> 16 ); -} - -/// Calc CRC32C of given data -uint32_t CheckedFile::checksum( char *buf, size_t size ) const -{ - static const CRC::Parameters sCRCParams{ 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, true, true }; - - static const CRC::Table sCRCTable = sCRCParams.MakeTable(); - - auto crc = CRC::Calculate( buf, size, sCRCTable ); - - // (Andy) I don't understand why we need to swap bytes here - crc = swap_uint32( crc ); - - return crc; -} - -void CheckedFile::verifyChecksum( char *page_buffer, size_t page ) -{ - const uint32_t check_sum = checksum( page_buffer, logicalPageSize ); - const uint32_t check_sum_in_page = *reinterpret_cast( &page_buffer[logicalPageSize] ); - - if ( check_sum_in_page != check_sum ) - { - const uint64_t physicalLength = length( Physical ); - - throw E57_EXCEPTION2( E57_ERROR_BAD_CHECKSUM, - "fileName=" + fileName_ + " computedChecksum=" + toString( check_sum ) + - " storedChecksum=" + toString( check_sum_in_page ) + " page=" + toString( page ) + - " length=" + toString( physicalLength ) ); - } -} - -void CheckedFile::getCurrentPageAndOffset( uint64_t &page, size_t &pageOffset, OffsetMode omode ) -{ - const uint64_t pos = position( omode ); - - if ( omode == Physical ) - { - page = pos >> physicalPageSizeLog2; - pageOffset = static_cast( pos & physicalPageSizeMask ); - } - else - { - page = pos / logicalPageSize; - pageOffset = static_cast( pos - page * logicalPageSize ); - } -} - -void CheckedFile::readPhysicalPage( char *page_buffer, uint64_t page ) -{ -#ifdef E57_MAX_VERBOSE - // cout << "readPhysicalPage, page:" << page << std::endl; -#endif - -#ifdef E57_CHECK_FILE_DEBUG - const uint64_t physicalLength = length( Physical ); - - assert( page * physicalPageSize < physicalLength ); -#endif - - /// Seek to start of physical page - seek( page * physicalPageSize, Physical ); - - if ( ( fd_ < 0 ) && bufView_ ) - { - bufView_->read( page_buffer, physicalPageSize ); - return; - } - -#if defined( _MSC_VER ) - int result = ::_read( fd_, page_buffer, physicalPageSize ); -#elif defined( __GNUC__ ) - ssize_t result = ::read( fd_, page_buffer, physicalPageSize ); -#else -#error "no supported compiler defined" -#endif - - if ( result < 0 || static_cast( result ) != physicalPageSize ) - { - throw E57_EXCEPTION2( E57_ERROR_READ_FAILED, "fileName=" + fileName_ + " result=" + toString( result ) ); - } -} - -void CheckedFile::writePhysicalPage( char *page_buffer, uint64_t page ) -{ -#ifdef E57_MAX_VERBOSE - // cout << "writePhysicalPage, page:" << page << std::endl; -#endif - - /// Append checksum - uint32_t check_sum = checksum( page_buffer, logicalPageSize ); - *reinterpret_cast( &page_buffer[logicalPageSize] ) = check_sum; //??? little endian dependency - - /// Seek to start of physical page - seek( page * physicalPageSize, Physical ); - -#if defined( _MSC_VER ) - int result = ::_write( fd_, page_buffer, physicalPageSize ); -#elif defined( __GNUC__ ) - ssize_t result = ::write( fd_, page_buffer, physicalPageSize ); -#else -#error "no supported compiler defined" -#endif - - if ( result < 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_WRITE_FAILED, "fileName=" + fileName_ + " result=" + toString( result ) ); - } -} diff --git a/src/3rdParty/libE57Format/src/CheckedFile.h b/src/3rdParty/libE57Format/src/CheckedFile.h deleted file mode 100644 index 3163c28875..0000000000 --- a/src/3rdParty/libE57Format/src/CheckedFile.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include - -#include "Common.h" - -namespace e57 -{ - /// Tool class to read buffer efficiently without - /// multiplying copy operations. - /// - /// WARNING: pointer input is handled by user! - class BufferView; - - class CheckedFile - { - public: - static constexpr size_t physicalPageSizeLog2 = 10; // physical page size is 2 raised to this power - static constexpr size_t physicalPageSize = 1 << physicalPageSizeLog2; - static constexpr uint64_t physicalPageSizeMask = physicalPageSize - 1; - static constexpr size_t logicalPageSize = physicalPageSize - 4; - - public: - enum Mode - { - ReadOnly, - WriteCreate, - WriteExisting - }; - - enum OffsetMode - { - Logical, - Physical - }; - - CheckedFile( const e57::ustring &fileName, Mode mode, ReadChecksumPolicy policy ); - CheckedFile( const char *input, uint64_t size, ReadChecksumPolicy policy ); - ~CheckedFile(); - - void read( char *buf, size_t nRead, size_t bufSize = 0 ); - void write( const char *buf, size_t nWrite ); - CheckedFile &operator<<( const e57::ustring &s ); - CheckedFile &operator<<( int64_t i ); - CheckedFile &operator<<( uint64_t i ); - CheckedFile &operator<<( float f ); - CheckedFile &operator<<( double d ); - void seek( uint64_t offset, OffsetMode omode = Logical ); - uint64_t position( OffsetMode omode = Logical ); - uint64_t length( OffsetMode omode = Logical ); - void extend( uint64_t newLength, OffsetMode omode = Logical ); - e57::ustring fileName() const - { - return fileName_; - } - void close(); - void unlink(); - - static inline uint64_t logicalToPhysical( uint64_t logicalOffset ); - static inline uint64_t physicalToLogical( uint64_t physicalOffset ); - - private: - uint32_t checksum( char *buf, size_t size ) const; - void verifyChecksum( char *page_buffer, size_t page ); - - template CheckedFile &writeFloatingPoint( FTYPE value, int precision ); - - void getCurrentPageAndOffset( uint64_t &page, size_t &pageOffset, OffsetMode omode = Logical ); - void readPhysicalPage( char *page_buffer, uint64_t page ); - void writePhysicalPage( char *page_buffer, uint64_t page ); - int open64( const e57::ustring &fileName, int flags, int mode ); - uint64_t lseek64( int64_t offset, int whence ); - - e57::ustring fileName_; - uint64_t logicalLength_ = 0; - uint64_t physicalLength_ = 0; - - ReadChecksumPolicy checkSumPolicy_ = CHECKSUM_POLICY_ALL; - - int fd_ = -1; - BufferView *bufView_ = nullptr; - bool readOnly_ = false; - }; - - inline uint64_t CheckedFile::logicalToPhysical( uint64_t logicalOffset ) - { - const uint64_t page = logicalOffset / logicalPageSize; - const uint64_t remainder = logicalOffset - page * logicalPageSize; - - return page * physicalPageSize + remainder; - } - - inline uint64_t CheckedFile::physicalToLogical( uint64_t physicalOffset ) - { - const uint64_t page = physicalOffset >> physicalPageSizeLog2; - const size_t remainder = static_cast( physicalOffset & physicalPageSizeMask ); - - return page * logicalPageSize + std::min( remainder, logicalPageSize ); - } - -} diff --git a/src/3rdParty/libE57Format/src/Common.cpp b/src/3rdParty/libE57Format/src/Common.cpp deleted file mode 100644 index 868c71a363..0000000000 --- a/src/3rdParty/libE57Format/src/Common.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// Copyright (c) 2020 PTC Inc. - -#include "Common.h" - -#include - -namespace e57 -{ - - std::string generateRandomGUID() - { - static constexpr const char UUID_CHARS[] = "0123456789ABCDEF"; - static std::random_device rd; - static std::mt19937 gen( rd() ); - static std::uniform_int_distribution<> dis( 0, 15 /* number of chars in UUID_CHARS */ ); - - std::string uuid( 38, ' ' ); - - uuid[0] = '{'; - uuid[9] = '-'; - uuid[14] = '-'; - uuid[19] = '-'; - uuid[24] = '-'; - uuid[37] = '}'; - - uuid[15] = '4'; - - for ( int i = 1; i < 37; ++i ) - { - if ( i != 9 && i != 14 && i != 19 && i != 24 && i != 15 ) - { - uuid[i] = UUID_CHARS[dis( gen )]; - } - } - return uuid; - } - -} // end namespace e57 diff --git a/src/3rdParty/libE57Format/src/Common.h b/src/3rdParty/libE57Format/src/Common.h deleted file mode 100644 index 355d59662d..0000000000 --- a/src/3rdParty/libE57Format/src/Common.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -// Define the following symbol adds some functions to the API for implementation -// purposes. These functions are not available to a normal API user. -#define E57_INTERNAL_IMPLEMENTATION_ENABLE 1 -#include "E57Format.h" - -#ifdef _MSC_VER -// Disable MSVC warning: warning C4224: nonstandard extension used : formal -// parameter 'locale' was previously defined as a type -#pragma warning( disable : 4224 ) -#endif - -namespace e57 -{ -//!!! inline these rather than macros? -#define E57_EXCEPTION1( ecode ) \ - ( E57Exception( ( ecode ), ustring(), __FILE__, __LINE__, static_cast( __FUNCTION__ ) ) ) -#define E57_EXCEPTION2( ecode, context ) \ - ( E57Exception( ( ecode ), ( context ), __FILE__, __LINE__, static_cast( __FUNCTION__ ) ) ) - - /// Create whitespace of given length, for indenting printouts in dump() - /// functions - inline std::string space( size_t n ) - { - return ( std::string( n, ' ' ) ); - } - - /// Convert number to decimal, hexadecimal, and binary strings (Note hex - /// strings don't have leading zeros). - template std::string toString( T x ) - { - std::ostringstream ss; - ss << x; - return ( ss.str() ); - } - - inline std::string hexString( uint64_t x ) - { - std::ostringstream ss; - ss << "0x" << std::hex << std::setw( 16 ) << std::setfill( '0' ) << x; - return ( ss.str() ); - } - inline std::string hexString( uint32_t x ) - { - std::ostringstream ss; - ss << "0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << x; - return ( ss.str() ); - } - inline std::string hexString( uint16_t x ) - { - std::ostringstream ss; - ss << "0x" << std::hex << std::setw( 4 ) << std::setfill( '0' ) << x; - return ( ss.str() ); - } - inline std::string hexString( uint8_t x ) - { - std::ostringstream ss; - ss << "0x" << std::hex << std::setw( 2 ) << std::setfill( '0' ) << static_cast( x ); - return ( ss.str() ); - } - inline std::string binaryString( uint64_t x ) - { - std::ostringstream ss; - for ( int i = 63; i >= 0; i-- ) - { - ss << ( ( x & ( 1LL << i ) ) ? 1 : 0 ); - if ( i > 0 && i % 8 == 0 ) - ss << " "; - } - return ( ss.str() ); - } - inline std::string binaryString( uint32_t x ) - { - std::ostringstream ss; - for ( int i = 31; i >= 0; i-- ) - { - ss << ( ( x & ( 1LL << i ) ) ? 1 : 0 ); - if ( i > 0 && i % 8 == 0 ) - ss << " "; - } - return ( ss.str() ); - } - inline std::string binaryString( uint16_t x ) - { - std::ostringstream ss; - for ( int i = 15; i >= 0; i-- ) - { - ss << ( ( x & ( 1LL << i ) ) ? 1 : 0 ); - if ( i > 0 && i % 8 == 0 ) - ss << " "; - } - return ( ss.str() ); - } - inline std::string binaryString( uint8_t x ) - { - std::ostringstream ss; - for ( int i = 7; i >= 0; i-- ) - { - ss << ( ( x & ( 1LL << i ) ) ? 1 : 0 ); - if ( i > 0 && i % 8 == 0 ) - ss << " "; - } - return ( ss.str() ); - } - inline std::string hexString( int64_t x ) - { - return ( hexString( static_cast( x ) ) ); - } - inline std::string hexString( int32_t x ) - { - return ( hexString( static_cast( x ) ) ); - } - inline std::string hexString( int16_t x ) - { - return ( hexString( static_cast( x ) ) ); - } - inline std::string hexString( int8_t x ) - { - return ( hexString( static_cast( x ) ) ); - } - inline std::string binaryString( int64_t x ) - { - return ( binaryString( static_cast( x ) ) ); - } - inline std::string binaryString( int32_t x ) - { - return ( binaryString( static_cast( x ) ) ); - } - inline std::string binaryString( int16_t x ) - { - return ( binaryString( static_cast( x ) ) ); - } - inline std::string binaryString( int8_t x ) - { - return ( binaryString( static_cast( x ) ) ); - } - - using ImageFileImplSharedPtr = std::shared_ptr; - using ImageFileImplWeakPtr = std::weak_ptr; - using NodeImplSharedPtr = std::shared_ptr; - using NodeImplWeakPtr = std::weak_ptr; - - using StringList = std::vector; - using StringSet = std::set; - - //! generates a new random GUID - std::string generateRandomGUID(); -} diff --git a/src/3rdParty/libE57Format/src/CompressedVectorNodeImpl.cpp b/src/3rdParty/libE57Format/src/CompressedVectorNodeImpl.cpp deleted file mode 100644 index d6bbd53bcb..0000000000 --- a/src/3rdParty/libE57Format/src/CompressedVectorNodeImpl.cpp +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "CompressedVectorNodeImpl.h" -#include "CheckedFile.h" -#include "CompressedVectorReaderImpl.h" -#include "CompressedVectorWriterImpl.h" -#include "ImageFileImpl.h" -#include "VectorNodeImpl.h" - -namespace e57 -{ - CompressedVectorNodeImpl::CompressedVectorNodeImpl( ImageFileImplWeakPtr destImageFile ) : NodeImpl( destImageFile ) - { - // don't checkImageFileOpen, NodeImpl() will do it - } - - void CompressedVectorNodeImpl::setPrototype( const NodeImplSharedPtr &prototype ) - { - // don't checkImageFileOpen, ctor did it - - //??? check ok for proto, no Blob CompressedVector, empty? - //??? throw E57_EXCEPTION2(E57_ERROR_BAD_PROTOTYPE) - - /// Can't set prototype twice. - if ( prototype_ ) - { - throw E57_EXCEPTION2( E57_ERROR_SET_TWICE, "this->pathName=" + this->pathName() ); - } - - /// prototype can't have a parent (must be a root node) - if ( !prototype->isRoot() ) - { - throw E57_EXCEPTION2( E57_ERROR_ALREADY_HAS_PARENT, - "this->pathName=" + this->pathName() + " prototype->pathName=" + prototype->pathName() ); - } - - /// Verify that prototype is destined for same ImageFile as this is - ImageFileImplSharedPtr thisDest( destImageFile() ); - ImageFileImplSharedPtr prototypeDest( prototype->destImageFile() ); - if ( thisDest != prototypeDest ) - { - throw E57_EXCEPTION2( E57_ERROR_DIFFERENT_DEST_IMAGEFILE, "this->destImageFile" + thisDest->fileName() + - " prototype->destImageFile" + - prototypeDest->fileName() ); - } - - //!!! check for incomplete CompressedVectors when closing file - prototype_ = prototype; - - /// Note that prototype is not attached to CompressedVector in a parent/child - /// relationship. This means that prototype is a root node (has no parent). - } - - NodeImplSharedPtr CompressedVectorNodeImpl::getPrototype() const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( prototype_ ); //??? check defined - } - - void CompressedVectorNodeImpl::setCodecs( const std::shared_ptr &codecs ) - { - // don't checkImageFileOpen, ctor did it - - //??? check ok for codecs, empty vector, or each element has "inputs" vector - // of strings, codec - // substruct - - /// Can't set codecs twice. - if ( codecs_ ) - { - throw E57_EXCEPTION2( E57_ERROR_SET_TWICE, "this->pathName=" + this->pathName() ); - } - - /// codecs can't have a parent (must be a root node) - if ( !codecs->isRoot() ) - { - throw E57_EXCEPTION2( E57_ERROR_ALREADY_HAS_PARENT, - "this->pathName=" + this->pathName() + " codecs->pathName=" + codecs->pathName() ); - } - - /// Verify that codecs is destined for same ImageFile as this is - ImageFileImplSharedPtr thisDest( destImageFile() ); - ImageFileImplSharedPtr codecsDest( codecs->destImageFile() ); - if ( thisDest != codecsDest ) - { - throw E57_EXCEPTION2( E57_ERROR_DIFFERENT_DEST_IMAGEFILE, "this->destImageFile" + thisDest->fileName() + - " codecs->destImageFile" + - codecsDest->fileName() ); - } - - codecs_ = codecs; - - /// Note that codecs is not attached to CompressedVector in a parent/child - /// relationship. This means that codecs is a root node (has no parent). - } - - std::shared_ptr CompressedVectorNodeImpl::getCodecs() const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( codecs_ ); //??? check defined - } - - bool CompressedVectorNodeImpl::isTypeEquivalent( NodeImplSharedPtr ni ) - { - // don't checkImageFileOpen - - //??? is this test a good idea? - - /// Same node type? - if ( ni->type() != E57_COMPRESSED_VECTOR ) - { - return ( false ); - } - - std::shared_ptr cvi( std::static_pointer_cast( ni ) ); - - /// recordCount must match - if ( recordCount_ != cvi->recordCount_ ) - { - return ( false ); - } - - /// Prototypes and codecs must match ??? - if ( !prototype_->isTypeEquivalent( cvi->prototype_ ) ) - { - return ( false ); - } - if ( !codecs_->isTypeEquivalent( cvi->codecs_ ) ) - { - return ( false ); - } - - return ( true ); - } - - bool CompressedVectorNodeImpl::isDefined( const ustring &pathName ) - { - throw E57_EXCEPTION2( E57_ERROR_NOT_IMPLEMENTED, "this->pathName=" + this->pathName() + " pathName=" + pathName ); - } - - void CompressedVectorNodeImpl::setAttachedRecursive() - { - /// Mark this node as attached to an ImageFile - isAttached_ = true; - - /// Mark nodes in prototype tree, if defined - if ( prototype_ ) - { - prototype_->setAttachedRecursive(); - } - - /// Mark nodes in codecs tree if defined - if ( codecs_ ) - { - codecs_->setAttachedRecursive(); - } - } - - int64_t CompressedVectorNodeImpl::childCount() const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( recordCount_ ); - } - - void CompressedVectorNodeImpl::checkLeavesInSet( const StringSet & /*pathNames*/, NodeImplSharedPtr /*origin*/ ) - { - // don't checkImageFileOpen - - /// Since only called for prototype nodes, shouldn't be able to get here since - /// CompressedVectors can't be in prototypes - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "this->pathName=" + this->pathName() ); - } - - void CompressedVectorNodeImpl::writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, - const char *forcedFieldName ) - { - // don't checkImageFileOpen - - ustring fieldName; - if ( forcedFieldName ) - { - fieldName = forcedFieldName; - } - else - { - fieldName = elementName_; - } - - uint64_t physicalStart = cf.logicalToPhysical( binarySectionLogicalStart_ ); - - cf << space( indent ) << "<" << fieldName << " type=\"CompressedVector\""; - cf << " fileOffset=\"" << physicalStart; - cf << "\" recordCount=\"" << recordCount_ << "\">\n"; - - if ( prototype_ ) - { - prototype_->writeXml( imf, cf, indent + 2, "prototype" ); - } - if ( codecs_ ) - { - codecs_->writeXml( imf, cf, indent + 2, "codecs" ); - } - cf << space( indent ) << "\n"; - } - -#ifdef E57_DEBUG - void CompressedVectorNodeImpl::dump( int indent, std::ostream &os ) const - { - os << space( indent ) << "type: CompressedVector" - << " (" << type() << ")" << std::endl; - NodeImpl::dump( indent, os ); - if ( prototype_ ) - { - os << space( indent ) << "prototype:" << std::endl; - prototype_->dump( indent + 2, os ); - } - else - { - os << space( indent ) << "prototype: " << std::endl; - } - if ( codecs_ ) - { - os << space( indent ) << "codecs:" << std::endl; - codecs_->dump( indent + 2, os ); - } - else - { - os << space( indent ) << "codecs: " << std::endl; - } - os << space( indent ) << "recordCount: " << recordCount_ << std::endl; - os << space( indent ) << "binarySectionLogicalStart: " << binarySectionLogicalStart_ << std::endl; - } -#endif - - std::shared_ptr CompressedVectorNodeImpl::writer( std::vector sbufs ) - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - ImageFileImplSharedPtr destImageFile( destImageFile_ ); - - /// Check don't have any writers/readers open for this ImageFile - if ( destImageFile->writerCount() > 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_TOO_MANY_WRITERS, - "fileName=" + destImageFile->fileName() + - " writerCount=" + toString( destImageFile->writerCount() ) + - " readerCount=" + toString( destImageFile->readerCount() ) ); - } - if ( destImageFile->readerCount() > 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_TOO_MANY_READERS, - "fileName=" + destImageFile->fileName() + - " writerCount=" + toString( destImageFile->writerCount() ) + - " readerCount=" + toString( destImageFile->readerCount() ) ); - } - - /// sbufs can't be empty - if ( sbufs.empty() ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_API_ARGUMENT, "fileName=" + destImageFile->fileName() ); - } - - if ( !destImageFile->isWriter() ) - { - throw E57_EXCEPTION2( E57_ERROR_FILE_IS_READ_ONLY, "fileName=" + destImageFile->fileName() ); - } - - if ( !isAttached() ) - { - throw E57_EXCEPTION2( E57_ERROR_NODE_UNATTACHED, "fileName=" + destImageFile->fileName() ); - } - - /// Get pointer to me (really shared_ptr) - NodeImplSharedPtr ni( shared_from_this() ); - - /// Downcast pointer to right type - std::shared_ptr cai( std::static_pointer_cast( ni ) ); - - /// Return a shared_ptr to new object - std::shared_ptr cvwi( new CompressedVectorWriterImpl( cai, sbufs ) ); - return ( cvwi ); - } - - std::shared_ptr CompressedVectorNodeImpl::reader( std::vector dbufs ) - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - ImageFileImplSharedPtr destImageFile( destImageFile_ ); - - /// Check don't have any writers/readers open for this ImageFile - if ( destImageFile->writerCount() > 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_TOO_MANY_WRITERS, - "fileName=" + destImageFile->fileName() + - " writerCount=" + toString( destImageFile->writerCount() ) + - " readerCount=" + toString( destImageFile->readerCount() ) ); - } - if ( destImageFile->readerCount() > 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_TOO_MANY_READERS, - "fileName=" + destImageFile->fileName() + - " writerCount=" + toString( destImageFile->writerCount() ) + - " readerCount=" + toString( destImageFile->readerCount() ) ); - } - - /// dbufs can't be empty - if ( dbufs.empty() ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_API_ARGUMENT, "fileName=" + destImageFile->fileName() ); - } - - /// Can be read or write mode, but must be attached - if ( !isAttached() ) - { - throw E57_EXCEPTION2( E57_ERROR_NODE_UNATTACHED, "fileName=" + destImageFile->fileName() ); - } - - /// Get pointer to me (really shared_ptr) - NodeImplSharedPtr ni( shared_from_this() ); -#ifdef E57_MAX_VERBOSE - // cout << "constructing CAReader, ni:" << std::endl; - // ni->dump(4); -#endif - - /// Downcast pointer to right type - std::shared_ptr cai( std::static_pointer_cast( ni ) ); -#ifdef E57_MAX_VERBOSE - // cout<<"constructing CAReader, cai:"<dump(4); -#endif - /// Return a shared_ptr to new object - std::shared_ptr cvri( new CompressedVectorReaderImpl( cai, dbufs ) ); - return ( cvri ); - } -} diff --git a/src/3rdParty/libE57Format/src/CompressedVectorNodeImpl.h b/src/3rdParty/libE57Format/src/CompressedVectorNodeImpl.h deleted file mode 100644 index e80541208f..0000000000 --- a/src/3rdParty/libE57Format/src/CompressedVectorNodeImpl.h +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "NodeImpl.h" - -namespace e57 -{ - class CompressedVectorNodeImpl : public NodeImpl - { - public: - CompressedVectorNodeImpl( ImageFileImplWeakPtr destImageFile ); - ~CompressedVectorNodeImpl() override = default; - - NodeType type() const override - { - return E57_COMPRESSED_VECTOR; - } - bool isTypeEquivalent( NodeImplSharedPtr ni ) override; - bool isDefined( const ustring &pathName ) override; - void setAttachedRecursive() override; - - void setPrototype( const NodeImplSharedPtr &prototype ); - NodeImplSharedPtr getPrototype() const; - void setCodecs( const std::shared_ptr &codecs ); - std::shared_ptr getCodecs() const; - - int64_t childCount() const; - - void checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) override; - - void writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, - const char *forcedFieldName = nullptr ) override; - - /// Iterator constructors - std::shared_ptr writer( std::vector sbufs ); - std::shared_ptr reader( std::vector dbufs ); - - int64_t getRecordCount() const - { - return ( recordCount_ ); - } - uint64_t getBinarySectionLogicalStart() const - { - return ( binarySectionLogicalStart_ ); - } - void setRecordCount( int64_t recordCount ) - { - recordCount_ = recordCount; - } - void setBinarySectionLogicalStart( uint64_t binarySectionLogicalStart ) - { - binarySectionLogicalStart_ = binarySectionLogicalStart; - } - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - - private: - friend class CompressedVectorReaderImpl; - - NodeImplSharedPtr prototype_; - std::shared_ptr codecs_; - - int64_t recordCount_ = 0; - uint64_t binarySectionLogicalStart_ = 0; - }; -} diff --git a/src/3rdParty/libE57Format/src/CompressedVectorReaderImpl.cpp b/src/3rdParty/libE57Format/src/CompressedVectorReaderImpl.cpp deleted file mode 100644 index 87fe47bae0..0000000000 --- a/src/3rdParty/libE57Format/src/CompressedVectorReaderImpl.cpp +++ /dev/null @@ -1,607 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "CompressedVectorReaderImpl.h" -#include "CheckedFile.h" -#include "CompressedVectorNodeImpl.h" -#include "ImageFileImpl.h" -#include "Packet.h" -#include "SectionHeaders.h" -#include "SourceDestBufferImpl.h" - -namespace e57 -{ - CompressedVectorReaderImpl::CompressedVectorReaderImpl( std::shared_ptr cvi, - std::vector &dbufs ) : - isOpen_( false ), // set to true when succeed below - cVector_( cvi ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "CompressedVectorReaderImpl() called" << std::endl; //??? -#endif - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - /// Allow reading of a completed CompressedVector, whether file is being read - /// or currently being written. - ///??? what other situations need checking for? - ///??? check if CV not yet written to? - ///??? file in error state? - - /// Empty dbufs is an error - if ( dbufs.empty() ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_API_ARGUMENT, - "imageFileName=" + cVector_->imageFileName() + " cvPathName=" + cVector_->pathName() ); - } - - /// Get CompressedArray's prototype node (all array elements must match this - /// type) - proto_ = cVector_->getPrototype(); - - /// Check dbufs well formed (matches proto exactly) - setBuffers( dbufs ); - - /// For each dbuf, create an appropriate Decoder based on the cVector_ - /// attributes - for ( unsigned i = 0; i < dbufs_.size(); i++ ) - { - std::vector theDbuf; - theDbuf.push_back( dbufs.at( i ) ); - - std::shared_ptr decoder = Decoder::DecoderFactory( i, cVector_.get(), theDbuf, ustring() ); - - /// Calc which stream the given path belongs to. This depends on position - /// of the node in the proto tree. - NodeImplSharedPtr readNode = proto_->get( dbufs.at( i ).pathName() ); - uint64_t bytestreamNumber = 0; - if ( !proto_->findTerminalPosition( readNode, bytestreamNumber ) ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "dbufIndex=" + toString( i ) ); - } - - channels_.emplace_back( dbufs.at( i ), decoder, static_cast( bytestreamNumber ), - cVector_->childCount() ); - } - - recordCount_ = 0; - - /// Get how many records are actually defined - maxRecordCount_ = cvi->childCount(); - - ImageFileImplSharedPtr imf( cVector_->destImageFile_ ); - - //??? what if fault in this constructor? - cache_ = new PacketReadCache( imf->file_, 32 ); - - /// Read CompressedVector section header - CompressedVectorSectionHeader sectionHeader; - uint64_t sectionLogicalStart = cVector_->getBinarySectionLogicalStart(); - if ( sectionLogicalStart == 0 ) - { - //??? should have caught this before got here, in XML read, get this if CV - // wasn't written to - // by writer. - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, - "imageFileName=" + cVector_->imageFileName() + " cvPathName=" + cVector_->pathName() ); - } - imf->file_->seek( sectionLogicalStart, CheckedFile::Logical ); - imf->file_->read( reinterpret_cast( §ionHeader ), sizeof( sectionHeader ) ); - -#ifdef E57_DEBUG - sectionHeader.verify( imf->file_->length( CheckedFile::Physical ) ); -#endif - - /// Pre-calc end of section, so can tell when we are out of packets. - sectionEndLogicalOffset_ = sectionLogicalStart + sectionHeader.sectionLogicalLength; - - /// Convert physical offset to first data packet to logical - uint64_t dataLogicalOffset = imf->file_->physicalToLogical( sectionHeader.dataPhysicalOffset ); - - /// Verify that packet given by dataPhysicalOffset is actually a data packet, - /// init channels - { - char *anyPacket = nullptr; - std::unique_ptr packetLock = cache_->lock( dataLogicalOffset, anyPacket ); - - auto dpkt = reinterpret_cast( anyPacket ); - - /// Double check that have a data packet - if ( dpkt->header.packetType != DATA_PACKET ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetType=" + toString( dpkt->header.packetType ) ); - } - - /// Have good packet, initialize channels - for ( auto &channel : channels_ ) - { - channel.currentPacketLogicalOffset = dataLogicalOffset; - channel.currentBytestreamBufferIndex = 0; - channel.currentBytestreamBufferLength = dpkt->getBytestreamBufferLength( channel.bytestreamNumber ); - } - } - - /// Just before return (and can't throw) increment reader count ??? safer - /// way to assure don't miss close? - imf->incrReaderCount(); - - /// If get here, the reader is open - isOpen_ = true; - } - - CompressedVectorReaderImpl::~CompressedVectorReaderImpl() - { -#ifdef E57_MAX_VERBOSE - std::cout << "~CompressedVectorReaderImpl() called" << std::endl; //??? - // dump(4); -#endif - - if ( isOpen_ ) - { - try - { - close(); ///??? what if already closed? - } - catch ( ... ) - { - //??? report? - } - } - } - - void CompressedVectorReaderImpl::setBuffers( std::vector &dbufs ) - { - /// don't checkImageFileOpen - /// don't checkReaderOpen - - /// Check dbufs well formed: no dups, no extra, missing is ok - proto_->checkBuffers( dbufs, true ); - - /// If had previous dbufs_, check to see if new ones have changed in - /// incompatible way - if ( !dbufs_.empty() ) - { - if ( dbufs_.size() != dbufs.size() ) - { - throw E57_EXCEPTION2( E57_ERROR_BUFFERS_NOT_COMPATIBLE, - "oldSize=" + toString( dbufs_.size() ) + " newSize=" + toString( dbufs.size() ) ); - } - for ( size_t i = 0; i < dbufs_.size(); i++ ) - { - std::shared_ptr oldBuf = dbufs_[i].impl(); - std::shared_ptr newBuf = dbufs[i].impl(); - - /// Throw exception if old and new not compatible - oldBuf->checkCompatible( newBuf ); - } - } - - dbufs_ = dbufs; - } - - unsigned CompressedVectorReaderImpl::read( std::vector &dbufs ) - { - /// don't checkImageFileOpen(__FILE__, __LINE__, __FUNCTION__), read() will - /// do it - - checkReaderOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - /// Check compatible with current dbufs - setBuffers( dbufs ); - - return ( read() ); - } - - unsigned CompressedVectorReaderImpl::read() - { -#ifdef E57_MAX_VERBOSE - std::cout << "CompressedVectorReaderImpl::read() called" << std::endl; //??? -#endif - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - checkReaderOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - /// Rewind all dbufs so start writing to them at beginning - for ( auto &dbuf : dbufs_ ) - { - dbuf.impl()->rewind(); - } - - /// Allow decoders to use data they already have in their queue to fill newly - /// empty dbufs This helps to keep decoder input queues smaller, which - /// reduces backtracking in the packet cache. - for ( auto &channel : channels_ ) - { - channel.decoder->inputProcess( nullptr, 0 ); - } - - /// Loop until every dbuf is full or we have reached end of the binary - /// section. - while ( true ) - { - /// Find the earliest packet position for channels that are still hungry - /// It's important to call inputProcess of the decoders before this call, - /// so current hungriness level is reflected. - uint64_t earliestPacketLogicalOffset = earliestPacketNeededForInput(); - - /// If nobody's hungry, we are done with the read - if ( earliestPacketLogicalOffset == E57_UINT64_MAX ) - { - break; - } - - /// Feed packet to the hungry decoders - feedPacketToDecoders( earliestPacketLogicalOffset ); - } - - /// Verify that each channel produced the same number of records - unsigned outputCount = 0; - for ( unsigned i = 0; i < channels_.size(); i++ ) - { - DecodeChannel *chan = &channels_[i]; - if ( i == 0 ) - { - outputCount = chan->dbuf.impl()->nextIndex(); - } - else - { - if ( outputCount != chan->dbuf.impl()->nextIndex() ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "outputCount=" + toString( outputCount ) + " nextIndex=" + - toString( chan->dbuf.impl()->nextIndex() ) ); - } - } - } - - /// Return number of records transferred to each dbuf. - return outputCount; - } - - uint64_t CompressedVectorReaderImpl::earliestPacketNeededForInput() const - { - uint64_t earliestPacketLogicalOffset = E57_UINT64_MAX; -#ifdef E57_MAX_VERBOSE - unsigned earliestChannel = 0; -#endif - - for ( unsigned i = 0; i < channels_.size(); i++ ) - { - const DecodeChannel *chan = &channels_[i]; - - /// Test if channel needs more input. - /// Important to call inputProcess just before this, so these tests work. - if ( !chan->isOutputBlocked() && !chan->inputFinished ) - { - /// Check if earliest so far - if ( chan->currentPacketLogicalOffset < earliestPacketLogicalOffset ) - { - earliestPacketLogicalOffset = chan->currentPacketLogicalOffset; -#ifdef E57_MAX_VERBOSE - earliestChannel = i; -#endif - } - } - } -#ifdef E57_MAX_VERBOSE - if ( earliestPacketLogicalOffset == E57_UINT64_MAX ) - { - std::cout << "earliestPacketNeededForInput returning none found" << std::endl; - } - else - { - std::cout << "earliestPacketNeededForInput returning " << earliestPacketLogicalOffset << " for channel[" - << earliestChannel << "]" << std::endl; - } -#endif - return earliestPacketLogicalOffset; - } - - DataPacket *CompressedVectorReaderImpl::dataPacket( uint64_t inLogicalOffset ) const - { - char *packet = nullptr; - - std::unique_ptr packetLock = cache_->lock( inLogicalOffset, packet ); - - return reinterpret_cast( packet ); - } - - inline bool _alreadyReadPacket( const DecodeChannel &channel, uint64_t currentPacketLogicalOffset ) - { - return ( ( channel.currentPacketLogicalOffset != currentPacketLogicalOffset ) || channel.isOutputBlocked() ); - } - - void CompressedVectorReaderImpl::feedPacketToDecoders( uint64_t currentPacketLogicalOffset ) - { - // Get packet at currentPacketLogicalOffset into memory. - auto dpkt = dataPacket( currentPacketLogicalOffset ); - - // Double check that have a data packet. Should have already determined - // this. - if ( dpkt->header.packetType != DATA_PACKET ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "packetType=" + toString( dpkt->header.packetType ) ); - } - - // Read earliest packet into cache and send data to decoders with unblocked - // output - - bool anyChannelHasExhaustedPacket = false; - uint64_t nextPacketLogicalOffset = E57_UINT64_MAX; - - // Feed bytestreams to channels with unblocked output that are reading from - // this packet - for ( DecodeChannel &channel : channels_ ) - { - // Skip channels that have already read this packet. - if ( _alreadyReadPacket( channel, currentPacketLogicalOffset ) ) - { - continue; - } - - // Get bytestream buffer for this channel from packet - unsigned int bsbLength = 0; - const char *bsbStart = dpkt->getBytestream( channel.bytestreamNumber, bsbLength ); - - // Double check we are not off end of buffer - if ( channel.currentBytestreamBufferIndex > bsbLength ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, - "currentBytestreamBufferIndex =" + toString( channel.currentBytestreamBufferIndex ) + - " bsbLength=" + toString( bsbLength ) ); - } - - // Calc where we are in the buffer - const char *uneatenStart = &bsbStart[channel.currentBytestreamBufferIndex]; - const size_t uneatenLength = bsbLength - channel.currentBytestreamBufferIndex; - - if ( &uneatenStart[uneatenLength] > &bsbStart[bsbLength] ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "uneatenLength=" + toString( uneatenLength ) + - " bsbLength=" + toString( bsbLength ) ); - } - - // Feed into decoder - const size_t bytesProcessed = channel.decoder->inputProcess( uneatenStart, uneatenLength ); - -#ifdef E57_MAX_VERBOSE - std::cout << " stream[" << channel.bytestreamNumber << "]: feeding decoder " << uneatenLength << " bytes" - << std::endl; - - if ( uneatenLength == 0 ) - { - channel.dump( 8 ); - } - - std::cout << " stream[" << channel.bytestreamNumber << "]: bytesProcessed=" << bytesProcessed << std::endl; -#endif - - // Adjust counts of bytestream location - channel.currentBytestreamBufferIndex += bytesProcessed; - - // Check if this channel has exhausted its bytestream buffer in this - // packet - if ( channel.isInputBlocked() ) - { -#ifdef E57_MAX_VERBOSE - std::cout << " stream[" << channel.bytestreamNumber << "] has exhausted its input in current packet" - << std::endl; -#endif - anyChannelHasExhaustedPacket = true; - nextPacketLogicalOffset = currentPacketLogicalOffset + dpkt->header.packetLogicalLengthMinus1 + 1; - } - } - - // Skip over any index or empty packets to next data packet. - nextPacketLogicalOffset = findNextDataPacket( nextPacketLogicalOffset ); - - // If no channel is exhausted, we're done - if ( !anyChannelHasExhaustedPacket ) - { - return; - } - - // Some channel has exhausted this packet, so find next data packet and - // update currentPacketLogicalOffset for all interested channels. - - if ( nextPacketLogicalOffset < E57_UINT64_MAX ) - { //??? huh? - // Get packet at nextPacketLogicalOffset into memory. - dpkt = dataPacket( nextPacketLogicalOffset ); - - // Got a data packet, update the channels with exhausted input - for ( DecodeChannel &channel : channels_ ) - { - // Skip channels that have already read this packet. - if ( _alreadyReadPacket( channel, currentPacketLogicalOffset ) ) - { - continue; - } - - channel.currentPacketLogicalOffset = nextPacketLogicalOffset; - channel.currentBytestreamBufferIndex = 0; - - // It is OK if the next packet doesn't contain any data for this - // channel, will skip packet on next iter of loop - channel.currentBytestreamBufferLength = dpkt->getBytestreamBufferLength( channel.bytestreamNumber ); - -#ifdef E57_MAX_VERBOSE - std::cout << " set new stream buffer for channel[" << channel.bytestreamNumber - << "], length=" << channel.currentBytestreamBufferLength << std::endl; -#endif - // ??? perform flush if new packet flag set? - } - } - else - { - // Reached end without finding data packet, mark exhausted channels as - // finished -#ifdef E57_MAX_VERBOSE - std::cout << " at end of data packets" << std::endl; -#endif - if ( nextPacketLogicalOffset >= sectionEndLogicalOffset_ ) - { - for ( DecodeChannel &channel : channels_ ) - { - // Skip channels that have already read this packet. - if ( _alreadyReadPacket( channel, currentPacketLogicalOffset ) ) - { - continue; - } - -#ifdef E57_MAX_VERBOSE - std::cout << " Marking channel[" << channel.bytestreamNumber << "] as finished" << std::endl; -#endif - channel.inputFinished = true; - } - } - } - } - - uint64_t CompressedVectorReaderImpl::findNextDataPacket( uint64_t nextPacketLogicalOffset ) - { -#ifdef E57_MAX_VERBOSE - std::cout << " searching for next data packet, nextPacketLogicalOffset=" << nextPacketLogicalOffset - << " sectionEndLogicalOffset=" << sectionEndLogicalOffset_ << std::endl; -#endif - - /// Starting at nextPacketLogicalOffset, search for next data packet until - /// hit end of binary section. - while ( nextPacketLogicalOffset < sectionEndLogicalOffset_ ) - { - char *anyPacket = nullptr; - - std::unique_ptr packetLock = cache_->lock( nextPacketLogicalOffset, anyPacket ); - - /// Guess it's a data packet, if not continue to next packet - auto dpkt = reinterpret_cast( anyPacket ); - - if ( dpkt->header.packetType == DATA_PACKET ) - { -#ifdef E57_MAX_VERBOSE - std::cout << " Found next data packet at nextPacketLogicalOffset=" << nextPacketLogicalOffset << std::endl; -#endif - return nextPacketLogicalOffset; - } - - /// All packets have length in same place, so can use the field to skip to - /// next packet. - nextPacketLogicalOffset += dpkt->header.packetLogicalLengthMinus1 + 1; - } - - /// Ran off end of section, so return failure code. - return E57_UINT64_MAX; - } - - void CompressedVectorReaderImpl::seek( uint64_t /*recordNumber*/ ) - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - ///!!! implement - throw E57_EXCEPTION1( E57_ERROR_NOT_IMPLEMENTED ); - } - - bool CompressedVectorReaderImpl::isOpen() const - { - /// don't checkImageFileOpen(__FILE__, __LINE__, __FUNCTION__), or - /// checkReaderOpen() - return ( isOpen_ ); - } - - std::shared_ptr CompressedVectorReaderImpl::compressedVectorNode() const - { - return ( cVector_ ); - } - - void CompressedVectorReaderImpl::close() - { - /// Before anything that can throw, decrement reader count - ImageFileImplSharedPtr imf( cVector_->destImageFile_ ); - imf->decrReaderCount(); - - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - /// No error if reader not open - if ( !isOpen_ ) - { - return; - } - - /// Destroy decoders - channels_.clear(); - - delete cache_; - cache_ = nullptr; - - isOpen_ = false; - } - - void CompressedVectorReaderImpl::checkImageFileOpen( const char *srcFileName, int srcLineNumber, - const char *srcFunctionName ) const - { - // unimplemented... - (void)srcFileName; (void)srcLineNumber; (void)srcFunctionName; - } - - void CompressedVectorReaderImpl::checkReaderOpen( const char *srcFileName, int srcLineNumber, - const char *srcFunctionName ) const - { - if ( !isOpen_ ) - { - throw E57Exception( E57_ERROR_READER_NOT_OPEN, - "imageFileName=" + cVector_->imageFileName() + " cvPathName=" + cVector_->pathName(), - srcFileName, srcLineNumber, srcFunctionName ); - } - } - -#ifdef E57_DEBUG - void CompressedVectorReaderImpl::dump( int indent, std::ostream &os ) - { - os << space( indent ) << "isOpen:" << isOpen_ << std::endl; - - for ( unsigned i = 0; i < dbufs_.size(); i++ ) - { - os << space( indent ) << "dbufs[" << i << "]:" << std::endl; - dbufs_[i].dump( indent + 4, os ); - } - - os << space( indent ) << "cVector:" << std::endl; - cVector_->dump( indent + 4, os ); - - os << space( indent ) << "proto:" << std::endl; - proto_->dump( indent + 4, os ); - - for ( unsigned i = 0; i < channels_.size(); i++ ) - { - os << space( indent ) << "channels[" << i << "]:" << std::endl; - channels_[i].dump( indent + 4, os ); - } - - os << space( indent ) << "recordCount: " << recordCount_ << std::endl; - os << space( indent ) << "maxRecordCount: " << maxRecordCount_ << std::endl; - os << space( indent ) << "sectionEndLogicalOffset: " << sectionEndLogicalOffset_ << std::endl; - } -#endif - -} diff --git a/src/3rdParty/libE57Format/src/CompressedVectorReaderImpl.h b/src/3rdParty/libE57Format/src/CompressedVectorReaderImpl.h deleted file mode 100644 index 7e289ae9da..0000000000 --- a/src/3rdParty/libE57Format/src/CompressedVectorReaderImpl.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "DecodeChannel.h" - -namespace e57 -{ - class DataPacket; - class PacketReadCache; - - class CompressedVectorReaderImpl - { - public: - CompressedVectorReaderImpl( std::shared_ptr ni, std::vector &dbufs ); - ~CompressedVectorReaderImpl(); - unsigned read(); - unsigned read( std::vector &dbufs ); - void seek( uint64_t recordNumber ); - bool isOpen() const; - std::shared_ptr compressedVectorNode() const; - void close(); - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ); -#endif - - private: - void checkImageFileOpen( const char *srcFileName, int srcLineNumber, const char *srcFunctionName ) const; - void checkReaderOpen( const char *srcFileName, int srcLineNumber, const char *srcFunctionName ) const; - void setBuffers( std::vector &dbufs ); //???needed? - uint64_t earliestPacketNeededForInput() const; - - DataPacket *dataPacket( uint64_t inLogicalOffset ) const; - void feedPacketToDecoders( uint64_t currentPacketLogicalOffset ); - uint64_t findNextDataPacket( uint64_t nextPacketLogicalOffset ); - - //??? no default ctor, copy, assignment? - - bool isOpen_; - std::vector dbufs_; - std::shared_ptr cVector_; - NodeImplSharedPtr proto_; - std::vector channels_; - PacketReadCache *cache_; - - uint64_t recordCount_; /// number of records written so far - uint64_t maxRecordCount_; - uint64_t sectionEndLogicalOffset_; - }; -} diff --git a/src/3rdParty/libE57Format/src/CompressedVectorWriterImpl.cpp b/src/3rdParty/libE57Format/src/CompressedVectorWriterImpl.cpp deleted file mode 100644 index c57da72d63..0000000000 --- a/src/3rdParty/libE57Format/src/CompressedVectorWriterImpl.cpp +++ /dev/null @@ -1,661 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include - -#include "CheckedFile.h" -#include "CompressedVectorNodeImpl.h" -#include "CompressedVectorWriterImpl.h" -#include "ImageFileImpl.h" -#include "SectionHeaders.h" -#include "SourceDestBufferImpl.h" - -namespace e57 -{ - struct SortByBytestreamNumber - { - bool operator()( const std::shared_ptr &lhs, const std::shared_ptr &rhs ) const - { - return ( lhs->bytestreamNumber() < rhs->bytestreamNumber() ); - } - }; - - CompressedVectorWriterImpl::CompressedVectorWriterImpl( std::shared_ptr ni, - std::vector &sbufs ) : - cVector_( ni ), - isOpen_( false ) // set to true when succeed below - { - //??? check if cvector already been written (can't write twice) - - /// Empty sbufs is an error - if ( sbufs.empty() ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_API_ARGUMENT, - "imageFileName=" + cVector_->imageFileName() + " cvPathName=" + cVector_->pathName() ); - } - - /// Get CompressedArray's prototype node (all array elements must match this - /// type) - proto_ = cVector_->getPrototype(); - - /// Check sbufs well formed (matches proto exactly) - setBuffers( sbufs ); //??? copy code here? - - /// For each individual sbuf, create an appropriate Encoder based on the - /// cVector_ attributes - for ( unsigned i = 0; i < sbufs_.size(); i++ ) - { - /// Create vector of single sbuf ??? for now, may have groups later - std::vector vTemp; - vTemp.push_back( sbufs_.at( i ) ); - - ustring codecPath = sbufs_.at( i ).pathName(); - - /// Calc which stream the given path belongs to. This depends on position - /// of the node in the proto tree. - NodeImplSharedPtr readNode = proto_->get( sbufs.at( i ).pathName() ); - uint64_t bytestreamNumber = 0; - if ( !proto_->findTerminalPosition( readNode, bytestreamNumber ) ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "sbufIndex=" + toString( i ) ); - } - - /// EncoderFactory picks the appropriate encoder to match type declared in - /// prototype - bytestreams_.push_back( - Encoder::EncoderFactory( static_cast( bytestreamNumber ), cVector_, vTemp, codecPath ) ); - } - - /// The bytestreams_ vector must be ordered by bytestreamNumber, not by order - /// called specified sbufs, so sort it. - sort( bytestreams_.begin(), bytestreams_.end(), SortByBytestreamNumber() ); -#ifdef E57_MAX_DEBUG - /// Double check that all bytestreams are specified - for ( unsigned i = 0; i < bytestreams_.size(); i++ ) - { - if ( bytestreams_.at( i )->bytestreamNumber() != i ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "bytestreamIndex=" + toString( i ) + " bytestreamNumber=" + - toString( bytestreams_.at( i )->bytestreamNumber() ) ); - } - } -#endif - - ImageFileImplSharedPtr imf( ni->destImageFile_ ); - - /// Reserve space for CompressedVector binary section header, record location - /// so can save to when writer closes. Request that file be extended with - /// zeros since we will write to it at a later time (when writer closes). - sectionHeaderLogicalStart_ = imf->allocateSpace( sizeof( CompressedVectorSectionHeader ), true ); - - sectionLogicalLength_ = 0; - dataPhysicalOffset_ = 0; - topIndexPhysicalOffset_ = 0; - recordCount_ = 0; - dataPacketsCount_ = 0; - indexPacketsCount_ = 0; - - /// Just before return (and can't throw) increment writer count ??? safer - /// way to assure don't miss close? - imf->incrWriterCount(); - - /// If get here, the writer is open - isOpen_ = true; - } - - CompressedVectorWriterImpl::~CompressedVectorWriterImpl() - { -#ifdef E57_MAX_VERBOSE - std::cout << "~CompressedVectorWriterImpl() called" << std::endl; //??? -#endif - - try - { - if ( isOpen_ ) - { - close(); - } - } - catch ( ... ) - { - //??? report? - } - } - - void CompressedVectorWriterImpl::close() - { -#ifdef E57_MAX_VERBOSE - std::cout << "CompressedVectorWriterImpl::close() called" << std::endl; //??? -#endif - ImageFileImplSharedPtr imf( cVector_->destImageFile_ ); - - /// Before anything that can throw, decrement writer count - imf->decrWriterCount(); - - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - /// don't call checkWriterOpen(); - - if ( !isOpen_ ) - { - return; - } - - /// Set closed before do anything, so if get fault and start unwinding, don't - /// try to close again. - isOpen_ = false; - - /// If have any data, write packet - /// Write all remaining ioBuffers and internal encoder register cache into - /// file. Know we are done when totalOutputAvailable() returns 0 after a - /// flush(). - flush(); - while ( totalOutputAvailable() > 0 ) - { - packetWrite(); - flush(); - } - - /// Compute length of whole section we just wrote (from section start to - /// current start of free space). - sectionLogicalLength_ = imf->unusedLogicalStart_ - sectionHeaderLogicalStart_; -#ifdef E57_MAX_VERBOSE - std::cout << " sectionLogicalLength_=" << sectionLogicalLength_ << std::endl; //??? -#endif - - /// Prepare CompressedVectorSectionHeader - CompressedVectorSectionHeader header; - header.sectionLogicalLength = sectionLogicalLength_; - header.dataPhysicalOffset = dataPhysicalOffset_; ///??? can be zero, if no data written ???not set yet - header.indexPhysicalOffset = topIndexPhysicalOffset_; ///??? can be zero, if no data written ???not set - /// yet -#ifdef E57_MAX_VERBOSE - std::cout << " CompressedVectorSectionHeader:" << std::endl; - header.dump( 4 ); //??? -#endif -#ifdef E57_DEBUG - /// Verify OK before write it. - header.verify( imf->file_->length( CheckedFile::Physical ) ); -#endif - - /// Write header at beginning of section, previously allocated - imf->file_->seek( sectionHeaderLogicalStart_ ); - imf->file_->write( reinterpret_cast( &header ), sizeof( header ) ); - - /// Set address and size of associated CompressedVector - cVector_->setRecordCount( recordCount_ ); - cVector_->setBinarySectionLogicalStart( sectionHeaderLogicalStart_ ); - - /// Free channels - bytestreams_.clear(); - -#ifdef E57_MAX_VERBOSE - std::cout << " CompressedVectorWriter:" << std::endl; - dump( 4 ); -#endif - } - - bool CompressedVectorWriterImpl::isOpen() const - { - /// don't checkImageFileOpen(__FILE__, __LINE__, __FUNCTION__), or - /// checkWriterOpen() - return isOpen_; - } - - std::shared_ptr CompressedVectorWriterImpl::compressedVectorNode() const - { - return cVector_; - } - - void CompressedVectorWriterImpl::setBuffers( std::vector &sbufs ) - { - /// don't checkImageFileOpen - - /// If had previous sbufs_, check to see if new ones have changed in - /// incompatible way - if ( !sbufs_.empty() ) - { - if ( sbufs_.size() != sbufs.size() ) - { - throw E57_EXCEPTION2( E57_ERROR_BUFFERS_NOT_COMPATIBLE, - "oldSize=" + toString( sbufs_.size() ) + " newSize=" + toString( sbufs.size() ) ); - } - - for ( size_t i = 0; i < sbufs_.size(); ++i ) - { - std::shared_ptr oldbuf = sbufs_[i].impl(); - std::shared_ptr newBuf = sbufs[i].impl(); - - /// Throw exception if old and new not compatible - oldbuf->checkCompatible( newBuf ); - } - } - - /// Check sbufs well formed: no dups, no missing, no extra - /// For writing, all data fields in prototype must be presented for writing - /// at same time. - proto_->checkBuffers( sbufs, false ); - - sbufs_ = sbufs; - } - - void CompressedVectorWriterImpl::write( std::vector &sbufs, const size_t requestedRecordCount ) - { - /// don't checkImageFileOpen, write(unsigned) will do it - /// don't checkWriterOpen(), write(unsigned) will do it - - setBuffers( sbufs ); - write( requestedRecordCount ); - } - - void CompressedVectorWriterImpl::write( const size_t requestedRecordCount ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "CompressedVectorWriterImpl::write() called" << std::endl; //??? -#endif - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - checkWriterOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - /// Check that requestedRecordCount is not larger than the sbufs - if ( requestedRecordCount > sbufs_.at( 0 ).impl()->capacity() ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_API_ARGUMENT, - "requested=" + toString( requestedRecordCount ) + - " capacity=" + toString( sbufs_.at( 0 ).impl()->capacity() ) + " imageFileName=" + - cVector_->imageFileName() + " cvPathName=" + cVector_->pathName() ); - } - - /// Rewind all sbufs so start reading from beginning - for ( auto &sbuf : sbufs_ ) - { - sbuf.impl()->rewind(); - } - - /// Loop until all channels have completed requestedRecordCount transfers - uint64_t endRecordIndex = recordCount_ + requestedRecordCount; - while ( true ) - { - /// Calc remaining record counts for all channels - uint64_t totalRecordCount = 0; - for ( auto &bytestream : bytestreams_ ) - { - totalRecordCount += endRecordIndex - bytestream->currentRecordIndex(); - } -#ifdef E57_MAX_VERBOSE - std::cout << " totalRecordCount=" << totalRecordCount << std::endl; //??? -#endif - - /// We are done if have no more work, break out of loop - if ( totalRecordCount == 0 ) - { - break; - } - - /// Estimate how many records can write before have enough data to fill - /// data packet to efficient length Efficient packet length is >= 75% - /// of maximum packet length. It is OK if get too much data (more than - /// one packet) in an iteration. Reader will be able to handle packets - /// whose streams are not exactly synchronized to the record - /// boundaries. But try to do a good job of keeping the stream - /// synchronization "close enough" (so a reader that can cache only two - /// packets is efficient). - -#ifdef E57_MAX_VERBOSE - std::cout << " currentPacketSize()=" << currentPacketSize() << std::endl; //??? -#endif - -#ifdef E57_WRITE_CRAZY_PACKET_MODE - ///??? depends on number of streams - constexpr size_t E57_TARGET_PACKET_SIZE = 500; -#else - constexpr size_t E57_TARGET_PACKET_SIZE = ( DATA_PACKET_MAX * 3 / 4 ); -#endif - /// If have more than target fraction of packet, send it now - if ( currentPacketSize() >= E57_TARGET_PACKET_SIZE ) - { //??? - packetWrite(); - continue; /// restart loop so recalc statistics (packet size may not be - /// zero after write, if have too much data) - } - -#ifdef E57_MAX_VERBOSE - ///??? useful? - /// Get approximation of number of bytes per record of CompressedVector - /// and total of bytes used - float totalBitsPerRecord = 0; // an estimate of future performance - for ( auto &bytestream : bytestreams_ ) - { - totalBitsPerRecord += bytestream->bitsPerRecord(); - } - - const float totalBytesPerRecord = std::max( totalBitsPerRecord / 8, 0.1F ); //??? trust - - std::cout << " totalBytesPerRecord=" << totalBytesPerRecord << std::endl; //??? -#endif - - /// Don't allow straggler to get too far behind. ??? - /// Don't allow a single channel to get too far ahead ??? - /// Process channels that are furthest behind first. ??? - - ///!!!! For now just process one record per loop until packet is full - /// enough, or completed request - for ( auto &bytestream : bytestreams_ ) - { - if ( bytestream->currentRecordIndex() < endRecordIndex ) - { - //!!! For now, process up to 50 records at a time - uint64_t recordCount = endRecordIndex - bytestream->currentRecordIndex(); - recordCount = ( recordCount < 50ULL ) ? recordCount : 50ULL; // min(recordCount, 50ULL); - bytestream->processRecords( static_cast( recordCount ) ); - } - } - } - - recordCount_ += requestedRecordCount; - - /// When we leave this function, will likely still have data in channel - /// ioBuffers as well as partial words in Encoder registers. - } - - size_t CompressedVectorWriterImpl::totalOutputAvailable() const - { - size_t total = 0; - - for ( const auto &bytestream : bytestreams_ ) - { - total += bytestream->outputAvailable(); - } - - return total; - } - - size_t CompressedVectorWriterImpl::currentPacketSize() const - { - /// Calc current packet size - return ( sizeof( DataPacketHeader ) + bytestreams_.size() * sizeof( uint16_t ) + totalOutputAvailable() ); - } - - uint64_t CompressedVectorWriterImpl::packetWrite() - { -#ifdef E57_MAX_VERBOSE - std::cout << "CompressedVectorWriterImpl::packetWrite() called" << std::endl; //??? -#endif - - /// Double check that we have work to do - size_t totalOutput = totalOutputAvailable(); - if ( totalOutput == 0 ) - { - return ( 0 ); - } -#ifdef E57_MAX_VERBOSE - std::cout << " totalOutput=" << totalOutput << std::endl; //??? -#endif - - /// Calc maximum number of bytestream values can put in data packet. - size_t packetMaxPayloadBytes = - DATA_PACKET_MAX - sizeof( DataPacketHeader ) - bytestreams_.size() * sizeof( uint16_t ); -#ifdef E57_MAX_VERBOSE - std::cout << " packetMaxPayloadBytes=" << packetMaxPayloadBytes << std::endl; //??? -#endif - - /// Allocate vector for number of bytes that each bytestream will write to - /// file. - std::vector count( bytestreams_.size() ); - - /// See if we can fit into a single data packet - if ( totalOutput < packetMaxPayloadBytes ) - { - /// We can fit everything in one packet - for ( unsigned i = 0; i < bytestreams_.size(); i++ ) - { - count.at( i ) = bytestreams_.at( i )->outputAvailable(); - } - } - else - { - /// We have too much data for one packet. Send proportional amounts from - /// each bytestream. Adjust packetMaxPayloadBytes down by one so have a - /// little slack for floating point weirdness. - float fractionToSend = ( packetMaxPayloadBytes - 1 ) / static_cast( totalOutput ); - for ( unsigned i = 0; i < bytestreams_.size(); i++ ) - { - /// Round down here so sum <= packetMaxPayloadBytes - count.at( i ) = - static_cast( std::floor( fractionToSend * bytestreams_.at( i )->outputAvailable() ) ); - } - } -#ifdef E57_MAX_VERBOSE - for ( unsigned i = 0; i < bytestreams_.size(); i++ ) - { - std::cout << " count[" << i << "]=" << count.at( i ) << std::endl; //??? - } -#endif - -#ifdef E57_DEBUG - /// Double check sum of count is <= packetMaxPayloadBytes - const size_t totalByteCount = std::accumulate( count.begin(), count.end(), 0 ); - - if ( totalByteCount > packetMaxPayloadBytes ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "totalByteCount=" + toString( totalByteCount ) + - " packetMaxPayloadBytes=" + toString( packetMaxPayloadBytes ) ); - } -#endif - - /// Get smart pointer to ImageFileImpl from associated CompressedVector - ImageFileImplSharedPtr imf( cVector_->destImageFile_ ); - - /// Use temp buf in object (is 64KBytes long) instead of allocating each time - /// here - char *packet = reinterpret_cast( &dataPacket_ ); -#ifdef E57_MAX_VERBOSE - std::cout << " packet=" << packet << std::endl; //??? -#endif - - /// To be safe, clear header part of packet - dataPacket_.header.reset(); - - /// Write bytestreamBufferLength[bytestreamCount] after header, in - /// dataPacket_ - auto bsbLength = reinterpret_cast( &packet[sizeof( DataPacketHeader )] ); -#ifdef E57_MAX_VERBOSE - std::cout << " bsbLength=" << bsbLength << std::endl; //??? -#endif - for ( unsigned i = 0; i < bytestreams_.size(); i++ ) - { - bsbLength[i] = static_cast( count.at( i ) ); // %%% Truncation -#ifdef E57_MAX_VERBOSE - std::cout << " Writing " << bsbLength[i] << " bytes into bytestream " << i << std::endl; //??? -#endif - } - - /// Get pointer to end of data so far - char *p = reinterpret_cast( &bsbLength[bytestreams_.size()] ); -#ifdef E57_MAX_VERBOSE - std::cout << " after bsbLength, p=" << p << std::endl; //??? -#endif - - /// Write contents of each bytestream in dataPacket_ - for ( size_t i = 0; i < bytestreams_.size(); i++ ) - { - size_t n = count.at( i ); - -#ifdef E57_DEBUG - /// Double check we aren't accidentally going to write off end of - /// vector - if ( &p[n] > &packet[DATA_PACKET_MAX] ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "n=" + toString( n ) ); - } -#endif - - /// Read from encoder output into packet - bytestreams_.at( i )->outputRead( p, n ); - - /// Move pointer to end of current data - p += n; - } - - /// Length of packet is difference in beginning pointer and ending pointer - auto packetLength = static_cast( p - packet ); ///??? pointer diff portable? -#ifdef E57_MAX_VERBOSE - std::cout << " packetLength=" << packetLength << std::endl; //??? -#endif - -#ifdef E57_DEBUG - /// Double check that packetLength is what we expect - if ( packetLength != sizeof( DataPacketHeader ) + bytestreams_.size() * sizeof( uint16_t ) + totalByteCount ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "packetLength=" + toString( packetLength ) + " bytestreamSize=" + - toString( bytestreams_.size() * sizeof( uint16_t ) ) + - " totalByteCount=" + toString( totalByteCount ) ); - } -#endif - - /// packetLength must be multiple of 4, if not, add some zero padding - while ( packetLength % 4 ) - { - /// Double check we aren't accidentally going to write off end of - /// vector - if ( p >= &packet[DATA_PACKET_MAX - 1] ) - { - throw E57_EXCEPTION1( E57_ERROR_INTERNAL ); - } - *p++ = 0; - packetLength++; -#ifdef E57_MAX_VERBOSE - std::cout << " padding with zero byte, new packetLength=" << packetLength << std::endl; //??? -#endif - } - - /// Prepare header in dataPacket_, now that we are sure of packetLength - dataPacket_.header.packetLogicalLengthMinus1 = static_cast( packetLength - 1 ); // %%% Truncation - dataPacket_.header.bytestreamCount = static_cast( bytestreams_.size() ); // %%% Truncation - - /// Double check that data packet is well formed - dataPacket_.verify( packetLength ); - - /// Write whole data packet at beginning of free space in file - uint64_t packetLogicalOffset = imf->allocateSpace( packetLength, false ); - uint64_t packetPhysicalOffset = imf->file_->logicalToPhysical( packetLogicalOffset ); - imf->file_->seek( packetLogicalOffset ); //??? have seekLogical and seekPhysical instead? - // more explicit - imf->file_->write( packet, packetLength ); - -#ifdef E57_MAX_VERBOSE -// std::cout << "data packet:" << std::endl; -// dataPacket_.dump(4); -#endif - - /// If first data packet written for this CompressedVector binary section, - /// save address to put in section header - ///??? what if no data packets? - ///??? what if have exceptions while write, what is state of file? will - /// close report file - /// good/bad? - if ( dataPacketsCount_ == 0 ) - { - dataPhysicalOffset_ = packetPhysicalOffset; - } - dataPacketsCount_++; - - ///!!! update seekIndex here? if started new chunk? - - /// Return physical offset of data packet for potential use in seekIndex - return ( packetPhysicalOffset ); //??? needed - } - - void CompressedVectorWriterImpl::flush() - { - for ( auto &bytestream : bytestreams_ ) - { - bytestream->registerFlushToOutput(); - } - } - - void CompressedVectorWriterImpl::checkImageFileOpen( const char *srcFileName, int srcLineNumber, - const char *srcFunctionName ) const - { - // unimplemented... - (void)srcFileName; (void)srcLineNumber; (void)srcFunctionName; - } - - void CompressedVectorWriterImpl::checkWriterOpen( const char *srcFileName, int srcLineNumber, - const char *srcFunctionName ) const - { - if ( !isOpen_ ) - { - throw E57Exception( E57_ERROR_WRITER_NOT_OPEN, - "imageFileName=" + cVector_->imageFileName() + " cvPathName=" + cVector_->pathName(), - srcFileName, srcLineNumber, srcFunctionName ); - } - } - -#ifdef E57_DEBUG - void CompressedVectorWriterImpl::dump( int indent, std::ostream &os ) - { - os << space( indent ) << "isOpen:" << isOpen_ << std::endl; - - for ( unsigned i = 0; i < sbufs_.size(); i++ ) - { - os << space( indent ) << "sbufs[" << i << "]:" << std::endl; - sbufs_.at( i ).dump( indent + 4, os ); - } - - os << space( indent ) << "cVector:" << std::endl; - cVector_->dump( indent + 4, os ); - - os << space( indent ) << "proto:" << std::endl; - proto_->dump( indent + 4, os ); - - for ( unsigned i = 0; i < bytestreams_.size(); i++ ) - { - os << space( indent ) << "bytestreams[" << i << "]:" << std::endl; - bytestreams_.at( i )->dump( indent + 4, os ); - } - - /// Don't call dump() for DataPacket, since it may contain junk when - /// debugging. Just print a few byte values. - os << space( indent ) << "dataPacket:" << std::endl; - auto p = reinterpret_cast( &dataPacket_ ); - - for ( unsigned i = 0; i < 40; ++i ) - { - os << space( indent + 4 ) << "dataPacket[" << i << "]: " << static_cast( p[i] ) << std::endl; - } - os << space( indent + 4 ) << "more unprinted..." << std::endl; - - os << space( indent ) << "sectionHeaderLogicalStart: " << sectionHeaderLogicalStart_ << std::endl; - os << space( indent ) << "sectionLogicalLength: " << sectionLogicalLength_ << std::endl; - os << space( indent ) << "dataPhysicalOffset: " << dataPhysicalOffset_ << std::endl; - os << space( indent ) << "topIndexPhysicalOffset: " << topIndexPhysicalOffset_ << std::endl; - os << space( indent ) << "recordCount: " << recordCount_ << std::endl; - os << space( indent ) << "dataPacketsCount: " << dataPacketsCount_ << std::endl; - os << space( indent ) << "indexPacketsCount: " << indexPacketsCount_ << std::endl; - } -#endif -} diff --git a/src/3rdParty/libE57Format/src/CompressedVectorWriterImpl.h b/src/3rdParty/libE57Format/src/CompressedVectorWriterImpl.h deleted file mode 100644 index 3b1808ab17..0000000000 --- a/src/3rdParty/libE57Format/src/CompressedVectorWriterImpl.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "Encoder.h" -#include "Packet.h" - -namespace e57 -{ - class CompressedVectorWriterImpl - { - public: - CompressedVectorWriterImpl( std::shared_ptr ni, std::vector &sbufs ); - ~CompressedVectorWriterImpl(); - void write( const size_t requestedRecordCount ); - void write( std::vector &sbufs, const size_t requestedRecordCount ); - bool isOpen() const; - std::shared_ptr compressedVectorNode() const; - void close(); - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ); -#endif - - private: - void checkImageFileOpen( const char *srcFileName, int srcLineNumber, const char *srcFunctionName ) const; - void checkWriterOpen( const char *srcFileName, int srcLineNumber, const char *srcFunctionName ) const; - void setBuffers( std::vector &sbufs ); //???needed? - size_t totalOutputAvailable() const; - size_t currentPacketSize() const; - uint64_t packetWrite(); - void flush(); - - //??? no default ctor, copy, assignment? - - std::vector sbufs_; - std::shared_ptr cVector_; - NodeImplSharedPtr proto_; - - std::vector> bytestreams_; - DataPacket dataPacket_; - - bool isOpen_; - uint64_t sectionHeaderLogicalStart_; /// start of CompressedVector binary section - uint64_t sectionLogicalLength_; /// total length of CompressedVector binary section - uint64_t dataPhysicalOffset_; /// start of first data packet - uint64_t topIndexPhysicalOffset_; /// top level index packet - uint64_t recordCount_; /// number of records written so far - uint64_t dataPacketsCount_; /// number of data packets written so far - uint64_t indexPacketsCount_; /// number of index packets written so far - }; -} diff --git a/src/3rdParty/libE57Format/src/DecodeChannel.cpp b/src/3rdParty/libE57Format/src/DecodeChannel.cpp deleted file mode 100644 index 043a7e60ba..0000000000 --- a/src/3rdParty/libE57Format/src/DecodeChannel.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "DecodeChannel.h" -#include "SourceDestBufferImpl.h" - -namespace e57 -{ - DecodeChannel::DecodeChannel( SourceDestBuffer dbuf_arg, std::shared_ptr decoder_arg, - unsigned bytestreamNumber_arg, uint64_t maxRecordCount_arg ) : - dbuf( dbuf_arg ), - decoder( decoder_arg ), bytestreamNumber( bytestreamNumber_arg ) - { - maxRecordCount = maxRecordCount_arg; - currentPacketLogicalOffset = 0; - currentBytestreamBufferIndex = 0; - currentBytestreamBufferLength = 0; - inputFinished = false; - } - - bool DecodeChannel::isOutputBlocked() const - { - /// If we have completed the entire vector, we are done - if ( decoder->totalRecordsCompleted() >= maxRecordCount ) - { - return ( true ); - } - - /// If we have filled the dest buffer, we are blocked - return ( dbuf.impl()->nextIndex() == dbuf.impl()->capacity() ); - } - - bool DecodeChannel::isInputBlocked() const - { - /// If have read until the section end, we are done - if ( inputFinished ) - { - return ( true ); - } - - /// If have eaten all the input in the current packet, we are blocked. - return ( currentBytestreamBufferIndex == currentBytestreamBufferLength ); - } - -#ifdef E57_DEBUG - void DecodeChannel::dump( int indent, std::ostream &os ) - { - os << space( indent ) << "dbuf" << std::endl; - dbuf.dump( indent + 4, os ); - - os << space( indent ) << "decoder:" << std::endl; - decoder->dump( indent + 4, os ); - - os << space( indent ) << "bytestreamNumber: " << bytestreamNumber << std::endl; - os << space( indent ) << "maxRecordCount: " << maxRecordCount << std::endl; - os << space( indent ) << "currentPacketLogicalOffset: " << currentPacketLogicalOffset << std::endl; - os << space( indent ) << "currentBytestreamBufferIndex: " << currentBytestreamBufferIndex << std::endl; - os << space( indent ) << "currentBytestreamBufferLength: " << currentBytestreamBufferLength << std::endl; - os << space( indent ) << "inputFinished: " << inputFinished << std::endl; - os << space( indent ) << "isInputBlocked(): " << isInputBlocked() << std::endl; - os << space( indent ) << "isOutputBlocked(): " << isOutputBlocked() << std::endl; - } -#endif -} diff --git a/src/3rdParty/libE57Format/src/DecodeChannel.h b/src/3rdParty/libE57Format/src/DecodeChannel.h deleted file mode 100644 index c458f0d3a7..0000000000 --- a/src/3rdParty/libE57Format/src/DecodeChannel.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "Decoder.h" - -namespace e57 -{ - class SourceDestBuffer; - - struct DecodeChannel - { - SourceDestBuffer dbuf; //??? for now, one input per channel - std::shared_ptr decoder; - unsigned bytestreamNumber; - uint64_t maxRecordCount; - uint64_t currentPacketLogicalOffset; - size_t currentBytestreamBufferIndex; - size_t currentBytestreamBufferLength; - bool inputFinished; - - DecodeChannel( SourceDestBuffer dbuf_arg, std::shared_ptr decoder_arg, unsigned bytestreamNumber_arg, - uint64_t maxRecordCount_arg ); - - bool isOutputBlocked() const; - bool isInputBlocked() const; /// has exhausted data in the current packet -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ); -#endif - }; -} diff --git a/src/3rdParty/libE57Format/src/Decoder.cpp b/src/3rdParty/libE57Format/src/Decoder.cpp deleted file mode 100644 index 48f15b13e0..0000000000 --- a/src/3rdParty/libE57Format/src/Decoder.cpp +++ /dev/null @@ -1,892 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include - -#include "CompressedVectorNodeImpl.h" -#include "Decoder.h" -#include "FloatNodeImpl.h" -#include "ImageFileImpl.h" -#include "IntegerNodeImpl.h" -#include "ScaledIntegerNodeImpl.h" -#include "SourceDestBufferImpl.h" - -using namespace e57; - -std::shared_ptr Decoder::DecoderFactory( unsigned bytestreamNumber, //!!! name ok? - const CompressedVectorNodeImpl *cVector, - std::vector &dbufs, const ustring & /*codecPath*/ ) -{ - //!!! verify single dbuf - - /// Get node we are going to decode from the CompressedVector's prototype - NodeImplSharedPtr prototype = cVector->getPrototype(); - ustring path = dbufs.at( 0 ).pathName(); - NodeImplSharedPtr decodeNode = prototype->get( path ); - -#ifdef E57_MAX_VERBOSE - std::cout << "Node to decode:" << std::endl; //??? - decodeNode->dump( 2 ); -#endif - - uint64_t maxRecordCount = cVector->childCount(); - - switch ( decodeNode->type() ) - { - case E57_INTEGER: - { - std::shared_ptr ini = - std::static_pointer_cast( decodeNode ); // downcast to correct type - - /// Get pointer to parent ImageFileImpl, to call bitsNeeded() - ImageFileImplSharedPtr imf( decodeNode->destImageFile_ ); //??? should be function for this, - // imf->parentFile() - //--> ImageFile? - - unsigned bitsPerRecord = imf->bitsNeeded( ini->minimum(), ini->maximum() ); - - //!!! need to pick smarter channel buffer sizes, here and elsewhere - /// Constuct Integer decoder with appropriate register size, based on - /// number of bits stored. - if ( bitsPerRecord == 0 ) - { - std::shared_ptr decoder( new ConstantIntegerDecoder( false, bytestreamNumber, dbufs.at( 0 ), - ini->minimum(), 1.0, 0.0, maxRecordCount ) ); - return decoder; - } - - if ( bitsPerRecord <= 8 ) - { - std::shared_ptr decoder( new BitpackIntegerDecoder( - false, bytestreamNumber, dbufs.at( 0 ), ini->minimum(), ini->maximum(), 1.0, 0.0, maxRecordCount ) ); - return decoder; - } - - if ( bitsPerRecord <= 16 ) - { - std::shared_ptr decoder( new BitpackIntegerDecoder( - false, bytestreamNumber, dbufs.at( 0 ), ini->minimum(), ini->maximum(), 1.0, 0.0, maxRecordCount ) ); - return decoder; - } - - if ( bitsPerRecord <= 32 ) - { - std::shared_ptr decoder( new BitpackIntegerDecoder( - false, bytestreamNumber, dbufs.at( 0 ), ini->minimum(), ini->maximum(), 1.0, 0.0, maxRecordCount ) ); - return decoder; - } - - std::shared_ptr decoder( new BitpackIntegerDecoder( - false, bytestreamNumber, dbufs.at( 0 ), ini->minimum(), ini->maximum(), 1.0, 0.0, maxRecordCount ) ); - return decoder; - } - - case E57_SCALED_INTEGER: - { - std::shared_ptr sini = - std::static_pointer_cast( decodeNode ); // downcast to correct type - - /// Get pointer to parent ImageFileImpl, to call bitsNeeded() - ImageFileImplSharedPtr imf( decodeNode->destImageFile_ ); //??? should be function for this, - // imf->parentFile() - //--> ImageFile? - - unsigned bitsPerRecord = imf->bitsNeeded( sini->minimum(), sini->maximum() ); - - //!!! need to pick smarter channel buffer sizes, here and elsewhere - /// Construct ScaledInteger dencoder with appropriate register size, - /// based on number of bits stored. - if ( bitsPerRecord == 0 ) - { - std::shared_ptr decoder( new ConstantIntegerDecoder( true, bytestreamNumber, dbufs.at( 0 ), - sini->minimum(), sini->scale(), - sini->offset(), maxRecordCount ) ); - return decoder; - } - - if ( bitsPerRecord <= 8 ) - { - std::shared_ptr decoder( - new BitpackIntegerDecoder( true, bytestreamNumber, dbufs.at( 0 ), sini->minimum(), - sini->maximum(), sini->scale(), sini->offset(), maxRecordCount ) ); - return decoder; - } - - if ( bitsPerRecord <= 16 ) - { - std::shared_ptr decoder( - new BitpackIntegerDecoder( true, bytestreamNumber, dbufs.at( 0 ), sini->minimum(), - sini->maximum(), sini->scale(), sini->offset(), maxRecordCount ) ); - return decoder; - } - - if ( bitsPerRecord <= 32 ) - { - std::shared_ptr decoder( - new BitpackIntegerDecoder( true, bytestreamNumber, dbufs.at( 0 ), sini->minimum(), - sini->maximum(), sini->scale(), sini->offset(), maxRecordCount ) ); - return decoder; - } - - std::shared_ptr decoder( - new BitpackIntegerDecoder( true, bytestreamNumber, dbufs.at( 0 ), sini->minimum(), - sini->maximum(), sini->scale(), sini->offset(), maxRecordCount ) ); - return decoder; - } - - case E57_FLOAT: - { - std::shared_ptr fni = - std::static_pointer_cast( decodeNode ); // downcast to correct type - - std::shared_ptr decoder( - new BitpackFloatDecoder( bytestreamNumber, dbufs.at( 0 ), fni->precision(), maxRecordCount ) ); - return decoder; - } - - case E57_STRING: - { - std::shared_ptr decoder( - new BitpackStringDecoder( bytestreamNumber, dbufs.at( 0 ), maxRecordCount ) ); - - return decoder; - } - - default: - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PROTOTYPE, "nodeType=" + toString( decodeNode->type() ) ); - } - } -} - -Decoder::Decoder( unsigned bytestreamNumber ) : bytestreamNumber_( bytestreamNumber ) -{ -} - -BitpackDecoder::BitpackDecoder( unsigned bytestreamNumber, SourceDestBuffer &dbuf, unsigned alignmentSize, - uint64_t maxRecordCount ) : - Decoder( bytestreamNumber ), - maxRecordCount_( maxRecordCount ), destBuffer_( dbuf.impl() ), - inBuffer_( 1024 ), //!!! need to pick smarter channel buffer sizes - inBufferAlignmentSize_( alignmentSize ), bitsPerWord_( 8 * alignmentSize ), bytesPerWord_( alignmentSize ) -{ -} - -void BitpackDecoder::destBufferSetNew( std::vector &dbufs ) -{ - if ( dbufs.size() != 1 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "dbufsSize=" + toString( dbufs.size() ) ); - } - - destBuffer_ = dbufs.at( 0 ).impl(); -} - -size_t BitpackDecoder::inputProcess( const char *source, const size_t availableByteCount ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "BitpackDecoder::inputprocess() called, source=" << ( source ? source : "none" ) - << " availableByteCount=" << availableByteCount << std::endl; -#endif - size_t bytesUnsaved = availableByteCount; - size_t bitsEaten = 0; - do - { - size_t byteCount = std::min( bytesUnsaved, inBuffer_.size() - static_cast( inBufferEndByte_ ) ); - - /// Copy input bytes from caller, if any - if ( ( byteCount > 0 ) && source ) - { - memcpy( &inBuffer_[inBufferEndByte_], source, byteCount ); - - /// Advance tail pointer. - inBufferEndByte_ += byteCount; - - /// Update amount available from caller - bytesUnsaved -= byteCount; - source += byteCount; - } -#ifdef E57_MAX_VERBOSE - { - unsigned i; - unsigned firstByte = inBufferFirstBit_ / 8; - for ( i = 0; i < byteCount && i < 20; i++ ) - { - std::cout << " inBuffer[" << firstByte + i << "]=" << (unsigned)(unsigned char)( inBuffer_[firstByte + i] ) - << std::endl; - } - if ( i < byteCount ) - { - std::cout << " " << byteCount - i << "source bytes unprinted..." << std::endl; - } - } -#endif - - /// ??? fix doc for new bit interface - /// Now that we have input stored in an aligned buffer, call derived class - /// to try to eat some Note that end of filled buffer may not be at a - /// natural boundary. The subclass may transfer this partial word in a - /// full word transfer, but it must be done carefully to only use the defined - /// bits. inBuffer_ is a multiple of largest word size, so this full word - /// transfer off the end will always be in defined memory. - - size_t firstWord = inBufferFirstBit_ / bitsPerWord_; - size_t firstNaturalBit = firstWord * bitsPerWord_; - size_t endBit = inBufferEndByte_ * 8; -#ifdef E57_MAX_VERBOSE - std::cout << " feeding aligned decoder " << endBit - inBufferFirstBit_ << " bits." << std::endl; -#endif - bitsEaten = inputProcessAligned( &inBuffer_[firstWord * bytesPerWord_], inBufferFirstBit_ - firstNaturalBit, - endBit - firstNaturalBit ); -#ifdef E57_MAX_VERBOSE - std::cout << " bitsEaten=" << bitsEaten << " firstWord=" << firstWord << " firstNaturalBit=" << firstNaturalBit - << " endBit=" << endBit << std::endl; -#endif -#ifdef E57_DEBUG - if ( bitsEaten > endBit - inBufferFirstBit_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "bitsEaten=" + toString( bitsEaten ) + - " endBit=" + toString( endBit ) + - " inBufferFirstBit=" + toString( inBufferFirstBit_ ) ); - } -#endif - inBufferFirstBit_ += bitsEaten; - - /// Shift uneaten data to beginning of inBuffer_, keep on natural word - /// boundaries. - inBufferShiftDown(); - - /// If the lower level processing didn't eat anything on this iteration, - /// stop looping and tell caller how much we ate or stored. - } while ( bytesUnsaved > 0 && bitsEaten > 0 ); - - /// Return the number of bytes we ate/saved. - return ( availableByteCount - bytesUnsaved ); -} - -void BitpackDecoder::stateReset() -{ - inBufferFirstBit_ = 0; - inBufferEndByte_ = 0; -} - -void BitpackDecoder::inBufferShiftDown() -{ - /// Move uneaten data down to beginning of inBuffer_. - /// Keep on natural boundaries. - /// Moves all of word that contains inBufferFirstBit. - size_t firstWord = inBufferFirstBit_ / bitsPerWord_; - size_t firstNaturalByte = firstWord * bytesPerWord_; -#ifdef E57_DEBUG - if ( firstNaturalByte > inBufferEndByte_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "firstNaturalByte=" + toString( firstNaturalByte ) + - " inBufferEndByte=" + toString( inBufferEndByte_ ) ); - } -#endif - size_t byteCount = inBufferEndByte_ - firstNaturalByte; - if ( byteCount > 0 ) - { - memmove( &inBuffer_[0], &inBuffer_[firstNaturalByte], - byteCount ); /// Overlapping regions ok with memmove(). - } - - /// Update indexes - inBufferEndByte_ = byteCount; - inBufferFirstBit_ = inBufferFirstBit_ % bitsPerWord_; -} - -#ifdef E57_DEBUG -void BitpackDecoder::dump( int indent, std::ostream &os ) -{ - os << space( indent ) << "bytestreamNumber: " << bytestreamNumber_ << std::endl; - os << space( indent ) << "currentRecordIndex: " << currentRecordIndex_ << std::endl; - os << space( indent ) << "maxRecordCount: " << maxRecordCount_ << std::endl; - os << space( indent ) << "destBuffer:" << std::endl; - destBuffer_->dump( indent + 4, os ); - os << space( indent ) << "inBufferFirstBit: " << inBufferFirstBit_ << std::endl; - os << space( indent ) << "inBufferEndByte: " << inBufferEndByte_ << std::endl; - os << space( indent ) << "inBufferAlignmentSize: " << inBufferAlignmentSize_ << std::endl; - os << space( indent ) << "bitsPerWord: " << bitsPerWord_ << std::endl; - os << space( indent ) << "bytesPerWord: " << bytesPerWord_ << std::endl; - os << space( indent ) << "inBuffer:" << std::endl; - unsigned i; - for ( i = 0; i < inBuffer_.size() && i < 20; i++ ) - { - os << space( indent + 4 ) << "inBuffer[" << i - << "]: " << static_cast( static_cast( inBuffer_.at( i ) ) ) << std::endl; - } - if ( i < inBuffer_.size() ) - { - os << space( indent + 4 ) << inBuffer_.size() - i << " more unprinted..." << std::endl; - } -} -#endif - -//================================================================ - -BitpackFloatDecoder::BitpackFloatDecoder( unsigned bytestreamNumber, SourceDestBuffer &dbuf, FloatPrecision precision, - uint64_t maxRecordCount ) : - BitpackDecoder( bytestreamNumber, dbuf, ( precision == E57_SINGLE ) ? sizeof( float ) : sizeof( double ), - maxRecordCount ), - precision_( precision ) -{ -} - -size_t BitpackFloatDecoder::inputProcessAligned( const char *inbuf, const size_t firstBit, const size_t endBit ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "BitpackFloatDecoder::inputProcessAligned() called, inbuf=" << inbuf << " firstBit=" << firstBit - << " endBit=" << endBit << std::endl; -#endif - /// Read from inbuf, decode, store in destBuffer - /// Repeat until have filled destBuffer, or completed all records - - size_t n = destBuffer_->capacity() - destBuffer_->nextIndex(); - - size_t typeSize = ( precision_ == E57_SINGLE ) ? sizeof( float ) : sizeof( double ); - -#ifdef E57_DEBUG -#if 0 // I know no way to do this portably - // Deactivate for now until a better solution is found. - /// Verify that inbuf is naturally aligned to correct boundary (4 or 8 bytes). Base class should be doing this for us. - if (reinterpret_cast(inbuf) % typeSize) { - throw E57_EXCEPTION2(E57_ERROR_INTERNAL, - "inbuf=" + toString(reinterpret_cast(inbuf)) - + " typeSize=" + toString(typeSize)); - } -#endif - /// Verify first bit is zero - if ( firstBit != 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "firstBit=" + toString( firstBit ) ); - } -#endif - - /// Calc how many whole records worth of data we have in inbuf - size_t maxInputRecords = ( endBit - firstBit ) / ( 8 * typeSize ); - - /// Can't process more records than we have input data for. - if ( n > maxInputRecords ) - { - n = maxInputRecords; - } - - // Can't process more than defined in input file - if ( n > maxRecordCount_ - currentRecordIndex_ ) - { - n = static_cast( maxRecordCount_ - currentRecordIndex_ ); - } - -#ifdef E57_MAX_VERBOSE - std::cout << " n:" << n << std::endl; //??? -#endif - - if ( precision_ == E57_SINGLE ) - { - /// Form the starting address for first data location in inBuffer - auto inp = reinterpret_cast( inbuf ); - - /// Copy floats from inbuf to destBuffer_ - for ( unsigned i = 0; i < n; i++ ) - { - float value = *inp; - -#ifdef E57_MAX_VERBOSE - std::cout << " got float value=" << value << std::endl; -#endif - destBuffer_->setNextFloat( value ); - inp++; - } - } - else - { /// E57_DOUBLE precision - /// Form the starting address for first data location in inBuffer - auto inp = reinterpret_cast( inbuf ); - - /// Copy doubles from inbuf to destBuffer_ - for ( unsigned i = 0; i < n; i++ ) - { - double value = *inp; - -#ifdef E57_MAX_VERBOSE - std::cout << " got double value=" << value << std::endl; -#endif - destBuffer_->setNextDouble( value ); - inp++; - } - } - - /// Update counts of records processed - currentRecordIndex_ += n; - - /// Returned number of bits processed (always a multiple of alignment size). - return ( n * 8 * typeSize ); -} - -#ifdef E57_DEBUG -void BitpackFloatDecoder::dump( int indent, std::ostream &os ) -{ - BitpackDecoder::dump( indent, os ); - if ( precision_ == E57_SINGLE ) - { - os << space( indent ) << "precision: E57_SINGLE" << std::endl; - } - else - { - os << space( indent ) << "precision: E57_DOUBLE" << std::endl; - } -} -#endif - -//================================================================ - -BitpackStringDecoder::BitpackStringDecoder( unsigned bytestreamNumber, SourceDestBuffer &dbuf, - uint64_t maxRecordCount ) : - BitpackDecoder( bytestreamNumber, dbuf, sizeof( char ), maxRecordCount ) -{ -} - -size_t BitpackStringDecoder::inputProcessAligned( const char *inbuf, const size_t firstBit, const size_t endBit ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "BitpackStringDecoder::inputProcessAligned() called, inbuf=" << inbuf << " firstBit=" << firstBit - << " endBit=" << endBit << std::endl; -#endif - /// Read from inbuf, decode, store in destBuffer - /// Repeat until have filled destBuffer, or completed all records - -#ifdef E57_DEBUG - /// Verify first bit is zero (always byte-aligned) - if ( firstBit != 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "firstBit=" + toString( firstBit ) ); - } -#endif - - /// Converts start/end bits to whole bytes - size_t nBytesAvailable = ( endBit - firstBit ) >> 3; - size_t nBytesRead = 0; - - /// Loop until we've finished all the records, or ran out of input currently - /// available - while ( currentRecordIndex_ < maxRecordCount_ && nBytesRead < nBytesAvailable ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "read string loop1: readingPrefix=" << readingPrefix_ << " prefixLength=" << prefixLength_ - << " nBytesPrefixRead=" << nBytesPrefixRead_ << " nBytesStringRead=" << nBytesStringRead_ << std::endl; -#endif - if ( readingPrefix_ ) - { - /// Try to read more prefix bytes - while ( nBytesRead < nBytesAvailable && ( nBytesPrefixRead_ == 0 || nBytesPrefixRead_ < prefixLength_ ) ) - { - /// If first byte of prefix, test the least significant bit to see - /// how long prefix is - if ( nBytesPrefixRead_ == 0 ) - { - if ( *inbuf & 0x01 ) - { - prefixLength_ = 8; // 8 byte prefix, length up to 2^63-1 - } - else - { - prefixLength_ = 1; // 1 byte prefix, length up to 2^7-1 - } - } - - /// Accumulate prefix bytes - prefixBytes_[nBytesPrefixRead_] = *inbuf++; - nBytesPrefixRead_++; - nBytesRead++; - } - -#ifdef E57_MAX_VERBOSE - std::cout << "read string loop2: readingPrefix=" << readingPrefix_ << " prefixLength=" << prefixLength_ - << " nBytesPrefixRead=" << nBytesPrefixRead_ << " nBytesStringRead=" << nBytesStringRead_ - << std::endl; -#endif - /// If got all of prefix, convert to length and get ready to read - /// string - if ( nBytesPrefixRead_ > 0 && nBytesPrefixRead_ == prefixLength_ ) - { - if ( prefixLength_ == 1 ) - { - /// Single byte prefix, extract length from b7-b1. - /// Removing the least significant bit (which says this is a - /// short prefix). - stringLength_ = static_cast( prefixBytes_[0] >> 1 ); - } - else - { - /// Eight byte prefix, extract length from b63-b1. Little endian - /// ordering. Removing the least significant bit (which says this - /// is a long prefix). - stringLength_ = ( static_cast( prefixBytes_[0] ) >> 1 ) + - ( static_cast( prefixBytes_[1] ) << ( 1 * 8 - 1 ) ) + - ( static_cast( prefixBytes_[2] ) << ( 2 * 8 - 1 ) ) + - ( static_cast( prefixBytes_[3] ) << ( 3 * 8 - 1 ) ) + - ( static_cast( prefixBytes_[4] ) << ( 4 * 8 - 1 ) ) + - ( static_cast( prefixBytes_[5] ) << ( 5 * 8 - 1 ) ) + - ( static_cast( prefixBytes_[6] ) << ( 6 * 8 - 1 ) ) + - ( static_cast( prefixBytes_[7] ) << ( 7 * 8 - 1 ) ); - } - /// Get ready to read string contents - readingPrefix_ = false; - prefixLength_ = 1; - memset( prefixBytes_, 0, sizeof( prefixBytes_ ) ); - nBytesPrefixRead_ = 0; - currentString_ = ""; - nBytesStringRead_ = 0; - } -#ifdef E57_MAX_VERBOSE - std::cout << "read string loop3: readingPrefix=" << readingPrefix_ << " prefixLength=" << prefixLength_ - << " nBytesPrefixRead=" << nBytesPrefixRead_ << " nBytesStringRead=" << nBytesStringRead_ - << std::endl; -#endif - } - - /// If currently reading string contents, keep doing it until have - /// complete string - if ( !readingPrefix_ ) - { - /// Calc how many bytes we need to complete current string - uint64_t nBytesNeeded = stringLength_ - nBytesStringRead_; - - /// Can process the smaller of unread or needed bytes - size_t nBytesProcess = nBytesAvailable - nBytesRead; - if ( nBytesNeeded < static_cast( nBytesProcess ) ) - { - nBytesProcess = static_cast( nBytesNeeded ); - } - - /// Append to current string and update counts - currentString_ += ustring( inbuf, nBytesProcess ); - inbuf += nBytesProcess; - nBytesRead += nBytesProcess; - nBytesStringRead_ += nBytesProcess; - - /// Check if completed reading the string contents - if ( nBytesStringRead_ == stringLength_ ) - { - /// Save accumulated string to dest buffer - destBuffer_->setNextString( currentString_ ); - currentRecordIndex_++; - - /// Get ready to read next prefix - readingPrefix_ = true; - prefixLength_ = 1; - memset( prefixBytes_, 0, sizeof( prefixBytes_ ) ); - nBytesPrefixRead_ = 0; - stringLength_ = 0; - currentString_ = ""; - nBytesStringRead_ = 0; - } - } - } - - /// Returned number of bits processed (always a multiple of alignment size). - return ( nBytesRead * 8 ); -} - -#ifdef E57_DEBUG -void BitpackStringDecoder::dump( int indent, std::ostream &os ) -{ - BitpackDecoder::dump( indent, os ); - os << space( indent ) << "readingPrefix: " << readingPrefix_ << std::endl; - os << space( indent ) << "prefixLength: " << prefixLength_ << std::endl; - os << space( indent ) << "prefixBytes[8]: " << static_cast( prefixBytes_[0] ) << " " - << static_cast( prefixBytes_[1] ) << " " << static_cast( prefixBytes_[2] ) << " " - << static_cast( prefixBytes_[3] ) << " " << static_cast( prefixBytes_[4] ) << " " - << static_cast( prefixBytes_[5] ) << " " << static_cast( prefixBytes_[6] ) << " " - << static_cast( prefixBytes_[7] ) << std::endl; - os << space( indent ) << "nBytesPrefixRead: " << nBytesPrefixRead_ << std::endl; - os << space( indent ) << "stringLength: " << stringLength_ << std::endl; - os << space( indent ) - << "currentString: " - "" - << currentString_ - << "" - "" - << std::endl; - os << space( indent ) << "nBytesStringRead: " << nBytesStringRead_ << std::endl; -} -#endif - -//================================================================ - -template -BitpackIntegerDecoder::BitpackIntegerDecoder( bool isScaledInteger, unsigned bytestreamNumber, - SourceDestBuffer &dbuf, int64_t minimum, int64_t maximum, - double scale, double offset, uint64_t maxRecordCount ) : - BitpackDecoder( bytestreamNumber, dbuf, sizeof( RegisterT ), maxRecordCount ), - isScaledInteger_( isScaledInteger ), minimum_( minimum ), maximum_( maximum ), scale_( scale ), offset_( offset ) -{ - /// Get pointer to parent ImageFileImpl - ImageFileImplSharedPtr imf( dbuf.impl()->destImageFile() ); //??? should be function for this, - // imf->parentFile() --> ImageFile? - - bitsPerRecord_ = imf->bitsNeeded( minimum_, maximum_ ); - destBitMask_ = ( bitsPerRecord_ == 64 ) ? ~0 : static_cast( 1ULL << bitsPerRecord_ ) - 1; -} - -template -size_t BitpackIntegerDecoder::inputProcessAligned( const char *inbuf, const size_t firstBit, - const size_t endBit ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "BitpackIntegerDecoder::inputProcessAligned() called, inbuf=" << (void *)( inbuf ) - << " firstBit=" << firstBit << " endBit=" << endBit << std::endl; -#endif - - /// Read from inbuf, decode, store in destBuffer - /// Repeat until have filled destBuffer, or completed all records - -#ifdef E57_DEBUG -#if 0 // I know now way to do this portably - // Deactivate for now until a better solution is found. - /// Verify that inbuf is naturally aligned to RegisterT boundary (1, 2, 4,or 8 bytes). Base class is doing this for us. - if ((reinterpret_cast(inbuf)) % sizeof(RegisterT)) - throw E57_EXCEPTION2(E57_ERROR_INTERNAL, "inbuf=" + toString(reinterpret_cast(inbuf))); -#endif - /// Verfiy first bit is in first word - if ( firstBit >= 8 * sizeof( RegisterT ) ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "firstBit=" + toString( firstBit ) ); - } -#endif - - size_t destRecords = destBuffer_->capacity() - destBuffer_->nextIndex(); - - /// Precalculate exact number of full records that are in inbuf - /// We can handle the case where don't have a full word at end of inbuf, but - /// all the bits of the record are there; - size_t bitCount = endBit - firstBit; - size_t maxInputRecords = bitCount / bitsPerRecord_; - - /// Number of transfers is the smaller of what was requested and what is - /// available in input. - size_t recordCount = std::min( destRecords, maxInputRecords ); - - // Can't process more than defined in input file - if ( static_cast( recordCount ) > maxRecordCount_ - currentRecordIndex_ ) - { - recordCount = static_cast( maxRecordCount_ - currentRecordIndex_ ); - } - -#ifdef E57_MAX_VERBOSE - std::cout << " recordCount=" << recordCount << std::endl; -#endif - - auto inp = reinterpret_cast( inbuf ); - unsigned wordPosition = 0; /// The index in inbuf of the word we are currently working on. - - /// For example on little endian machine: - /// Assume: registerT=uint32_t, bitOffset=20, destBitMask=0x00007fff (for a - /// 15 bit value). inp[wordPosition] LLLLLLLL LLLLXXXX - /// XXXXXXXX XXXXXXXX Note LSB of value is at bit20 inp(wordPosition+1] - /// XXXXXXXX XXXXXXXX XXXXXXXX XXXXXHHH H=high bits of value, - /// X=uninteresting bits low = inp[i] >> bitOffset 00000000 - /// 00000000 0000LLLL LLLLLLLL L=low bits of value, X=uninteresting bits - /// high = inp[i+1] << (32-bitOffset) XXXXXXXX XXXXXXXX XHHH0000 00000000 - /// w = high | low XXXXXXXX XXXXXXXX XHHHLLLL LLLLLLLL destBitmask 00000000 - /// 00000000 01111111 11111111 w & mask 00000000 - /// 00000000 0HHHLLLL LLLLLLLL - - size_t bitOffset = firstBit; - - for ( size_t i = 0; i < recordCount; i++ ) - { - /// Get lower word (contains at least the LSbit of the value), - RegisterT low = inp[wordPosition]; - -#ifdef E57_MAX_VERBOSE - std::cout << " bitOffset: " << bitOffset << std::endl; - std::cout << " low: " << binaryString( low ) << std::endl; -#endif - - RegisterT w; - if ( bitOffset > 0 ) - { - /// Get upper word (may or may not contain interesting bits), - RegisterT high = inp[wordPosition + 1]; - -#ifdef E57_MAX_VERBOSE - std::cout << " high:" << binaryString( high ) << std::endl; -#endif - - /// Shift high to just above the lower bits, shift low LSBit to bit0, - /// OR together. Note shifts are logical (not arithmetic) because using - /// unsigned variables. - w = ( high << ( 8 * sizeof( RegisterT ) - bitOffset ) ) | ( low >> bitOffset ); - } - else - { - /// The left shift (used above) is not defined if shift is >= size of - /// word - w = low; - } - -#ifdef E57_MAX_VERBOSE - std::cout << " w: " << binaryString( w ) << std::endl; -#endif - - /// Mask off uninteresting bits - w &= destBitMask_; - - /// Add minimum_ to value to get back what writer originally sent - int64_t value = minimum_ + static_cast( w ); - -#ifdef E57_MAX_VERBOSE - std::cout << " Storing value=" << value << std::endl; -#endif - - /// The parameter isScaledInteger_ determines which version of - /// setNextInt64 gets called - if ( isScaledInteger_ ) - { - destBuffer_->setNextInt64( value, scale_, offset_ ); - } - else - { - destBuffer_->setNextInt64( value ); - } - - /// Store the result in next available position in the user's dest buffer - - /// Calc next bit alignment and which word it starts in - bitOffset += bitsPerRecord_; - if ( bitOffset >= 8 * sizeof( RegisterT ) ) - { - bitOffset -= 8 * sizeof( RegisterT ); - wordPosition++; - } -#ifdef E57_MAX_VERBOSE - std::cout << " Processed " << i + 1 << " records, wordPosition=" << wordPosition << " decoder:" << std::endl; - dump( 4 ); -#endif - } - - /// Update counts of records processed - currentRecordIndex_ += recordCount; - - /// Return number of bits processed. - return ( recordCount * bitsPerRecord_ ); -} - -#ifdef E57_DEBUG -template void BitpackIntegerDecoder::dump( int indent, std::ostream &os ) -{ - BitpackDecoder::dump( indent, os ); - os << space( indent ) << "isScaledInteger: " << isScaledInteger_ << std::endl; - os << space( indent ) << "minimum: " << minimum_ << std::endl; - os << space( indent ) << "maximum: " << maximum_ << std::endl; - os << space( indent ) << "scale: " << scale_ << std::endl; - os << space( indent ) << "offset: " << offset_ << std::endl; - os << space( indent ) << "bitsPerRecord: " << bitsPerRecord_ << std::endl; - os << space( indent ) << "destBitMask: " << binaryString( destBitMask_ ) << " = " << hexString( destBitMask_ ) - << std::endl; -} -#endif - -//================================================================ - -ConstantIntegerDecoder::ConstantIntegerDecoder( bool isScaledInteger, unsigned bytestreamNumber, SourceDestBuffer &dbuf, - int64_t minimum, double scale, double offset, - uint64_t maxRecordCount ) : - Decoder( bytestreamNumber ), - maxRecordCount_( maxRecordCount ), destBuffer_( dbuf.impl() ), isScaledInteger_( isScaledInteger ), - minimum_( minimum ), scale_( scale ), offset_( offset ) -{ -} - -void ConstantIntegerDecoder::destBufferSetNew( std::vector &dbufs ) -{ - if ( dbufs.size() != 1 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "dbufsSize=" + toString( dbufs.size() ) ); - } - - destBuffer_ = dbufs.at( 0 ).impl(); -} - -size_t ConstantIntegerDecoder::inputProcess( const char *source, const size_t availableByteCount ) -{ - (void)source; (void)availableByteCount; -#ifdef E57_MAX_VERBOSE - std::cout << "ConstantIntegerDecoder::inputprocess() called, source=" << (void *)( source ) - << " availableByteCount=" << availableByteCount << std::endl; -#endif - - /// We don't need any input bytes to produce output, so ignore source and - /// availableByteCount. - - /// Fill dest buffer unless get to maxRecordCount - size_t count = destBuffer_->capacity() - destBuffer_->nextIndex(); - uint64_t remainingRecordCount = maxRecordCount_ - currentRecordIndex_; - if ( static_cast( count ) > remainingRecordCount ) - { - count = static_cast( remainingRecordCount ); - } - - if ( isScaledInteger_ ) - { - for ( size_t i = 0; i < count; i++ ) - { - destBuffer_->setNextInt64( minimum_, scale_, offset_ ); - } - } - else - { - for ( size_t i = 0; i < count; i++ ) - { - destBuffer_->setNextInt64( minimum_ ); - } - } - currentRecordIndex_ += count; - return ( count ); -} - -void ConstantIntegerDecoder::stateReset() -{ -} - -#ifdef E57_DEBUG -void ConstantIntegerDecoder::dump( int indent, std::ostream &os ) -{ - os << space( indent ) << "bytestreamNumber: " << bytestreamNumber_ << std::endl; - os << space( indent ) << "currentRecordIndex: " << currentRecordIndex_ << std::endl; - os << space( indent ) << "maxRecordCount: " << maxRecordCount_ << std::endl; - os << space( indent ) << "isScaledInteger: " << isScaledInteger_ << std::endl; - os << space( indent ) << "minimum: " << minimum_ << std::endl; - os << space( indent ) << "scale: " << scale_ << std::endl; - os << space( indent ) << "offset: " << offset_ << std::endl; - os << space( indent ) << "destBuffer:" << std::endl; - destBuffer_->dump( indent + 4, os ); -} -#endif diff --git a/src/3rdParty/libE57Format/src/Decoder.h b/src/3rdParty/libE57Format/src/Decoder.h deleted file mode 100644 index 7d9496c5c4..0000000000 --- a/src/3rdParty/libE57Format/src/Decoder.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include "Common.h" - -namespace e57 -{ - class Decoder - { - public: - static std::shared_ptr DecoderFactory( unsigned bytestreamNumber, - const CompressedVectorNodeImpl *cVector, - std::vector &dbufs, const ustring &codecPath ); - Decoder() = delete; - virtual ~Decoder() = default; - - virtual void destBufferSetNew( std::vector &dbufs ) = 0; - virtual uint64_t totalRecordsCompleted() = 0; - virtual size_t inputProcess( const char *source, const size_t count ) = 0; - virtual void stateReset() = 0; - unsigned bytestreamNumber() const - { - return bytestreamNumber_; - } -#ifdef E57_DEBUG - virtual void dump( int indent = 0, std::ostream &os = std::cout ) = 0; -#endif - - protected: - Decoder( unsigned bytestreamNumber ); - - unsigned int bytestreamNumber_; - }; - - class BitpackDecoder : public Decoder - { - public: - void destBufferSetNew( std::vector &dbufs ) override; - - uint64_t totalRecordsCompleted() override - { - return ( currentRecordIndex_ ); - } - - size_t inputProcess( const char *source, const size_t availableByteCount ) override; - virtual size_t inputProcessAligned( const char *inbuf, const size_t firstBit, const size_t endBit ) = 0; - - void stateReset() override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) override; -#endif - protected: - BitpackDecoder( unsigned bytestreamNumber, SourceDestBuffer &dbuf, unsigned alignmentSize, - uint64_t maxRecordCount ); - - void inBufferShiftDown(); - - uint64_t currentRecordIndex_ = 0; - uint64_t maxRecordCount_ = 0; - - std::shared_ptr destBuffer_; - - std::vector inBuffer_; - size_t inBufferFirstBit_ = 0; - size_t inBufferEndByte_ = 0; - unsigned int inBufferAlignmentSize_; - unsigned int bitsPerWord_; - unsigned int bytesPerWord_; - }; - - class BitpackFloatDecoder : public BitpackDecoder - { - public: - BitpackFloatDecoder( unsigned bytestreamNumber, SourceDestBuffer &dbuf, FloatPrecision precision, - uint64_t maxRecordCount ); - - size_t inputProcessAligned( const char *inbuf, const size_t firstBit, const size_t endBit ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) override; -#endif - protected: - FloatPrecision precision_ = E57_SINGLE; - }; - - class BitpackStringDecoder : public BitpackDecoder - { - public: - BitpackStringDecoder( unsigned bytestreamNumber, SourceDestBuffer &dbuf, uint64_t maxRecordCount ); - - size_t inputProcessAligned( const char *inbuf, const size_t firstBit, const size_t endBit ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) override; -#endif - protected: - bool readingPrefix_ = true; - int prefixLength_ = 1; - uint8_t prefixBytes_[8] = {}; - int nBytesPrefixRead_ = 0; - uint64_t stringLength_ = 0; - ustring currentString_; - uint64_t nBytesStringRead_ = 0; - }; - - template class BitpackIntegerDecoder : public BitpackDecoder - { - public: - BitpackIntegerDecoder( bool isScaledInteger, unsigned bytestreamNumber, SourceDestBuffer &dbuf, int64_t minimum, - int64_t maximum, double scale, double offset, uint64_t maxRecordCount ); - - size_t inputProcessAligned( const char *inbuf, const size_t firstBit, const size_t endBit ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) override; -#endif - protected: - bool isScaledInteger_; - int64_t minimum_; - int64_t maximum_; - double scale_; - double offset_; - unsigned bitsPerRecord_; - RegisterT destBitMask_; - }; - - class ConstantIntegerDecoder : public Decoder - { - public: - ConstantIntegerDecoder( bool isScaledInteger, unsigned bytestreamNumber, SourceDestBuffer &dbuf, int64_t minimum, - double scale, double offset, uint64_t maxRecordCount ); - void destBufferSetNew( std::vector &dbufs ) override; - uint64_t totalRecordsCompleted() override - { - return currentRecordIndex_; - } - size_t inputProcess( const char *source, const size_t availableByteCount ) override; - void stateReset() override; -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) override; -#endif - protected: - uint64_t currentRecordIndex_ = 0; - uint64_t maxRecordCount_; - - std::shared_ptr destBuffer_; - - bool isScaledInteger_; - int64_t minimum_; - double scale_; - double offset_; - }; -} diff --git a/src/3rdParty/libE57Format/src/E57Exception.cpp b/src/3rdParty/libE57Format/src/E57Exception.cpp deleted file mode 100644 index e95afe7724..0000000000 --- a/src/3rdParty/libE57Format/src/E57Exception.cpp +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "E57Exception.h" -#include "E57Version.h" - -namespace e57 -{ - /*! - @class E57Exception - @brief Object thrown by E57 API functions to communicate the conditions of an - error. - @details - The E57Exception object communicates information about errors occurring in calls - to the E57 API functions. The error information is communicated from the - location in the E57 implementation where the error was detected to the @c catch - statement in the code of the API user. The state of E57Exception object has one - mandatory field, the errorCode, and several optional fields that can be set - depending on the debug level of the E57 implementation. There are three optional - fields that encode the location in the source code of the E57 implementation - where the error was detected: @c sourceFileName, @c sourceFunctionName, and @c - sourceLineNumber. Another optional field is the @c context string that is human - (or at least programmer) readable, which can capture some variable values that - might be useful in debugging. The E57Exception class is derived from - std::exception. So applications that only catch std::exceptions will detect - E57Exceptions (but with no information about the origin of the error). - - Many other APIs use error codes (defined integer constants) returned from the - API functions to communicate success or failure of the requested command. In - contrast, the E57 API uses the C++ exception mechanism to communicate failure - (success is communicated by the return of the function without exception). - E57Exception(E57_SUCCESS) is never thrown. The API ErrorCode is packaged inside - the E57Exception. The documentation for each function in the API declares which - ErrorCode values (inside an E57Exception) can possibly be thrown by the - function. Some API functions do not throw any E57Exceptions, and this is - documented by the designation "No E57Exceptions." in the "Exceptions:" section - of the function documentation page. - - If an API function does throw an E57Exception, the API user will rightfully be - concerned about the state of all of the API objects. There are four categories - of guarantee about the state of all objects that the API specifies. - - 1) All objects unchanged - all API objects are left in their original - state before the API function was called. This is the default guarantee, so if - there is no notation next to the ErrorCode in the "Exceptions:" section of the - function documentation page, the this category is implied. - - 2) XXX object modified, but consistent - The given object (or objects) - have been modified, but are left in a consistent state. - - 3) XXX object in undocumented state - The given object (or objects) may - have been left in an inconsistent state, and the only safe thing to do with them - is to call their destructor. - - 4) All objects in undocumented state - A very serious consistency error - has been detected, and the state of all API objects is suspect. The only safe - thing to do is to call their destructors. - - Almost all of the API functions can throw the following two ErrorCodes: - E57_ERROR_IMAGEFILE_NOT_OPEN and E57_ERROR_INTERNAL. In some E57 - implementations, the tree information may be stored on disk rather than in - memory. If the disk file is closed, even the most basic information may not be - available about nodes in the tree. So if the ImageFile is closed (by calling - ImageFile::close), the API user must be ready for many of the API functions to - throw E57Exception(E57_ERROR_IMAGEFILE_NOT_OPEN). Secondly, regarding the - E57_ERROR_INTERNAL error, there is a lot of consistency checking in the - Reference Implementation, and there may be much more added. Even if some API - routines do not now throw E57_ERROR_INTERNAL, they could some time in the - future, or in different implementations. So the right to throw - E57_ERROR_INTERNAL is reserved for every API function (except those that by - design can't throw E57Exceptions). - - It is strongly recommended that catch statements in user code that call API - functions catch E57Exception by reference (i.e. catch (E57Exception& - ex) and, if necessary, rethrow using the syntax that throws the currently - active exception (i.e. throw;). - - Exceptions other that E57Exception may be thrown by calls to API functions (e.g. - std::bad_alloc). Production code will likely have catch handlers for these - exceptions as well. - - @see HelloWorld.cpp example - */ - - //! @cond documentNonPublic The following isn't part of the API, and isn't - //! documented. - E57Exception::E57Exception( ErrorCode ecode, const std::string &context, const std::string &srcFileName, - int srcLineNumber, const char *srcFunctionName ) : - errorCode_( ecode ), - context_( context ), sourceFunctionName_( srcFunctionName ), sourceLineNumber_( srcLineNumber ) - { - sourceFileName_ = srcFileName.substr( srcFileName.find_last_of( "/\\" ) + 1 ); - } - //! @endcond - - /*! - @brief Print error information on a given output stream. - @param [in] reportingFileName Name of file where catch statement caught - the exception. NULL if unknown. - @param [in] reportingLineNumber Number of source code line where catch - statement caught the exception. 0 if unknown. - @param [in] reportingFunctionName String name of function containing catch - statement that caught the exception. NULL if unknown. - @param [in] os Output string to print a summary of exception information and - location of catch statement. - @details - The amount of information printed to output stream may depend on whether the E57 - implementation was built with debugging enabled. - @post No visible state is modified. - @throw No E57Exceptions. - @see E57ExceptionFunctions.cpp example, ErrorCode, HelloWorld.cpp example - */ - void E57Exception::report( const char *reportingFileName, int reportingLineNumber, const char *reportingFunctionName, - std::ostream &os ) const - { - os << "**** Got an e57 exception: " << e57::Utilities::errorCodeToString( errorCode() ) << std::endl; - -#ifdef E57_DEBUG - os << " Debug info: " << std::endl; - os << " context: " << context_ << std::endl; - os << " sourceFunctionName: " << sourceFunctionName_ << std::endl; - if ( reportingFunctionName ) - os << " reportingFunctionName: " << reportingFunctionName << std::endl; - - /*** Add a line in error message that a smart editor (gnu emacs) can - * interpret as a link to the source code: */ - os << sourceFileName_ << "(" << sourceLineNumber_ << ") : error C" << errorCode_ << ": <--- occurred on" - << std::endl; - if ( reportingFileName ) - os << reportingFileName << "(" << reportingLineNumber << ") : error C0: <--- reported on" << std::endl; -#endif - } - - /*! - @brief Get numeric ::ErrorCode associated with the exception. - @post No visible state is modified. - @return The numeric ::ErrorCode associated with the exception. - @throw No E57Exceptions. - @see E57ExceptionFunctions.cpp example, E57Utilities::errorCodeToString, - ErrorCode - */ - ErrorCode E57Exception::errorCode() const - { - return errorCode_; - } - - /*! - @brief Get human-readable string that describes the context of the error. - @details - The context string may include values in object state, or function arguments. - The format of the context string is not standardized. - However, in the Reference Implementation, many strings contain a sequence of " - VARNAME=VARVALUE" fields. - @post No visible state is modified. - @return The human-readable string that describes the context of the error. - @throw No E57Exceptions. - @see E57ExceptionsFunctions.cpp example - */ - std::string E57Exception::context() const - { - return context_; - } - - /*! - @brief Get string description of exception category. - @details - Returns "E57 Exception" for all E57Exceptions, no matter what the errorCode. - @post No visible state is modified. - @return The string description of exception category. - @throw No E57Exceptions. - @see E57ExceptionsFunctions.cpp example - */ - const char *E57Exception::what() const noexcept - { - return "E57 exception"; - } - - /*! - @brief Get name of source file where exception occurred, for debugging. - @details - May return the value of the macro variable __FILE__ at the location where the - E57Exception was constructed. May return the empty string ("") in some E57 - implementations. - @post No visible state is modified. - @return The name of source file where exception occurred, for debugging. - @throw No E57Exceptions. - @see E57ExceptionsFunctions.cpp example - */ - const char *E57Exception::sourceFileName() const - { - return sourceFileName_.c_str(); - } - - /*! - @brief Get name of function in source code where the error occurred , for - debugging. - @details - May return the value of the macro variable __FUNCTION__ at the location where - the E57Exception was constructed. May return the empty string ("") in some E57 - implementations. - @post No visible state is modified. - @return The name of source code function where the error occurred , for - debugging. - @throw No E57Exceptions. - */ - const char *E57Exception::sourceFunctionName() const - { - return sourceFunctionName_; - } - - /*! - @brief Get line number in source code file where exception occurred, for - debugging. - @details - May return the value of the macro variable __LINE__ at the location where the - E57Exception was constructed. May return the empty string ("") in some E57 - implementations. - @post No visible state is modified. - @return The line number in source code file where exception occurred, for - debugging. - @throw No E57Exceptions. - */ - int E57Exception::sourceLineNumber() const - { - return sourceLineNumber_; - } - - //===================================================================================== - - /*! - @brief Get the version of ASTM E57 standard that the API implementation - supports, and library id string. - @param [out] astmMajor The major version number of the ASTM E57 standard - supported. - @param [out] astmMinor The minor version number of the ASTM E57 standard - supported. - @param [out] libraryId A string identifying the implementation of the API. - @details - Since the E57 implementation may be dynamically linked underneath the API, the - version string for the implementation and the ASTM version that it supports - can't be determined at compile-time. This function returns these identifiers - from the underlying implementation. - @throw No E57Exceptions. - */ - void Utilities::getVersions( int &astmMajor, int &astmMinor, std::string &libraryId ) - { - /// REVISION_ID should be passed from compiler command line - -#ifndef REVISION_ID -#error "Need to specify REVISION_ID on command line" -#endif - - astmMajor = E57_FORMAT_MAJOR; - astmMinor = E57_FORMAT_MINOR; - libraryId = REVISION_ID; - } - - /*! - @brief Get short string description of an E57 ErrorCode. - @param [in] ecode The numeric errorCode from an E57Exception. - @details - The errorCode is translated into a one-line English string. - @return English std::string describing error. - @throw No E57Exceptions. - @see E57Exception::errorCode - */ - std::string Utilities::errorCodeToString( ErrorCode ecode ) - { - switch ( ecode ) - { - // N.B. *** When changing error strings here, remember to update the - // Doxygen strings in E57Exception.h **** - case E57_SUCCESS: - return "operation was successful (E57_SUCCESS)"; - case E57_ERROR_BAD_CV_HEADER: - return "a CompressedVector binary header was bad " - "(E57_ERROR_BAD_CV_HEADER)"; - case E57_ERROR_BAD_CV_PACKET: - return "a CompressedVector binary packet was bad " - "(E57_ERROR_BAD_CV_PACKET)"; - case E57_ERROR_CHILD_INDEX_OUT_OF_BOUNDS: - return "a numerical index identifying a child was out of bounds " - "(E57_ERROR_CHILD_INDEX_OUT_OF_BOUNDS)"; - case E57_ERROR_SET_TWICE: - return "attempted to set an existing child element to a new value " - "(E57_ERROR_SET_TWICE)"; - case E57_ERROR_HOMOGENEOUS_VIOLATION: - return "attempted to add an E57 Element that would have made the " - "children of a " - "homogeneous Vector have different types " - "(E57_ERROR_HOMOGENEOUS_VIOLATION)"; - case E57_ERROR_VALUE_NOT_REPRESENTABLE: - return "a value could not be represented in the requested type " - "(E57_ERROR_VALUE_NOT_REPRESENTABLE)"; - case E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE: - return "after scaling the result could not be represented in the " - "requested type " - "(E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE)"; - case E57_ERROR_REAL64_TOO_LARGE: - return "a 64 bit IEEE float was too large to store in a 32 bit IEEE " - "float " - "(E57_ERROR_REAL64_TOO_LARGE)"; - case E57_ERROR_EXPECTING_NUMERIC: - return "Expecting numeric representation in user's buffer, found " - "ustring " - "(E57_ERROR_EXPECTING_NUMERIC)"; - case E57_ERROR_EXPECTING_USTRING: - return "Expecting string representation in user's buffer, found " - "numeric " - "(E57_ERROR_EXPECTING_USTRING)"; - case E57_ERROR_INTERNAL: - return "An unrecoverable inconsistent internal state was detected " - "(E57_ERROR_INTERNAL)"; - case E57_ERROR_BAD_XML_FORMAT: - return "E57 primitive not encoded in XML correctly " - "(E57_ERROR_BAD_XML_FORMAT)"; - case E57_ERROR_XML_PARSER: - return "XML not well formed (E57_ERROR_XML_PARSER)"; - case E57_ERROR_BAD_API_ARGUMENT: - return "bad API function argument provided by user " - "(E57_ERROR_BAD_API_ARGUMENT)"; - case E57_ERROR_FILE_IS_READ_ONLY: - return "can't modify read only file (E57_ERROR_FILE_IS_READ_ONLY)"; - case E57_ERROR_BAD_CHECKSUM: - return "checksum mismatch, file is corrupted (E57_ERROR_BAD_CHECKSUM)"; - case E57_ERROR_OPEN_FAILED: - return "open() failed (E57_ERROR_OPEN_FAILED)"; - case E57_ERROR_CLOSE_FAILED: - return "close() failed (E57_ERROR_CLOSE_FAILED)"; - case E57_ERROR_READ_FAILED: - return "read() failed (E57_ERROR_READ_FAILED)"; - case E57_ERROR_WRITE_FAILED: - return "write() failed (E57_ERROR_WRITE_FAILED)"; - case E57_ERROR_LSEEK_FAILED: - return "lseek() failed (E57_ERROR_LSEEK_FAILED)"; - case E57_ERROR_PATH_UNDEFINED: - return "E57 element path well formed but not defined " - "(E57_ERROR_PATH_UNDEFINED)"; - case E57_ERROR_BAD_BUFFER: - return "bad SourceDestBuffer (E57_ERROR_BAD_BUFFER)"; - case E57_ERROR_NO_BUFFER_FOR_ELEMENT: - return "no buffer specified for an element in CompressedVectorNode " - "during write " - "(E57_ERROR_NO_BUFFER_FOR_ELEMENT)"; - case E57_ERROR_BUFFER_SIZE_MISMATCH: - return "SourceDestBuffers not all same size " - "(E57_ERROR_BUFFER_SIZE_MISMATCH)"; - case E57_ERROR_BUFFER_DUPLICATE_PATHNAME: - return "duplicate pathname in CompressedVectorNode read/write " - "(E57_ERROR_BUFFER_DUPLICATE_PATHNAME)"; - case E57_ERROR_BAD_FILE_SIGNATURE: - return "file signature not " - "ASTM-E57" - " (E57_ERROR_BAD_FILE_SIGNATURE)"; - case E57_ERROR_UNKNOWN_FILE_VERSION: - return "incompatible file version (E57_ERROR_UNKNOWN_FILE_VERSION)"; - case E57_ERROR_BAD_FILE_LENGTH: - return "size in file header not same as actual " - "(E57_ERROR_BAD_FILE_LENGTH)"; - case E57_ERROR_XML_PARSER_INIT: - return "XML parser failed to initialize (E57_ERROR_XML_PARSER_INIT)"; - case E57_ERROR_DUPLICATE_NAMESPACE_PREFIX: - return "namespace prefix already defined " - "(E57_ERROR_DUPLICATE_NAMESPACE_PREFIX)"; - case E57_ERROR_DUPLICATE_NAMESPACE_URI: - return "namespace URI already defined " - "(E57_ERROR_DUPLICATE_NAMESPACE_URI)"; - case E57_ERROR_BAD_PROTOTYPE: - return "bad prototype in CompressedVectorNode " - "(E57_ERROR_BAD_PROTOTYPE)"; - case E57_ERROR_BAD_CODECS: - return "bad codecs in CompressedVectorNode (E57_ERROR_BAD_CODECS)"; - case E57_ERROR_VALUE_OUT_OF_BOUNDS: - return "element value out of min/max bounds " - "(E57_ERROR_VALUE_OUT_OF_BOUNDS)"; - case E57_ERROR_CONVERSION_REQUIRED: - return "conversion required to assign element value, but not " - "requested " - "(E57_ERROR_CONVERSION_REQUIRED)"; - case E57_ERROR_BAD_PATH_NAME: - return "E57 path name is not well formed (E57_ERROR_BAD_PATH_NAME)"; - case E57_ERROR_NOT_IMPLEMENTED: - return "functionality not implemented (E57_ERROR_NOT_IMPLEMENTED)"; - case E57_ERROR_BAD_NODE_DOWNCAST: - return "bad downcast from Node to specific node type " - "(E57_ERROR_BAD_NODE_DOWNCAST)"; - case E57_ERROR_WRITER_NOT_OPEN: - return "CompressedVectorWriter is no longer open " - "(E57_ERROR_WRITER_NOT_OPEN)"; - case E57_ERROR_READER_NOT_OPEN: - return "CompressedVectorReader is no longer open " - "(E57_ERROR_READER_NOT_OPEN)"; - case E57_ERROR_NODE_UNATTACHED: - return "node is not yet attached to tree of ImageFile " - "(E57_ERROR_NODE_UNATTACHED)"; - case E57_ERROR_ALREADY_HAS_PARENT: - return "node already has a parent (E57_ERROR_ALREADY_HAS_PARENT)"; - case E57_ERROR_DIFFERENT_DEST_IMAGEFILE: - return "nodes were constructed with different destImageFiles " - "(E57_ERROR_DIFFERENT_DEST_IMAGEFILE)"; - case E57_ERROR_IMAGEFILE_NOT_OPEN: - return "destImageFile is no longer open " - "(E57_ERROR_IMAGEFILE_NOT_OPEN)"; - case E57_ERROR_BUFFERS_NOT_COMPATIBLE: - return "SourceDestBuffers not compatible with previously given ones " - "(E57_ERROR_BUFFERS_NOT_COMPATIBLE)"; - case E57_ERROR_TOO_MANY_WRITERS: - return "too many open CompressedVectorWriters of an ImageFile " - "(E57_ERROR_TOO_MANY_WRITERS)"; - case E57_ERROR_TOO_MANY_READERS: - return "too many open CompressedVectorReaders of an ImageFile " - "(E57_ERROR_TOO_MANY_READERS)"; - case E57_ERROR_BAD_CONFIGURATION: - return "bad configuration string (E57_ERROR_BAD_CONFIGURATION)"; - case E57_ERROR_INVARIANCE_VIOLATION: - return "class invariance constraint violation in debug mode " - "(E57_ERROR_INVARIANCE_VIOLATION)"; - default: - return "unknown error (" + std::to_string( ecode ) + ")"; - } - } - -} diff --git a/src/3rdParty/libE57Format/src/E57Format.cpp b/src/3rdParty/libE57Format/src/E57Format.cpp deleted file mode 100644 index 47ff2e8b8f..0000000000 --- a/src/3rdParty/libE57Format/src/E57Format.cpp +++ /dev/null @@ -1,4891 +0,0 @@ -/* - * E57Format.cpp - implementation of public functions of the E57 format - * Reference Implementation. - * - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -//! @file E57Format.cpp - -#include "BlobNodeImpl.h" -#include "CompressedVectorNodeImpl.h" -#include "CompressedVectorReaderImpl.h" -#include "CompressedVectorWriterImpl.h" -#include "FloatNodeImpl.h" -#include "ImageFileImpl.h" -#include "IntegerNodeImpl.h" -#include "ScaledIntegerNodeImpl.h" -#include "SourceDestBufferImpl.h" -#include "StringNodeImpl.h" -#include "VectorNodeImpl.h" - -using namespace e57; - -/*! -@brief Check whether Node class invariant is true -@param [in] doRecurse If true, also check invariants of all children or -sub-objects recursively. -@param [in] doDowncast If true, also check any invariants of the actual -derived type in addition to the generic node invariants. -@details -This function checks at least the assertions in the documented class invariant -description (see class reference page for this object). Other internal -invariants that are implementation-dependent may also be checked. If any -invariant clause is violated, an E57Exception with errorCode of -E57_ERROR_INVARIANCE_VIOLATION is thrown. - -Specifying doRecurse=true only makes sense if doDowncast=true is also specified -(the generic Node has no way to access any children). Checking the invariant -recursively may be expensive if the tree is large, so should be used -judiciously, in debug versions of the application. -@post No visible state is modified. -@throw ::E57_ERROR_INVARIANCE_VIOLATION or any other E57 ErrorCode -@see Class Invariant section in Node, -IntegerNode::checkInvariant, ScaledIntegerNode::checkInvariant, -FloatNode::checkInvariant, BlobNode::checkInvariant, -StructureNode::checkInvariant, VectorNode::checkInvariant, -CompressedVectorNode::checkInvariant -*/ -void Node::checkInvariant( bool doRecurse, bool doDowncast ) -{ - ImageFile imf = destImageFile(); - - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !imf.isOpen() ) - { - return; - } - - // Parent attachment state is same as this attachment state - if ( isAttached() != parent().isAttached() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Parent destination ImageFile is same as this - if ( imf != parent().destImageFile() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // If this is the ImageFile root node - if ( *this == imf.root() ) - { - // Must be attached - if ( !isAttached() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Must be is a root node - if ( !isRoot() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - - // If this is a root node - if ( isRoot() ) - { - // Absolute pathName is "/" - if ( pathName() != "/" ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // parent() returns this node - if ( *this != parent() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - else - { - // Non-root can't be own parent - if ( *this == parent() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // pathName is concatenation of parent pathName and this elementName - if ( parent().isRoot() ) - { - if ( pathName() != "/" + elementName() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - else - { - if ( pathName() != parent().pathName() + "/" + elementName() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - - // Non-root nodes must be children of either a VectorNode or StructureNode - if ( parent().type() == E57_VECTOR ) - { - VectorNode v = static_cast( parent() ); - - // Must be defined in parent VectorNode with this elementName - if ( !v.isDefined( elementName() ) ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Getting child of parent with this elementName must return this - if ( v.get( elementName() ) != *this ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - else if ( parent().type() == E57_STRUCTURE ) - { - StructureNode s = static_cast( parent() ); - - // Must be defined in parent VectorNode with this elementName - if ( !s.isDefined( elementName() ) ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Getting child of parent with this elementName must return this - if ( s.get( elementName() ) != *this ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - else - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - - // If this is attached - if ( isAttached() ) - { - // Get root of this - Node n = *this; - while ( !n.isRoot() ) - { - n = n.parent(); - } - - // If in tree of ImageFile (could be in a prototype instead) - if ( n == imf.root() ) - { - // pathName must be defined - if ( !imf.root().isDefined( pathName() ) ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Getting by absolute pathName must be this - if ( imf.root().get( pathName() ) != *this ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - } - - // If requested, check invariants of derived types: - if ( doDowncast ) - { - switch ( type() ) - { - case E57_STRUCTURE: - { - StructureNode s( *this ); - s.checkInvariant( doRecurse, false ); - } - break; - case E57_VECTOR: - { - VectorNode v( *this ); - v.checkInvariant( doRecurse, false ); - } - break; - case E57_COMPRESSED_VECTOR: - { - CompressedVectorNode cv( *this ); - cv.checkInvariant( doRecurse, false ); - } - break; - case E57_INTEGER: - { - IntegerNode i( *this ); - i.checkInvariant( doRecurse, false ); - } - break; - case E57_SCALED_INTEGER: - { - ScaledIntegerNode si( *this ); - si.checkInvariant( doRecurse, false ); - } - break; - case E57_FLOAT: - { - FloatNode f( *this ); - f.checkInvariant( doRecurse, false ); - } - break; - case E57_STRING: - { - StringNode s( *this ); - s.checkInvariant( doRecurse, false ); - } - break; - case E57_BLOB: - { - BlobNode b( *this ); - b.checkInvariant( doRecurse, false ); - } - break; - default: - break; - } - } -} - -/*! -@class Node -@brief Generic handle to any of the 8 types of E57 element objects. -@details -A Node is a generic handle to an underlying object that is any of the eight type -of E57 element objects. Each of the eight node types support the all the -functions of the Node class. A Node is a vertex in a tree (acyclic graph), which -is a hierarchical organization of nodes. At the top of the hierarchy is a single -root Node. If a Node is a container type (StructureNode, VectorNode, -CompressedVectorNode) it may have child nodes. The following are non-container -type nodes (also known as terminal nodes): IntegerNode, ScaledIntegerNode, -FloatNode, StringNode, BlobNode. Terminal nodes store various types of values -and cannot have children. Each Node has an elementName, which is a string that -uniquely identifies it within the children of its parent. Children of a -StructureNode have elementNames that are explicitly given by the API user. -Children of a VectorNode or CompressedVectorNode have element names that are -string reorientations of the Node's positional index, starting at "0". A path -name is a sequence elementNames (divided by "/") that must be traversed to get -from a Node to one of its descendents. - -Data is organized in an E57 format file (an ImageFile) hierarchically. -Each ImageFile has a predefined root node that other nodes can be attached to as -children (either directly or indirectly). A Node can exist temporarily without -being attached to an ImageFile, however the state will not be saved in the -associated file, and the state will be lost if the program exits. - -A handle to a generic Node may be safely be converted to and from a handle to -the Node's true underlying type. Since an attempt to convert a generic Node to a -incorrect handle type will fail with an exception, the true type should be -interrogated beforehand. - -Due to the set-once design of the Foundation API, terminal nodes are immutable -(i.e. their values and attributes can't change after creation). Once a -parent-child relationship has been established, it cannot be changed. - -Only generic operations are available for a Node, to access more specific -operations (e.g. StructureNode::childCount) the generic handle must be converted -to the node type of the underlying object. This conversion is done in a -type-safe way using "downcasting" (see discussion below). - -@section node_Downcasting Downcasting -The conversion from a general handle type to a specific handle type is called -"downcasting". Each of the 8 specific node types have a downcast function (see -IntegerNode::IntegerNode(const Node&) for example). If a downcast is requested -to an incorrect type (e.g. taking a Node handle that is actually a FloatNode and -trying to downcast it to a IntegerNode), an E57Exception is thrown with an -ErrorCode of E57_ERROR_BAD_NODE_DOWNCAST. Depending on the program design, -throwing a bad downcast exception might be acceptable, if an element must be a -specific type and no recovery is possible. If a standard requires an element be -one several types, then Node::type() should be used to interrogate the type in -an @c if or @c switch statement. Downcasting is "dangerous" (can fail with an -exception) so the API requires the programmer to explicitly call the downcast -functions rather than have the c++ compiler insert them automatically. - -@section node_Upcasting Upcasting -The conversion of a specific node handle (e.g. IntegerNode) to a general Node -handle is called "upcasting". Each of the 8 specific node types have an upcast -function (see IntegerNode::operator Node() for example). Upcasting is "safe" -(can't cause an exception) so the API allows the c++ compiler to insert them -automatically. Upcasting is useful if you have a specific node handle and want -to call a function that takes a generic Node handle argument. In this case, the -function can be called with the specific handle and the compiler will -automatically insert the upcast conversion. This implicit conversion allows one -function, with an argument of type Node, to handle operations that apply to all -8 types of nodes (e.g. StructureNode::set()). - -@section node_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Foundation.cpp -@skip begin Node::checkInvariant -@skip checkInvariant( -@until end Node::checkInvariant - -@see StructureNode, VectorNode, CompressedVectorNode, IntegerNode, -ScaledIntegerNode, FloatNode, StringNode, BlobNode -*/ - -//! @brief Check whether StructureNode class invariant is true -//! @copydetails IntegerNode::checkInvariant() -void StructureNode::checkInvariant( bool doRecurse, bool doUpcast ) -{ - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !destImageFile().isOpen() ) - { - return; - } - - // If requested, call Node::checkInvariant - if ( doUpcast ) - { - static_cast( *this ).checkInvariant( false, false ); - } - - // Check each child - for ( int64_t i = 0; i < childCount(); i++ ) - { - Node child = get( i ); - - // If requested, check children recursively - if ( doRecurse ) - { - child.checkInvariant( doRecurse, true ); - } - - // Child's parent must be this - if ( static_cast( *this ) != child.parent() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Child's elementName must be defined - if ( !isDefined( child.elementName() ) ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Getting child by element name must yield same child - Node n = get( child.elementName() ); - if ( n != child ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } -} - -//! @brief Check whether VectorNode class invariant is true -//! @copydetails IntegerNode::checkInvariant() -void VectorNode::checkInvariant( bool doRecurse, bool doUpcast ) -{ - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !destImageFile().isOpen() ) - { - return; - } - - // If requested, call Node::checkInvariant - if ( doUpcast ) - { - static_cast( *this ).checkInvariant( false, false ); - } - - // Check each child - for ( int64_t i = 0; i < childCount(); i++ ) - { - Node child = get( i ); - - // If requested, check children recursively - if ( doRecurse ) - { - child.checkInvariant( doRecurse, true ); - } - - // Child's parent must be this - if ( static_cast( *this ) != child.parent() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Child's elementName must be defined - if ( !isDefined( child.elementName() ) ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Getting child by element name must yield same child - Node n = get( child.elementName() ); - if ( n != child ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } -} - -//! @brief Check whether CompressedVectorNode class invariant is true -//! @copydetails IntegerNode::checkInvariant() -void CompressedVectorNode::checkInvariant( bool doRecurse, bool doUpcast ) -{ - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !destImageFile().isOpen() ) - { - return; - } - - // If requested, call Node::checkInvariant - if ( doUpcast ) - { - static_cast( *this ).checkInvariant( false, false ); - } - - // Check prototype is good Node - prototype().checkInvariant( doRecurse ); - - // prototype attached state not same as this attached state - if ( prototype().isAttached() != isAttached() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // prototype not root - if ( !prototype().isRoot() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // prototype dest ImageFile not same as this dest ImageFile - if ( prototype().destImageFile() != destImageFile() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Check codecs is good Node - codecs().checkInvariant( doRecurse ); - - // codecs attached state not same as this attached state - if ( codecs().isAttached() != isAttached() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // codecs not root - if ( !codecs().isRoot() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // codecs dest ImageFile not same as this dest ImageFile - if ( codecs().destImageFile() != destImageFile() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } -} -/*! -@brief Check whether IntegerNode class invariant is true -@param [in] doRecurse If true, also check invariants of all children or -sub-objects recursively. -@param [in] doUpcast If true, also check invariants of the generic Node -class. -@details -This function checks at least the assertions in the documented class invariant -description (see class reference page for this object). Other internal -invariants that are implementation-dependent may also be checked. If any -invariant clause is violated, an E57Exception with errorCode of -E57_ERROR_INVARIANCE_VIOLATION is thrown. - -Checking the invariant recursively may be expensive if the tree is large, so -should be used judiciously, in debug versions of the application. -@post No visible state is modified. -@throw ::E57_ERROR_INVARIANCE_VIOLATION or any other E57 ErrorCode -*/ -void IntegerNode::checkInvariant( bool /*doRecurse*/, bool doUpcast ) -{ - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !destImageFile().isOpen() ) - { - return; - } - - // If requested, call Node::checkInvariant - if ( doUpcast ) - { - static_cast( *this ).checkInvariant( false, false ); - } - - if ( value() < minimum() || value() > maximum() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } -} - -//! @brief Check whether ScaledIntegerNode class invariant is true -//! @copydetails IntegerNode::checkInvariant() -void ScaledIntegerNode::checkInvariant( bool /*doRecurse*/, bool doUpcast ) -{ - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !destImageFile().isOpen() ) - { - return; - } - - // If requested, call Node::checkInvariant - if ( doUpcast ) - { - static_cast( *this ).checkInvariant( false, false ); - } - - // If value is out of bounds - if ( rawValue() < minimum() || rawValue() > maximum() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // If scale is zero - if ( scale() == 0 ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // If scaled value is not calculated correctly - if ( scaledValue() != rawValue() * scale() + offset() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } -} -//! @brief Check whether FloatNode class invariant is true -//! @copydetails IntegerNode::checkInvariant() -void FloatNode::checkInvariant( bool /*doRecurse*/, bool doUpcast ) -{ - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !destImageFile().isOpen() ) - { - return; - } - - // If requested, call Node::checkInvariant - if ( doUpcast ) - { - static_cast( *this ).checkInvariant( false, false ); - } - - if ( precision() == E57_SINGLE ) - { - if ( static_cast( minimum() ) < E57_FLOAT_MIN || static_cast( maximum() ) > E57_FLOAT_MAX ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - - // If value is out of bounds - if ( value() < minimum() || value() > maximum() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } -} -//! @brief Check whether StringNode class invariant is true -//! @copydetails IntegerNode::checkInvariant() -void StringNode::checkInvariant( bool /*doRecurse*/, bool doUpcast ) -{ - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !destImageFile().isOpen() ) - { - return; - } - - // If requested, call Node::checkInvariant - if ( doUpcast ) - { - static_cast( *this ).checkInvariant( false, false ); - } - /// ? check legal UTF-8 -} -//! @brief Check whether BlobNode class invariant is true -//! @copydetails IntegerNode::checkInvariant() -void BlobNode::checkInvariant( bool /*doRecurse*/, bool doUpcast ) -{ - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !destImageFile().isOpen() ) - { - return; - } - - // If requested, call Node::checkInvariant - if ( doUpcast ) - { - static_cast( *this ).checkInvariant( false, false ); - } - - if ( byteCount() < 0 ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } -} -/*! -@brief Check whether CompressedVectorReader class invariant is true -@param [in] doRecurse If true, also check invariants of all children or -sub-objects recursively. -@details -This function checks at least the assertions in the documented class invariant -description (see class reference page for this object). Other internal -invariants that are implementation-dependent may also be checked. If any -invariant clause is violated, an E57Exception with errorCode of -E57_ERROR_INVARIANCE_VIOLATION is thrown. -@post No visible state is modified. -*/ -void CompressedVectorReader::checkInvariant( bool /*doRecurse*/ ) -{ - // If this CompressedVectorReader is not open, can't test invariant (almost - // every call would throw) - if ( !isOpen() ) - { - return; - } - - CompressedVectorNode cv = compressedVectorNode(); - ImageFile imf = cv.destImageFile(); - - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !imf.isOpen() ) - { - return; - } - - // Associated CompressedVectorNode must be attached to ImageFile - if ( !cv.isAttached() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Dest ImageFile must have at least 1 reader (this one) - if ( imf.readerCount() < 1 ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Dest ImageFile can't have any writers - if ( imf.writerCount() != 0 ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } -} - -//! @brief Check whether CompressedVectorWriter class invariant is true -//! @copydetails CompressedVectorReader::checkInvariant -void CompressedVectorWriter::checkInvariant( bool /*doRecurse*/ ) -{ - // If this CompressedVectorWriter is not open, can't test invariant (almost - // every call would throw) - if ( !isOpen() ) - { - return; - } - - CompressedVectorNode cv = compressedVectorNode(); - ImageFile imf = cv.destImageFile(); - - // If destImageFile not open, can't test invariant (almost every call would - // throw) - if ( !imf.isOpen() ) - { - return; - } - - // Associated CompressedVectorNode must be attached to ImageFile - if ( !cv.isAttached() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Dest ImageFile must be writable - if ( !imf.isWritable() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Dest ImageFile must have exactly 1 writer (this one) - if ( imf.writerCount() != 1 ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Dest ImageFile can't have any readers - if ( imf.readerCount() != 0 ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } -} - -/*! -@brief Check whether ImageFile class invariant is true -@param [in] doRecurse If true, also check invariants of all children or -sub-objects recursively. -@details -This function checks at least the assertions in the documented class invariant -description (see class reference page for this object). Other internal -invariants that are implementation-dependent may also be checked. If any -invariant clause is violated, an E57Exception with errorCode of -E57_ERROR_INVARIANCE_VIOLATION is thrown. - -Checking the invariant recursively may be expensive if the tree is large, so -should be used judiciously, in debug versions of the application. -@post No visible state is modified. -@throw ::E57_ERROR_INVARIANCE_VIOLATION or any other E57 ErrorCode -@see Node::checkInvariant -*/ -void ImageFile::checkInvariant( bool doRecurse ) const -{ - // If this ImageFile is not open, can't test invariant (almost every call - // would throw) - if ( !isOpen() ) - { - return; - } - - // root() node must be a root node - if ( !root().isRoot() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Can't have empty fileName - if ( fileName().empty() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - int wCount = writerCount(); - int rCount = readerCount(); - - // Can't have negative number of readers - if ( rCount < 0 ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Can't have negative number of writers - if ( wCount < 0 ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Can't have more than one writer - if ( 1 < wCount ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // If have writer - if ( wCount > 0 ) - { - // Must be in write-mode - if ( !isWritable() ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - - // Can't have any readers - if ( rCount > 0 ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - - // Extension prefixes and URIs are unique - const size_t eCount = extensionsCount(); - for ( size_t i = 0; i < eCount; i++ ) - { - for ( size_t j = i + 1; j < eCount; j++ ) - { - if ( extensionsPrefix( i ) == extensionsPrefix( j ) ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - if ( extensionsUri( i ) == extensionsUri( j ) ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - } - - // Verify lookup functions are correct - for ( size_t i = 0; i < eCount; i++ ) - { - ustring goodPrefix = extensionsPrefix( i ); - ustring goodUri = extensionsUri( i ); - ustring prefix; - ustring uri; - if ( !extensionsLookupPrefix( goodPrefix, uri ) ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - if ( uri != goodUri ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - if ( !extensionsLookupUri( goodUri, prefix ) ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - if ( prefix != goodPrefix ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - } - - // If requested, check all objects "below" this one - if ( doRecurse ) - { - root().checkInvariant( doRecurse ); - } -} - -//! @brief Check whether SourceDestBuffer class invariant is true -void SourceDestBuffer::checkInvariant( bool /*doRecurse*/ ) const -{ - // Stride must be >= a memory type dependent value - size_t min_stride = 0; - switch ( memoryRepresentation() ) - { - case E57_INT8: - case E57_UINT8: - case E57_BOOL: - min_stride = 1; - break; - case E57_INT16: - case E57_UINT16: - min_stride = 2; - break; - case E57_INT32: - case E57_UINT32: - case E57_REAL32: - min_stride = 4; - break; - case E57_INT64: - case E57_REAL64: - min_stride = 8; - break; - case E57_USTRING: - min_stride = sizeof( ustring ); - break; - default: - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } - if ( stride() < min_stride ) - { - throw E57_EXCEPTION1( E57_ERROR_INVARIANCE_VIOLATION ); - } -} - -/*! -@brief Return the NodeType of a generic Node. -@details This function allows the actual node type to be interrogated before -upcasting the handle to the actual node type (see Upcasting and Dowcasting -section in Node). -@return The NodeType of a generic Node, which may be one of the following -NodeType enumeration values: -::E57_STRUCTURE, ::E57_VECTOR, ::E57_COMPRESSED_VECTOR, ::E57_INTEGER, -::E57_SCALED_INTEGER, -::E57_FLOAT, ::E57_STRING, ::E57_BLOB. -@post No visible state is modified. -@see NodeType, upcast/dowcast discussion in Node -*/ -NodeType Node::type() const -{ - return impl_->type(); -} - -/*! -@brief Is this a root node. -@details A root node has itself as a parent (it is not a child of any node). -Newly constructed nodes (before they are inserted into an ImageFile tree) start -out as root nodes. It is possible to temporarily create small trees that are -unattached to any ImageFile. In these temporary trees, the top-most node will be -a root node. After the tree is attached to the ImageFile tree, the only root -node will be the pre-created one of the ImageTree (the one returned by -ImageFile::root). The concept of @em attachment is slightly larger than that of -the parent-child relationship (see Node::isAttached and -CompressedVectorNode::CompressedVectorNode for more details). -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return true if this node is a root node. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see Node::parent, Node::isAttached, CompressedVectorNode::CompressedVectorNode -*/ -bool Node::isRoot() const -{ - return impl_->isRoot(); -} - -/*! -@brief Return parent of node, or self if a root node. -@details Nodes are organized into trees (acyclic graphs) with a distinguished -node (the "top-most" node) called the root node. A parent-child relationship is -established between nodes to form a tree. Nodes can have zero or one parent. -Nodes with zero parents are called root nodes. -In the API, if a node has zero parents it is represented by having itself as a -parent. Due to the set-once design of the API, a parent-child relationship -cannot be modified once established. A child node can be any of the 8 node -types, but a parent node can only be one of the 3 container node types -(E57_STRUCTURE, E57_VECTOR, and E57_COMPRESSED_VECTOR). Each parent-child link -has a string name (the elementName) associated with it (See Node::elementName -for more details). More than one tree can be formed at any given time. Typically -small trees are temporarily constructed before attachment to an ImageFile so -that they will be written to the disk. - -@b Warning: user algorithms that use this function to walk the tree must take -care to handle the case where a node is its own parent (it is a root node). Use -Node::isRoot to avoid infinite loops or infinite recursion. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return A smart Node handle referencing the parent node or this node if is a -root node. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see Node::isRoot, Node::isAttached, CompressedVectorNode::CompressedVectorNode, Node::elementName -*/ -Node Node::parent() const -{ - return Node( impl_->parent() ); -} - -/*! -@brief Get absolute pathname of node. -@details -Nodes are organized into trees (acyclic graphs) by a parent-child relationship -between nodes. Each parent-child relationship has an associated elementName -string that is unique for a given parent. Any node in a given tree can be -identified by a sequence of elementNames of how to get to the node from the root -of the tree. An absolute pathname string that is formed by arranging this -sequence of elementNames separated by the "/" character with a leading "/" -prepended. - -Some example absolute pathNames: "/data3D/0/points/153/cartesianX", -"/data3D/0/points", -"/cameraImages/1/pose/rotation/w", and "/". These examples have probably been -attached to an ImageFile. Here is an example absolute pathName of a node in a -pose tree that has not yet been attached to an ImageFile: "/pose/rotation/w". - -A technical aside: the elementName of a root node does not appear in absolute -pathnames, since the "path" is between the staring node (the root) and the -ending node. By convention, in this API, a root node has the empty string ("") -as its elementName. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The absolute path name of the node. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see Node::elementName, Node::parent, Node::isRoot -*/ -ustring Node::pathName() const -{ - return impl_->pathName(); -} - -/*! -@brief Get element name of node. -@details -The elementName is a string associated with each parent-child link between -nodes. For a given parent, the elementName uniquely identifies each of its -children. Thus, any node in a tree can be identified by a sequence of -elementNames that form a path from the tree's root node (see Node::pathName for -more details). - -Three types of nodes (the container node types) can be parents: StructureNode, -VectorNode, and CompressedVectorNode. The children of a StructureNode are -explicitly given unique elementNames when they are attached to the parent (using -StructureNode::set). The children of VectorNode and CompressedVectorNode are -implicitly given elementNames based on their position in the list (starting at -"0"). In a CompressedVectorNode, the elementName can become quite large: -"1000000000" or more. However in a CompressedVectorNode, the elementName string -is not stored in the file and is deduced by the position of the child. - -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The element name of the node, or "" if a root node. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see Node::pathName, Node::parent, Node::isRoot -*/ -ustring Node::elementName() const -{ - return impl_->elementName(); -} - -/*! -@brief Get the ImageFile that was declared as the destination for the node -when it was created. -@details The first argument of the constructors of each of the 8 types of nodes -is an ImageFile that indicates which ImageFile the node will eventually be -attached to. This function returns that constructor argument. It is an error to -attempt to attach the node to a different ImageFile. However it is not an error -to not attach the node to any ImageFile (it's just wasteful). Use -Node::isAttached to check if the node actually did get attached. -@post No visible object state is modified. -@return The ImageFile that was declared as the destination for the node when it -was created. -@see Node::isAttached, -StructureNode::StructureNode(), VectorNode::VectorNode(), -CompressedVectorNode::CompressedVectorNode(), IntegerNode::IntegerNode(), -ScaledIntegerNode::ScaledIntegerNode(), FloatNode::FloatNode(), -StringNode::StringNode(), BlobNode::BlobNode() -*/ -ImageFile Node::destImageFile() const -{ - return ImageFile( impl_->destImageFile() ); -} - -/*! -@brief Has node been attached into the tree of an ImageFile. -@details Nodes are attached into an ImageFile tree by inserting them as children -(directly or indirectly) of the ImageFile's root node. Nodes can also be -attached to an ImageFile if they are used in the @c codecs or @c prototype trees -of an CompressedVectorNode that is attached. Attached nodes will be saved to -disk when the ImageFile is closed, and restored when the ImageFile is read back -in from disk. Unattached nodes will not be saved to disk. It is not recommended -to create nodes that are not eventually attached to the ImageFile. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible object state is modified. -@return @c true if node is child of (or in codecs or prototype of a child -CompressedVectorNode of) the root node of an ImageFile. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see Node::destImageFile, ImageFile::root -*/ -bool Node::isAttached() const -{ - return impl_->isAttached(); -} - -/*! -@brief Diagnostic function to print internal state of object to output stream -in an indented format. -@param [in] indent Number of spaces to indent all the printed lines of this -object. -@param [in] os Output stream to print on. -@details -All objects in the E57 Foundation API (with exception of E57Exception) support a -dump() function. These functions print out to the console a detailed listing of -the internal state of objects. The content of these printouts is not documented, -and is really of interest only to implementation developers/maintainers or the -really adventurous users. In implementations of the API other than the Reference -Implementation, the dump() functions may produce no output (although the -functions should still be defined). The output format may change from version to -version. -@post No visible object state is modified. -@throw No E57Exceptions -*/ -#ifdef E57_DEBUG -void Node::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void Node::dump( int indent, std::ostream &os ) const -{ -} -#endif - -/*! -@brief Test if two node handles refer to the same underlying node -@param [in] n2 The node to compare this node with -@post No visible object state is modified. -@return @c true if node handles refer to the same underlying node. -@throw No E57Exceptions -*/ -bool Node::operator==( Node n2 ) const -{ - return ( impl_ == n2.impl_ ); -} - -/*! -@brief Test if two node handles refer to different underlying nodes -@param [in] n2 The node to compare this node with -@post No visible object state is modified. -@return @c true if node handles refer to different underlying nodes. -@throw No E57Exceptions -*/ -bool Node::operator!=( Node n2 ) const -{ - return ( impl_ != n2.impl_ ); -} - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -Node::Node( NodeImplSharedPtr ni ) : impl_( ni ) -{ -} -//! @endcond - -//===================================================================================== -/*! -@class StructureNode -@brief An E57 element containing named child nodes. -@details -A StructureNode is a container of named child nodes, which may be any of the -eight node types. The children of a structure node must have unique -elementNames. Once a child node is set with a particular elementName, it may not -be modified. - -See Node class discussion for discussion of the common functions that -StructureNode supports. -@section structurenode_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin StructureNode::checkInvariant -@skip checkInvariant( -@until end StructureNode::checkInvariant - -@see Node -*/ - -/*! -@brief Create an empty StructureNode. -@param [in] destImageFile The ImageFile where the new node will eventually -be stored. -@details -A StructureNode is a container for collections of named E57 nodes. -The @a destImageFile indicates which ImageFile the StructureNode will eventually -be attached to. A node is attached to an ImageFile by adding it underneath the -predefined root of the ImageFile (gotten from ImageFile::root). It is not an -error to fail to attach the StructureNode to the @a destImageFile. It is an -error to attempt to attach the StructureNode to a different ImageFile. -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@pre The @a destImageFile must have been opened in write mode (i.e. -destImageFile.isWritable() must be true). -@return A smart StructureNode handle referencing the underlying object. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see Node -*/ -StructureNode::StructureNode( ImageFile destImageFile ) : impl_( new StructureNodeImpl( destImageFile.impl() ) ) -{ -} - -//! @brief Is this a root node. -//! @copydetails Node::isRoot() -bool StructureNode::isRoot() const -{ - return impl_->isRoot(); -} - -//! @brief Return parent of node, or self if a root node. -//! @copydetails Node::parent() -Node StructureNode::parent() const -{ - return Node( impl_->parent() ); -} - -//! @brief Get absolute pathname of node. -//! @copydetails Node::pathName() -ustring StructureNode::pathName() const -{ - return impl_->pathName(); -} - -//! @brief Get elementName string, that identifies the node in its parent. -//! @copydetails Node::elementName() -ustring StructureNode::elementName() const -{ - return impl_->elementName(); -} - -//! @brief Get the ImageFile that was declared as the destination for the node -//! when it was created. -//! @copydetails Node::destImageFile() -ImageFile StructureNode::destImageFile() const -{ - return ImageFile( impl_->destImageFile() ); -} - -//! @brief Has node been attached into the tree of an ImageFile. -//! @copydetails Node::isAttached() -bool StructureNode::isAttached() const -{ - return impl_->isAttached(); -} - -/*! -@brief Return number of child nodes contained by this StructureNode. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return Number of child nodes contained by this StructureNode. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see StructureNode::get(int64_t) const, -StructureNode::set, VectorNode::childCount -*/ -int64_t StructureNode::childCount() const -{ - return impl_->childCount(); -} - -/*! -@brief Is the given pathName defined relative to this node. -@param [in] pathName The absolute pathname, or pathname relative to this -object, to check. -@details -The @a pathName may be relative to this node, or absolute (starting with a "/"). -The origin of the absolute path name is the root of the tree that contains this -StructureNode. If this StructureNode is not attached to an ImageFile, the @a -pathName origin root will not the root node of an ImageFile. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return true if pathName is currently defined. -@throw ::E57_ERROR_BAD_PATH_NAME -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ImageFile::root, VectorNode::isDefined -*/ -bool StructureNode::isDefined( const ustring &pathName ) const -{ - return impl_->isDefined( pathName ); -} - -/*! -@brief Get a child element by positional index. -@param [in] index The index of child element to get, starting at 0. -@details -The order of children is not specified, and may be different than order the -children were added to the StructureNode. The order of children may change if -more children are added to the StructureNode. -@pre 0 <= @a index < childCount() -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return A smart Node handle referencing the child node. -@throw ::E57_ERROR_CHILD_INDEX_OUT_OF_BOUNDS -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see StructureNode::childCount, -StructureNode::get(const ustring&) const, VectorNode::get -*/ -Node StructureNode::get( int64_t index ) const -{ - return Node( impl_->get( index ) ); -} - -/*! -@brief Get a child by path name. -@param [in] pathName The absolute pathname, or pathname relative to this -object, of the object to get. The @a pathName may be relative to this node, or -absolute (starting with a "/"). The origin of the absolute path name is the root -of the tree that contains this StructureNode. If this StructureNode is not -attached to an ImageFile, the @a pathName origin root will not the root node of -an ImageFile. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@pre The @a pathName must be defined (i.e. isDefined(pathName)). -@post No visible state is modified. -@return A smart Node handle referencing the child node. -@throw ::E57_ERROR_BAD_PATH_NAME -@throw ::E57_ERROR_PATH_UNDEFINED -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see StructureNode::get(int64_t) const -*/ -Node StructureNode::get( const ustring &pathName ) const -{ - return Node( impl_->get( pathName ) ); -} - -/*! -@brief Add a new child at a given path - @param [in] pathName The absolute pathname, or pathname relative to this -object, that the child object @a n will be given. -@param [in] n The node to be added to the tree with given @a pathName. -@details -The @a pathName may be relative to this node, or absolute (starting with a "/"). -The origin of the absolute path name is the root of the tree that contains this -StructureNode. If this StructureNode is not attached to an ImageFile, the @a -pathName origin root will not the root node of an ImageFile. - -The path name formed from all element names in @a pathName except the last must -exist. If the @a pathName identifies the child of a VectorNode, then the last -element name in @a pathName must be numeric, and be equal to the childCount of -that VectorNode (the request is equivalent to VectorNode::append). The -StructureNode must not be a descendent of a homogeneous VectorNode with more -than one child. - -The element naming grammar specified by the ASTM E57 format standard are not -enforced in this function. This would be very difficult to do dynamically, as -some of the naming rules involve combinations of names. -@pre The new child node @a n must be a root node (i.e. n.isRoot()). -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@pre The associated destImageFile must have been opened in write mode (i.e. -destImageFile().isWritable()). -@pre The @a pathName must not already be defined (i.e. -!isDefined(pathName)). -@pre The associated destImageFile of this StructureNode and of @a n must be -same (i.e. destImageFile() == n.destImageFile()). -@post The @a pathName will be defined (i.e. isDefined(pathName)). -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_BAD_PATH_NAME -@throw ::E57_ERROR_PATH_UNDEFINED -@throw ::E57_ERROR_SET_TWICE -@throw ::E57_ERROR_ALREADY_HAS_PARENT -@throw ::E57_ERROR_DIFFERENT_DEST_IMAGEFILE -@throw ::E57_ERROR_HOMOGENEOUS_VIOLATION -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see VectorNode::append -*/ -void StructureNode::set( const ustring &pathName, const Node &n ) -{ - impl_->set( pathName, n.impl(), false ); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void StructureNode::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void StructureNode::dump( int indent, std::ostream &os ) const -{ -} -#endif - -/*! -@brief Upcast a StructureNode handle to a generic Node handle. -@details An upcast is always safe, and the compiler can automatically insert it -for initializations of Node variables and Node function arguments. -@return A smart Node handle referencing the underlying object. -@throw No E57Exceptions. -@see explanation in Node, Node::type(), StructureNode(const Node&) -*/ -StructureNode::operator Node() const -{ - /// Implicitly upcast from shared_ptr to SharedNodeImplPtr - /// and construct a Node object - return Node( impl_ ); -} - -/*! -@brief Downcast a generic Node handle to a StructureNode handle. -@param [in] n The generic handle to downcast. -@details The handle @a n must be for an underlying StructureNode, otherwise an -exception is thrown. In designs that need to avoid the exception, use -Node::type() to determine the actual type of the @a n before downcasting. This -function must be explicitly called (c++ compiler cannot insert it -automatically). -@return A smart StructureNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_NODE_DOWNCAST -@see Node::type(), StructureNode::operator Node() -*/ -StructureNode::StructureNode( const Node &n ) -{ - if ( n.type() != E57_STRUCTURE ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_NODE_DOWNCAST, "nodeType=" + toString( n.type() ) ); - } - - /// Set our shared_ptr to the downcast shared_ptr - impl_ = std::static_pointer_cast( n.impl() ); -} - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -StructureNode::StructureNode( std::weak_ptr fileParent ) : impl_( new StructureNodeImpl( fileParent ) ) -{ -} - -StructureNode::StructureNode( std::shared_ptr ni ) : impl_( ni ) -{ -} -//! @endcond - -//===================================================================================== -/*! -@class VectorNode -@brief An E57 element containing ordered vector of child nodes. -@details -A VectorNode is a container of ordered child nodes. -The child nodes are automatically assigned an elementName, which is a string -version of the positional index of the child starting at "0". Child nodes may -only be appended onto the end of a VectorNode. - -A VectorNode that is created with a restriction that its children must have the -same type is called a "homogeneous VectorNode". A VectorNode without such a -restriction is called a "heterogeneous VectorNode". - -See Node class discussion for discussion of the common functions that -StructureNode supports. -@section vectornode_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin VectorNode::checkInvariant -@skip checkInvariant( -@until end VectorNode::checkInvariant - -@see Node -*/ - -/*! -@brief Create a new empty Vector node. -@param [in] destImageFile The ImageFile where the new node will -eventually be stored. -@param [in] allowHeteroChildren Will child elements of differing types be -allowed in this VectorNode. -@details -A VectorNode is a ordered container of E57 nodes. -The @a destImageFile indicates which ImageFile the VectorNode will eventually be -attached to. A node is attached to an ImageFile by adding it underneath the -predefined root of the ImageFile (gotten from ImageFile::root). It is not an -error to fail to attach the VectorNode to the @a destImageFile. It is an error -to attempt to attach the VectorNode to a different ImageFile. - -If @a allowHeteroChildren is false, then the children that are appended to the -VectorNode must be identical in every visible characteristic except the stored -values. These visible characteristics include number of children (for -StructureNode and VectorNode descendents), number of records/prototypes/codecs -(for CompressedVectorNode), minimum/maximum attributes (for IntegerNode, -ScaledIntegerNode, FloatNode), byteCount (for BlobNode), scale/offset (for -ScaledIntegerNode), and all elementNames. The enforcement of this homogeneity -rule begins when the second child is appended to the VectorNode, thus it is not -an error to modify a child of a homogeneous VectorNode containing only one -child. - -If @a allowHeteroChildren is true, then the types of the children of the -VectorNode are completely unconstrained. -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@pre The @a destImageFile must have been opened in write mode (i.e. -destImageFile.isWritable() must be true). -@return A smart VectorNode handle referencing the underlying object. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see Node, VectorNode::allowHeteroChildren, ::E57_ERROR_HOMOGENEOUS_VIOLATION -*/ -VectorNode::VectorNode( ImageFile destImageFile, bool allowHeteroChildren ) : - impl_( new VectorNodeImpl( destImageFile.impl(), allowHeteroChildren ) ) -{ -} - -//! @brief Is this a root node. -//! @copydetails Node::isRoot() -bool VectorNode::isRoot() const -{ - return impl_->isRoot(); -} - -//! @brief Return parent of node, or self if a root node. -//! @copydetails Node::parent() -Node VectorNode::parent() const -{ - return Node( impl_->parent() ); -} - -//! @brief Get absolute pathname of node. -//! @copydetails Node::pathName() -ustring VectorNode::pathName() const -{ - return impl_->pathName(); -} - -//! @brief Get elementName string, that identifies the node in its parent.. -//! @copydetails Node::elementName() -ustring VectorNode::elementName() const -{ - return impl_->elementName(); -} - -//! @brief Get the ImageFile that was declared as the destination for the node -//! when it was created. -//! @copydetails Node::destImageFile() -ImageFile VectorNode::destImageFile() const -{ - return ImageFile( impl_->destImageFile() ); -} - -//! @brief Has node been attached into the tree of an ImageFile. -//! @copydetails Node::isAttached() -bool VectorNode::isAttached() const -{ - return impl_->isAttached(); -} - -/*! -@brief Get whether child elements are allowed to be different types? -@details -See the class discussion at bottom of VectorNode page for details of -homogeneous/heterogeneous VectorNode. The returned attribute is determined when -the VectorNode is created, and cannot be changed. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return True if child elements can be different types. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ::E57_ERROR_HOMOGENEOUS_VIOLATION -*/ -bool VectorNode::allowHeteroChildren() const -{ - return impl_->allowHeteroChildren(); -} - -/*! -@brief Get number of child elements in this VectorNode. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return Number of child elements in this VectorNode. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see VectorNode::get(int64_t), VectorNode::append, StructureNode::childCount -*/ -int64_t VectorNode::childCount() const -{ - return impl_->childCount(); -} - -/*! -@brief Is the given pathName defined relative to this node. -@param [in] pathName The absolute pathname, or pathname relative to this -object, to check. -@details -The @a pathName may be relative to this node, or absolute (starting with a "/"). -The origin of the absolute path name is the root of the tree that contains this -VectorNode. If this VectorNode is not attached to an ImageFile, the @a pathName -origin root will not the root node of an ImageFile. - -The element names of child elements of VectorNodes are numbers, encoded as -strings, starting at "0". -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return true if pathName is currently defined. -@throw ::E57_ERROR_BAD_PATH_NAME -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see StructureNode::isDefined -*/ -bool VectorNode::isDefined( const ustring &pathName ) const -{ - return impl_->isDefined( pathName ); -} - -/*! -@brief Get a child element by positional index. -@param [in] index The index of child element to get, starting at 0. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@pre 0 <= @a index < childCount() -@post No visible state is modified. -@return A smart Node handle referencing the child node. -@throw ::E57_ERROR_CHILD_INDEX_OUT_OF_BOUNDS -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see VectorNode::childCount, VectorNode::append, StructureNode::get(int64_t) const -*/ -Node VectorNode::get( int64_t index ) const -{ - return Node( impl_->get( index ) ); -} - -/*! -@brief Get a child element by string path name -@param [in] pathName The pathname, either absolute or relative, of the -object to get. -@details -The @a pathName may be relative to this node, or absolute (starting with a "/"). -The origin of the absolute path name is the root of the tree that contains this -VectorNode. If this VectorNode is not attached to an ImageFile, the @a pathName -origin root will not the root node of an ImageFile. - -The element names of child elements of VectorNodes are numbers, encoded as -strings, starting at "0". -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@pre The @a pathName must be defined (i.e. isDefined(pathName)). -@post No visible state is modified. -@return A smart Node handle referencing the child node. -@throw ::E57_ERROR_BAD_PATH_NAME -@throw ::E57_ERROR_PATH_UNDEFINED -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see VectorNode::childCount, VectorNode::append, StructureNode::get(int64_t) const -*/ -Node VectorNode::get( const ustring &pathName ) const -{ - return Node( impl_->get( pathName ) ); -} - -/*! -@brief Append a child element to end of VectorNode. -@param [in] n The node to be added as a child at end of the VectorNode. -@details -If the VectorNode is homogeneous and already has at least one child, then @a n -must be identical to the existing children in every visible characteristic -except the stored values. These visible characteristics include number of -children (for StructureNode and VectorNode descendents), number of -records/prototypes/codecs (for CompressedVectorNode), minimum/maximum attributes -(for IntegerNode, ScaledIntegerNode, FloatNode), byteCount (for BlobNode), -scale/offset (for ScaledIntegerNode), and all elementNames. - -The VectorNode must not be a descendent of a homogeneous VectorNode with more -than one child. -@pre The new child node @a n must be a root node (not already having a -parent). -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@pre The associated destImageFile must have been opened in write mode (i.e. -destImageFile().isWritable()). -@post the childCount is incremented. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_HOMOGENEOUS_VIOLATION -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_ALREADY_HAS_PARENT -@throw ::E57_ERROR_DIFFERENT_DEST_IMAGEFILE -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see VectorNode::childCount, VectorNode::get(int64_t), StructureNode::set -*/ -void VectorNode::append( const Node &n ) -{ - impl_->append( n.impl() ); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void VectorNode::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void VectorNode::dump( int indent, std::ostream &os ) const -{ -} -#endif - -/*! -@brief Upcast a VectorNode handle to a generic Node handle. -@details An upcast is always safe, and the compiler can automatically insert it -for initializations of Node variables and Node function arguments. -@return A smart Node handle referencing the underlying object. -@throw No E57Exceptions. -@see explanation in Node, Node::type(), VectorNode(const Node&) -*/ -VectorNode::operator Node() const -{ - /// Implicitly upcast from shared_ptr to SharedNodeImplPtr - /// and construct a Node object - return Node( impl_ ); -} - -/*! -@brief Downcast a generic Node handle to a VectorNode handle. -@param [in] n The generic handle to downcast. -@details The handle @a n must be for an underlying VectorNode, otherwise an -exception is thrown. In designs that need to avoid the exception, use -Node::type() to determine the actual type of the @a n before downcasting. This -function must be explicitly called (c++ compiler cannot insert it -automatically). -@return A smart VectorNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_NODE_DOWNCAST -@see Node::type(), VectorNode::operator Node() -*/ -VectorNode::VectorNode( const Node &n ) -{ - if ( n.type() != E57_VECTOR ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_NODE_DOWNCAST, "nodeType=" + toString( n.type() ) ); - } - - /// Set our shared_ptr to the downcast shared_ptr - impl_ = std::static_pointer_cast( n.impl() ); -} - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -VectorNode::VectorNode( std::shared_ptr ni ) : impl_( ni ) -{ -} -//! @endcond - -//===================================================================================== -/*! -@class SourceDestBuffer -@brief A memory buffer to transfer data to/from a CompressedVectorNode in a -block. -@details -The SourceDestBuffer is an encapsulation of a buffer in memory that will -transfer data to/from a field in a CompressedVectorNode. The API user is -responsible for creating the actual memory buffer, describing it correctly to -the API, making sure it exists during the transfer period, and destroying it -after the transfer is complete. Additionally, the SourceDestBuffer has -information that specifies the connection to the CompressedVectorNode field -(i.e. the field's path name in the prototype). - -The type of buffer element may be an assortment of built-in C++ memory types. -There are all combinations of signed/unsigned and 8/16/32/64 bit integers -(except unsigned 64bit integer, which is not supported in the ASTM standard), -bool, float, double, as well as a vector of variable length unicode strings. The -compiler selects the appropriate constructor automatically based on the type of -the buffer array. However, the API user is responsible for reporting the correct -length and stride options (otherwise unspecified behavior can occur). - -The connection of the SourceDestBuffer to a CompressedVectorNode field is -established by specifying the pathName. There are several options to this -connection: doConversion and doScaling, which are described in the constructor -documentation. - -@section sourcedestbuffer_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin SourceDestBuffer::checkInvariant -@skip checkInvariant( -@until end SourceDestBuffer::checkInvariant - -@see Node -*/ - -/*! -@brief Designate buffers to transfer data to/from a CompressedVectorNode in a -block. -@param [in] destImageFile The ImageFile where the new node will eventually be -stored. -@param [in] pathName The pathname of the field in CompressedVectorNode -that will transfer data to/from. -@param [in] b The caller allocated memory buffer. -@param [in] capacity The total number of memory elements in buffer @a b. -@param [in] doConversion Will a conversion be attempted between memory and -ImageFile representations. -@param [in] doScaling In a ScaledInteger field, do memory elements hold -scaled values, if false they hold raw values. -@param [in] stride The number of bytes between memory elements. If -zero, defaults to sizeof memory element. -@details -This overloaded form of the SourceDestBuffer constructor declares a buffer @a b -to be the source/destination of a transfer of values stored in a -CompressedVectorNode.\n\n - -The @a pathName will be used to identify a Node in the prototype that will -get/receive data from this buffer. The @a pathName may be an absolute path name -(e.g. "/cartesianX") or a path name relative to the root of the prototype (i.e. -the absolute path name without the leading "/", for example: "cartesianX").\n\n - -The type of @a b is used to determine the MemoryRepresentation of the -SourceDestBuffer. The buffer @a b may be used for multiple block transfers. See -discussions of operation of SourceDestBuffer attributes in -SourceDestBuffer::memoryRepresentation, SourceDestBuffer::capacity, -SourceDestBuffer::doConversion, and SourceDestBuffer::doScaling, and -SourceDestBuffer::stride.\n\n - -The API user is responsible for ensuring that the lifetime of the @a b memory -buffer exceeds the time that it is used in transfers (i.e. the E57 Foundation -Implementation cannot detect that the buffer been destroyed).\n\n - -The @a capacity must match the capacity of all other SourceDestBuffers that will -participate in a transfer with a CompressedVectorNode. - -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@pre The stride must be >= sizeof(*b) -@return A smart SourceDestBuffer handle referencing the underlying object. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_BAD_PATH_NAME -@throw ::E57_ERROR_BAD_BUFFER -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ImageFile::reader, ImageFile::writer, -CompressedVectorReader::read(std::vector&), -CompressedVectorWriter::write(std::vector&) -*/ -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, int8_t *b, const size_t capacity, - bool doConversion, bool doScaling, size_t stride ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, capacity, doConversion, doScaling ) ) -{ - impl_->setTypeInfo( b, stride ); -} - -//! @brief Designate buffers to transfer data to/from a CompressedVectorNode -//! in a block. -//! @copydetails SourceDestBuffer::SourceDestBuffer(ImageFile,const -//! ustring,int8_t*,size_t,bool,bool,size_t) -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, uint8_t *b, const size_t capacity, - bool doConversion, bool doScaling, size_t stride ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, capacity, doConversion, doScaling ) ) -{ - impl_->setTypeInfo( b, stride ); -} - -//! @brief Designate buffers to transfer data to/from a CompressedVectorNode -//! in a block. -//! @copydetails SourceDestBuffer::SourceDestBuffer(ImageFile,const -//! ustring,int8_t*,size_t,bool,bool,size_t) -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, int16_t *b, const size_t capacity, - bool doConversion, bool doScaling, size_t stride ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, capacity, doConversion, doScaling ) ) -{ - impl_->setTypeInfo( b, stride ); -} - -//! @brief Designate buffers to transfer data to/from a CompressedVectorNode -//! in a block. -//! @copydetails SourceDestBuffer::SourceDestBuffer(ImageFile,const -//! ustring,int8_t*,size_t,bool,bool,size_t) -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, uint16_t *b, - const size_t capacity, bool doConversion, bool doScaling, size_t stride ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, capacity, doConversion, doScaling ) ) -{ - impl_->setTypeInfo( b, stride ); -} - -//! @brief Designate buffers to transfer data to/from a CompressedVectorNode -//! in a block. -//! @copydetails SourceDestBuffer::SourceDestBuffer(ImageFile,const -//! ustring,int8_t*,size_t,bool,bool,size_t) -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, int32_t *b, const size_t capacity, - bool doConversion, bool doScaling, size_t stride ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, capacity, doConversion, doScaling ) ) -{ - impl_->setTypeInfo( b, stride ); -} - -//! @brief Designate buffers to transfer data to/from a CompressedVectorNode -//! in a block. -//! @copydetails SourceDestBuffer::SourceDestBuffer(ImageFile,const -//! ustring,int8_t*,size_t,bool,bool,size_t) -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, uint32_t *b, - const size_t capacity, bool doConversion, bool doScaling, size_t stride ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, capacity, doConversion, doScaling ) ) -{ - impl_->setTypeInfo( b, stride ); -} - -//! @brief Designate buffers to transfer data to/from a CompressedVectorNode -//! in a block. -//! @copydetails SourceDestBuffer::SourceDestBuffer(ImageFile,const -//! ustring,int8_t*,size_t,bool,bool,size_t) -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, int64_t *b, const size_t capacity, - bool doConversion, bool doScaling, size_t stride ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, capacity, doConversion, doScaling ) ) -{ - impl_->setTypeInfo( b, stride ); -} - -//! @brief Designate buffers to transfer data to/from a CompressedVectorNode -//! in a block. -//! @copydetails SourceDestBuffer::SourceDestBuffer(ImageFile,const -//! ustring,int8_t*,size_t,bool,bool,size_t) -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, bool *b, const size_t capacity, - bool doConversion, bool doScaling, size_t stride ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, capacity, doConversion, doScaling ) ) -{ - impl_->setTypeInfo( b, stride ); -} - -//! @brief Designate buffers to transfer data to/from a CompressedVectorNode -//! in a block. -//! @copydetails SourceDestBuffer::SourceDestBuffer(ImageFile,const -//! ustring,int8_t*,size_t,bool,bool,size_t) -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, float *b, const size_t capacity, - bool doConversion, bool doScaling, size_t stride ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, capacity, doConversion, doScaling ) ) -{ - impl_->setTypeInfo( b, stride ); -} - -//! @brief Designate buffers to transfer data to/from a CompressedVectorNode -//! in a block. -//! @copydetails SourceDestBuffer::SourceDestBuffer(ImageFile,const -//! ustring,int8_t*,size_t,bool,bool,size_t) -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, double *b, const size_t capacity, - bool doConversion, bool doScaling, size_t stride ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, capacity, doConversion, doScaling ) ) -{ - impl_->setTypeInfo( b, stride ); -} - -/*! -@brief Designate vector of strings to transfer data to/from a CompressedVector -as a block. -@param [in] destImageFile The ImageFile where the new node will eventually be -stored. -@param [in] pathName The pathname of the field in CompressedVectorNode -that will transfer data to/from. -@param [in] b The caller created vector of ustrings to transfer -from/to. -@details -This overloaded form of the SourceDestBuffer constructor declares a -vector to be the source/destination of a transfer of StringNode values -stored in a CompressedVectorNode. - -The @a pathName will be used to identify a Node in the prototype that will -get/receive data from this buffer. The @a pathName may be an absolute path name -(e.g. "/cartesianX") or a path name relative to the root of the prototype (i.e. -the absolute path name without the leading "/", for example: "cartesianX"). - -The @a b->size() must match capacity of all other SourceDestBuffers that will -participate in a transfer with a CompressedVectorNode (string or any other type -of buffer). In a read into the SourceDestBuffer, the previous contents of the -strings in the vector are lost, and the memory space is potentially freed. The -@a b->size() of the vector will not be changed. It is an error to request a -read/write of more records that @a b->size() (just as it would be for buffers of -integer types). The API user is responsible for ensuring that the lifetime of -the @a b vector exceeds the time that it is used in transfers (i.e. the E57 -Foundation Implementation cannot detect that the buffer been destroyed). - -@pre b.size() must be > 0. -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@return A smart SourceDestBuffer handle referencing the underlying object. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_BAD_PATH_NAME -@throw ::E57_ERROR_BAD_BUFFER -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see SourceDestBuffer::doConversion for discussion on representations compatible with string SourceDestBuffers. -*/ -SourceDestBuffer::SourceDestBuffer( ImageFile destImageFile, const ustring &pathName, StringList *b ) : - impl_( new SourceDestBufferImpl( destImageFile.impl(), pathName, b ) ) -{ -} - -/*! -@brief Get path name in prototype that this SourceDestBuffer will transfer -data to/from. -@details -The prototype of a CompressedVectorNode describes the fields that are in each -record. This function returns the path name of the node in the prototype tree -that this SourceDestBuffer will write/read. The correctness of this path name is -checked when this SourceDestBuffer is associated with a CompressedVectorNode -(either in CompressedVectorNode::writer, -CompressedVectorWriter::write(std::vector&, unsigned), -CompressedVectorNode::reader, -CompressedVectorReader::read(std::vector&)). - -@post No visible state is modified. -@return Path name in prototype that this SourceDestBuffer will transfer data -to/from. -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVector, CompressedVectorNode::prototype -*/ -ustring SourceDestBuffer::pathName() const -{ - return impl_->pathName(); -} - -/*! -@brief Get memory representation of the elements in this SourceDestBuffer. -@details -The memory representation is deduced from which overloaded SourceDestBuffer -constructor was used. The memory representation is independent of the type and -minimum/maximum bounds of the node in the prototype that the SourceDestBuffer -will transfer to/from. However, some combinations will result in an error if -doConversion is not requested (e.g. E57_INT16 and FloatNode). - -Some combinations risk an error occurring during a write, if a value is too -large (e.g. writing a E57_INT16 memory representation to an IntegerNode with -minimum=-1024 maximum=1023). Some combinations risk an error occurring during a -read, if a value is too large (e.g. reading an IntegerNode with minimum=-1024 -maximum=1023 int an E57_INT8 memory representation). Some combinations are never -possible (e.g. E57_INT16 and StringNode). -@post No visible state is modified. -@return Memory representation of the elements in buffer. -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see MemoryRepresentation, NodeType -*/ -MemoryRepresentation SourceDestBuffer::memoryRepresentation() const -{ - return impl_->memoryRepresentation(); -} - -/*! -@brief Get total capacity of buffer. -@details -The API programmer is responsible for correctly specifying the length of a -buffer. This function returns that declared length. If the length is incorrect -(in particular, too long) memory may be corrupted or erroneous values written. -@post No visible state is modified. -@return Total capacity of buffer. -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -*/ -size_t SourceDestBuffer::capacity() const -{ - return impl_->capacity(); -} - -/*! -@brief Get whether conversions will be performed to match the memory type of -buffer. -@details -The API user must explicitly request conversion between basic representation -groups in memory and on the disk. The four basic representation groups are: -integer, boolean, floating point, and string. There is no distinction between -integer and boolean groups on the disk (they both use IntegerNode). A explicit -request for conversion between single and double precision floating point -representations is not required. - -The most useful conversion is between integer and floating point representation -groups. Conversion from integer to floating point representations cannot result -in an overflow, and is usually loss-less (except for extremely large integers). -Conversion from floating point to integer representations can result in an -overflow, and can be lossy. - -Conversion between any of the integer, boolean, and floating point -representation groups is supported. No conversion from the string to any other -representation group is possible. Missing or unsupported conversions are -detected when the first transfer is attempted (i.e. not when the -CompressedVectorReader or CompressedVectorWriter is created). - -@post No visible state is modified. -@return true if conversions will be performed to match the memory type of -buffer. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -*/ -bool SourceDestBuffer::doConversion() const -{ - return impl_->doConversion(); -} - -/*! -@brief Get whether scaling will be performed for ScaledIntegerNode transfers. -@details -The doScaling option only applies to ScaledIntegerNodes stored in a -CompressedVectorNode on the disk (it is ignored if a ScaledIntegerNode is not -involved). - -As a convenience, an E57 Foundation Implementation can perform scaling of data -so that the API user can manipulate scaledValues rather than rawValues. For a -reader, the scaling process is: scaledValue = (rawValue * scale) + offset. For a -writer, the scaling process is reversed: rawValue = (scaledValue - offset) / -scale. The result performing a scaling in a reader (or "unscaling" in a writer) -is always a floating point number. This floating point number may have to be -converted to be compatible with the destination representation. If the -destination representation is not floating point, there is a risk of violating -declared min/max bounds. Because of this risk, it is recommended that scaling -only be requested for reading scaledValues from ScaledIntegerNodes into floating -point numbers in memory. - -It is also possible (and perhaps safest of all) to never request that scaling be -performed, and always deal with rawValues outside the API. Note this does not -mean that ScaledIntegerNodes should be avoided. ScaledIntgerNodes are essential -for encoding numeric data with fractional parts in CompressedVectorNodes. -Because the ASTM E57 format recommends that SI units without prefix be used -(i.e. meters, not milli-meters or micro-furlongs), almost every measured value -will have a fractional part. - -@post No visible state is modified. -@return true if scaling will be performed for ScaledInteger transfers. -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode -*/ -bool SourceDestBuffer::doScaling() const -{ - return impl_->doScaling(); -} - -/*! -@brief Get number of bytes between consecutive memory elements in buffer -@details -Elements in a memory buffer do not have to be consecutive. -They can also be spaced at regular intervals. -This allows a value to be picked out of an array of C++ structures (the stride -would be the size of the structure). In the case that the element values are -stored consecutively in memory, the stride equals the size of the memory -representation of the element. -@post No visible state is modified. -@return Number of bytes between consecutive memory elements in buffer -*/ -size_t SourceDestBuffer::stride() const -{ - return impl_->stride(); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void SourceDestBuffer::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void SourceDestBuffer::dump( int indent, std::ostream &os ) const -{ -} -#endif - -//===================================================================================== -/*! -@class CompressedVectorReader -@brief An iterator object keeping track of a read in progress from a -CompressedVectorNode. -@details -A CompressedVectorReader object is a block iterator that reads blocks of records -from a CompressedVectorNode and stores them in memory buffers -(SourceDestBuffers). Blocks of records are processed rather than a single -record-at-a-time for efficiency reasons. The CompressedVectorReader class -encapsulates all the state that must be saved in between the processing of one -record block and the next (e.g. partially read disk pages, or data decompression -state). New memory buffers can be used for each record block read, or the -previous buffers can be reused. - -CompressedVectorReader objects have an open/closed state. -Initially a newly created CompressedVectorReader is in the open state. -After the API user calls CompressedVectorReader::close, the object will be in -the closed state and no more data transfers will be possible. - -There is no CompressedVectorReader constructor in the API. -The function CompressedVectorNode::reader returns an already constructed -CompressedVectorReader object with given memory buffers (SourceDestBuffers) -already associated. - -It is recommended to call CompressedVectorReader::close to gracefully end the -transfer. Unlike the CompressedVectorWriter, not all fields in the record of the -CompressedVectorNode are required to be read at one time. - -@section CompressedVectorReader_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin CompressedVectorReader::checkInvariant -@skip checkInvariant( -@until end CompressedVectorReader::checkInvariant - -@see CompressedVectorNode, CompressedVectorWriter -*/ - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -CompressedVectorReader::CompressedVectorReader( std::shared_ptr ni ) : impl_( ni ) -{ -} -//! @endcond - -/*! -@brief Request transfer of blocks of data from CompressedVectorNode into -previously designated destination buffers. -@details -The SourceDestBuffers used are previously designated either in -CompressedVectorNode::reader where this object was created, or in the last call -to CompressedVectorReader::read(std::vector&) where new -buffers were designated. The function will always return the full number of -records requested (the capacity of the SourceDestBuffers) unless it has reached -the end of the CompressedVectorNode, in which case it will return less than the -capacity of the SourceDestBuffers. Partial reads will store the records at the -beginning of the SourceDestBuffers. It is not an error to call this function -after all records in the CompressedVectorNode have been read (the function -returns 0). - -If a conversion or bounds error occurs during the transfer, the -CompressedVectorReader is left in an undocumented state (it can't be used any -further). If a file I/O or checksum error occurs during the transfer, both the -CompressedVectorReader and the associated ImageFile are left in an undocumented -state (they can't be used any further). - -The API user is responsible for ensuring that the underlying memory buffers -represented in the SourceDestBuffers still exist when this function is called. -The E57 Foundation Implementation cannot detect that a memory buffer been -destroyed. - -@pre The associated ImageFile must be open. -@pre This CompressedVectorReader must be open (i.e isOpen()) -@return The number of records read. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_READER_NOT_OPEN -@throw ::E57_ERROR_CONVERSION_REQUIRED This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_VALUE_NOT_REPRESENTABLE This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_REAL64_TOO_LARGE This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_EXPECTING_NUMERIC This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_EXPECTING_USTRING This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_BAD_CV_PACKET This CompressedVectorReader, associated -ImageFile in undocumented state -@throw ::E57_ERROR_LSEEK_FAILED This CompressedVectorReader, associated -ImageFile in undocumented state -@throw ::E57_ERROR_READ_FAILED This CompressedVectorReader, associated -ImageFile in undocumented state -@throw ::E57_ERROR_BAD_CHECKSUM This CompressedVectorReader, associated -ImageFile in undocumented state -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorReader::read(std::vector&), -CompressedVectorNode::reader, SourceDestBuffer, -CompressedVectorReader::read(std::vector&) -*/ -unsigned CompressedVectorReader::read() -{ - return impl_->read(); -} - -/*! -@brief Request transfer of block of data from CompressedVectorNode into given -destination buffers. -@param [in] dbufs Vector of memory buffers that will receive data read -from a CompressedVectorNode. -@details -The @a dbufs must all have the same capacity. -The specified @a dbufs must have same number of elements as previously -designated SourceDestBuffer vector. The each SourceDestBuffer within @a dbufs -must be identical to the previously designated SourceDestBuffer except for -capacity and buffer address. - -The @a dbufs locations are saved so that a later call to -CompressedVectorReader::read() can be used without having to re-specify the -SourceDestBuffers. - -The function will always return the full number of records requested (the -capacity of the SourceDestBuffers) unless it has reached the end of the -CompressedVectorNode, in which case it will return less than the capacity of the -SourceDestBuffers. Partial reads will store the records at the beginning of the -SourceDestBuffers. It is not an error to call this function after all records in -the CompressedVectorNode have been read (the function returns 0). - -If a conversion or bounds error occurs during the transfer, the -CompressedVectorReader is left in an undocumented state (it can't be used any -further). If a file I/O or checksum error occurs during the transfer, both the -CompressedVectorReader and the associated ImageFile are left in an undocumented -state (they can't be used any further). - -The API user is responsible for ensuring that the underlying memory buffers -represented in the SourceDestBuffers still exist when this function is called. -The E57 Foundation Implementation cannot detect that a memory buffer been -destroyed. - -@pre The associated ImageFile must be open. -@pre This CompressedVectorReader must be open (i.e isOpen()) -@return The number of records read. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_READER_NOT_OPEN -@throw ::E57_ERROR_PATH_UNDEFINED -@throw ::E57_ERROR_BUFFER_SIZE_MISMATCH -@throw ::E57_ERROR_BUFFER_DUPLICATE_PATHNAME -@throw ::E57_ERROR_CONVERSION_REQUIRED This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_VALUE_NOT_REPRESENTABLE This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_REAL64_TOO_LARGE This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_EXPECTING_NUMERIC This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_EXPECTING_USTRING This CompressedVectorReader -in undocumented state -@throw ::E57_ERROR_BAD_CV_PACKET This CompressedVectorReader, associated -ImageFile in undocumented state -@throw ::E57_ERROR_LSEEK_FAILED This CompressedVectorReader, associated -ImageFile in undocumented state -@throw ::E57_ERROR_READ_FAILED This CompressedVectorReader, associated -ImageFile in undocumented state -@throw ::E57_ERROR_BAD_CHECKSUM This CompressedVectorReader, associated -ImageFile in undocumented state -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorReader::read(), CompressedVectorNode::reader, SourceDestBuffer -*/ -unsigned CompressedVectorReader::read( std::vector &dbufs ) -{ - return impl_->read( dbufs ); -} - -/*! -@brief Set record number of CompressedVectorNode where next read will start. -@param [in] recordNumber The index of record in ComressedVectorNode where -next read using this CompressedVectorReader will start. -@details -This function may be called at any time (as long as ImageFile and -CompressedVectorReader are open). The next read will start at the given -recordNumber. It is not an error to seek to recordNumber = childCount() (i.e. to -one record past end of CompressedVectorNode). - -@pre @a recordNumber <= childCount() of CompressedVectorNode. -@pre The associated ImageFile must be open. -@pre This CompressedVectorReader must be open (i.e isOpen()) -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_READER_NOT_OPEN -@throw ::E57_ERROR_BAD_CV_PACKET -@throw ::E57_ERROR_LSEEK_FAILED -@throw ::E57_ERROR_READ_FAILED -@throw ::E57_ERROR_BAD_CHECKSUM -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorNode::reader -*/ -void CompressedVectorReader::seek( int64_t recordNumber ) -{ - impl_->seek( recordNumber ); -} - -/*! -@brief End the read operation. -@details -It is recommended that this function be called to gracefully end a transfer to a -CompressedVectorNode. It is not an error to call this function if the -CompressedVectorReader is already closed. This function will cause the -CompressedVectorReader to enter the closed state, and any further transfers -requests will fail. - -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorReader::isOpen, CompressedVectorNode::reader -*/ -void CompressedVectorReader::close() -{ - impl_->close(); -} - -/*! -@brief Test whether CompressedVectorReader is still open for reading. -@pre The associated ImageFile must be open. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorReader::close, CompressedVectorNode::reader -*/ -bool CompressedVectorReader::isOpen() -{ - return impl_->isOpen(); -} - -/*! -@brief Return the CompressedVectorNode being read. -@details -It is not an error if this CompressedVectorReader is closed. -@pre The associated ImageFile must be open. -@return A smart CompressedVectorNode handle referencing the underlying object -being read from. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorReader::close, CompressedVectorNode::reader -*/ -CompressedVectorNode CompressedVectorReader::compressedVectorNode() const -{ - return impl_->compressedVectorNode(); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void CompressedVectorReader::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void CompressedVectorReader::dump( int indent, std::ostream &os ) const -{ -} -#endif - -//===================================================================================== -/*! -@class CompressedVectorWriter -@brief An iterator object keeping track of a write in progress to a -CompressedVectorNode. -@details -A CompressedVectorWriter object is a block iterator that reads blocks of records -from memory and stores them in a CompressedVectorNode. Blocks of records are -processed rather than a single record-at-a-time for efficiency reasons. The -CompressedVectorWriter class encapsulates all the state that must be saved in -between the processing of one record block and the next (e.g. partially written -disk pages, partially filled bytes in a bytestream, or data compression state). -New memory buffers can be used for each record block write, or the previous -buffers can be reused. - -CompressedVectorWriter objects have an open/closed state. -Initially a newly created CompressedVectorWriter is in the open state. -After the API user calls CompressedVectorWriter::close, the object will be in -the closed state and no more data transfers will be possible. - -There is no CompressedVectorWriter constructor in the API. -The function CompressedVectorNode::writer returns an already constructed -CompressedVectorWriter object with given memory buffers (SourceDestBuffers) -already associated. CompressedVectorWriter::close must explicitly be called to -safely and gracefully end the transfer. - -@b Warning: If CompressedVectorWriter::close is not called before the -CompressedVectorWriter destructor is invoked, all writes to the -CompressedVectorNode will be lost (it will have zero children). - -@section CompressedVectorWriter_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin CompressedVectorWriter::checkInvariant -@skip checkInvariant( -@until end CompressedVectorWriter::checkInvariant - -@see CompressedVectorNode, CompressedVectorReader -*/ - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -CompressedVectorWriter::CompressedVectorWriter( std::shared_ptr ni ) : impl_( ni ) -{ -} -//! @endcond - -/*! -@brief Request transfer of blocks of data to CompressedVectorNode from -previously designated source buffers. -@param [in] recordCount Number of records to write. -@details -The SourceDestBuffers used are previously designated either in -CompressedVectorNode::writer where this object was created, or in the last call -to CompressedVectorWriter::write(std::vector&, unsigned) where -new buffers were designated. - -If a conversion or bounds error occurs during the transfer, the -CompressedVectorWriter is left in an undocumented state (it can't be used any -further), and all previously written records are deleted from the associated -CompressedVectorNode which will then have zero children. If a file I/O or -checksum error occurs during the transfer, both this CompressedVectorWriter and -the associated ImageFile are left in an undocumented state (they can't be used -any further). If CompressedVectorWriter::close is not called before the -CompressedVectorWriter destructor is invoked, all writes to the -CompressedVectorNode will be lost (it will have zero children). - -@pre The associated ImageFile must be open. -@pre This CompressedVectorWriter must be open (i.e isOpen()) -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_WRITER_NOT_OPEN -@throw ::E57_ERROR_PATH_UNDEFINED -@throw ::E57_ERROR_NO_BUFFER_FOR_ELEMENT -@throw ::E57_ERROR_BUFFER_SIZE_MISMATCH -@throw ::E57_ERROR_BUFFER_DUPLICATE_PATHNAME -@throw ::E57_ERROR_CONVERSION_REQUIRED This CompressedVectorWriter in -undocumented state, associated CompressedVectorNode modified but consistent, -associated ImageFile modified but consistent. -@throw ::E57_ERROR_VALUE_OUT_OF_BOUNDS This CompressedVectorWriter in -undocumented state, associated CompressedVectorNode modified but consistent, -associated ImageFile modified but consistent. -@throw ::E57_ERROR_VALUE_NOT_REPRESENTABLE This CompressedVectorWriter in -undocumented state, associated CompressedVectorNode modified but consistent, -associated ImageFile modified but consistent. -@throw ::E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE This CompressedVectorWriter -in undocumented state, associated CompressedVectorNode modified but consistent, -associated ImageFile modified but consistent. -@throw ::E57_ERROR_REAL64_TOO_LARGE This CompressedVectorWriter in -undocumented state, associated CompressedVectorNode modified but consistent, -associated ImageFile modified but consistent. -@throw ::E57_ERROR_EXPECTING_NUMERIC This CompressedVectorWriter in -undocumented state, associated CompressedVectorNode modified but consistent, -associated ImageFile modified but consistent. -@throw ::E57_ERROR_EXPECTING_USTRING This CompressedVectorWriter in -undocumented state, associated CompressedVectorNode modified but consistent, -associated ImageFile modified but consistent. -@throw ::E57_ERROR_LSEEK_FAILED This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_READ_FAILED This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_WRITE_FAILED This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_BAD_CHECKSUM This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorWriter::write(std::vector&,unsigned), -CompressedVectorNode::writer, CompressedVectorWriter::close, SourceDestBuffer, -E57Exception -*/ -void CompressedVectorWriter::write( const size_t recordCount ) -{ - impl_->write( recordCount ); -} - -/*! -@brief Request transfer of block of data to CompressedVectorNode from given -source buffers. -@param [in] sbufs Vector of memory buffers that hold data to be -written to a CompressedVectorNode. -@param [in] recordCount Number of records to write. -@details -The @a sbufs must all have the same capacity. -The @a sbufs capacity must be >= @a recordCount. -The specified @a sbufs must have same number of elements as previously -designated SourceDestBuffer vector. The each SourceDestBuffer within @a sbufs -must be identical to the previously designated SourceDestBuffer except for -capacity and buffer address. - -The @a sbufs locations are saved so that a later call to -CompressedVectorWriter::write(unsigned) can be used without having to re-specify -the SourceDestBuffers. - -If a conversion or bounds error occurs during the transfer, the -CompressedVectorWriter is left in an undocumented state (it can't be used any -further), and all previously written records are deleted from the the associated -CompressedVectorNode which will then have zero children. If a file I/O or -checksum error occurs during the transfer, both this CompressedVectorWriter and -the associated ImageFile are left in an undocumented state (they can't be used -any further). - -@b Warning: If CompressedVectorWriter::close is not called before the -CompressedVectorWriter destructor is invoked, all writes to the -CompressedVectorNode will be lost (it will have zero children). - -@pre The associated ImageFile must be open. -@pre This CompressedVectorWriter must be open (i.e isOpen()) -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_WRITER_NOT_OPEN -@throw ::E57_ERROR_PATH_UNDEFINED -@throw ::E57_ERROR_NO_BUFFER_FOR_ELEMENT -@throw ::E57_ERROR_BUFFER_SIZE_MISMATCH -@throw ::E57_ERROR_BUFFER_DUPLICATE_PATHNAME -@throw ::E57_ERROR_CONVERSION_REQUIRED This CompressedVectorWriter in -undocumented state, associated ImageFile modified but consistent. -@throw ::E57_ERROR_VALUE_OUT_OF_BOUNDS This CompressedVectorWriter in -undocumented state, associated ImageFile modified but consistent. -@throw ::E57_ERROR_VALUE_NOT_REPRESENTABLE This CompressedVectorWriter in -undocumented state, associated ImageFile modified but consistent. -@throw ::E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE This CompressedVectorWriter -in undocumented state, associated ImageFile modified but consistent. -@throw ::E57_ERROR_REAL64_TOO_LARGE This CompressedVectorWriter in -undocumented state, associated ImageFile modified but consistent. -@throw ::E57_ERROR_EXPECTING_NUMERIC This CompressedVectorWriter in -undocumented state, associated ImageFile modified but consistent. -@throw ::E57_ERROR_EXPECTING_USTRING This CompressedVectorWriter in -undocumented state, associated ImageFile modified but consistent. -@throw ::E57_ERROR_LSEEK_FAILED This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_READ_FAILED This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_WRITE_FAILED This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_BAD_CHECKSUM This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorWriter::write(unsigned), CompressedVectorNode::writer, -CompressedVectorWriter::close, SourceDestBuffer, E57Exception -*/ -void CompressedVectorWriter::write( std::vector &sbufs, const size_t recordCount ) -{ - impl_->write( sbufs, recordCount ); -} - -/*! -@brief End the write operation. -@details -This function must be called to safely and gracefully end a transfer to a -CompressedVectorNode. This is required because errors cannot be communicated -from the CompressedVectorNode destructor (in C++ destructors can't throw -exceptions). It is not an error to call this function if the -CompressedVectorWriter is already closed. This function will cause the -CompressedVectorWriter to enter the closed state, and any further transfers -requests will fail. - -@b Warning: If this function is not called before the CompressedVectorWriter -destructor is invoked, all writes to the CompressedVectorNode will be lost (it -will have zero children). -@pre The associated ImageFile must be open. -@post This CompressedVectorWriter is closed (i.e !isOpen()) -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_LSEEK_FAILED This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_READ_FAILED This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_WRITE_FAILED This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_BAD_CHECKSUM This CompressedVectorWriter, associated -ImageFile in undocumented state -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorWriter::isOpen -*/ -void CompressedVectorWriter::close() -{ - impl_->close(); -} - -/*! -@brief Test whether CompressedVectorWriter is still open for writing. -@pre The associated ImageFile must be open. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorWriter::close, CompressedVectorNode::writer -*/ -bool CompressedVectorWriter::isOpen() -{ - return impl_->isOpen(); -} - -/*! -@brief Return the CompressedVectorNode being written to. -@pre The associated ImageFile must be open. -@return A smart CompressedVectorNode handle referencing the underlying object -being written to. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorNode::writer -*/ -CompressedVectorNode CompressedVectorWriter::compressedVectorNode() const -{ - return impl_->compressedVectorNode(); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void CompressedVectorWriter::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void CompressedVectorWriter::dump( int indent, std::ostream &os ) const -{ -} -#endif - -//===================================================================================== -/*! -@class CompressedVectorNode -@brief An E57 element containing ordered vector of child nodes, stored in an -efficient binary format. -@details -The CompressedVectorNode encodes very long sequences of identically typed -records. In an E57 file, the per-point information (coordinates, intensity, -color, time stamp etc.) are stored in a CompressedVectorNode. For time and space -efficiency, the CompressedVectorNode data is stored in a binary section of the -E57 file. - -Conceptually, the CompressedVectorNode encodes a structure that looks very much -like a homogeneous VectorNode object. However because of the huge volume of data -(E57 files can store more than 10 billion points) within a CompressedVectorNode, -the functions for accessing the data are dramatically different. -CompressedVectorNode data is accessed in large blocks of records (100s to 1000s -at a time). - -Two attributes are required to create a new CompressedVectorNode. -The first attribute describes the shape of the record that will be stored. -This record type description is called the @c prototype of the -CompressedVectorNode. Often the @c prototype will be a StructNode with a single -level of named child elements. However, the prototype can be a tree of any depth -consisting of the following node types: IntegerNode, ScaledIntegerNode, -FloatNode, StringNode, StructureNode, or VectorNode (i.e. CompressedVectorNode -and BlobNode are not allowed). Only the node types and attributes are used in -the prototype, the values stored are ignored. For example, if the prototype -contains an IntegerNode, with a value=0, minimum=0, maximum=1023, then this -means that each record will contain an integer that can take any value in the -interval [0,1023]. As a second example, if the prototype contains an -ScaledIntegerNode, with a value=0, minimum=0, maximum=1023, scale=.001, offset=0 -then this means that each record will contain an integer that can take any value -in the interval [0,1023] and if a reader requests the scaledValue of the field, -the rawValue should be multiplied by 0.001. - -The second attribute needed to describe a new CompressedVectorNode is the @c -codecs description of how the values of the records are to be represented on the -disk. The codec object is a VectorNode of a particular format that describes the -encoding for each field in the record, which codec will be used to transfer the -values to and from the disk. Currently only one codec is defined for E57 files, -the bitPackCodec, which copies the numbers from memory, removes any unused bit -positions, and stores the without additional spaces on the disk. The -bitPackCodec has no configuration options or parameters to tune. In the ASTM -standard, if no codec is specified, the bitPackCodec is assumed. So specifying -the @c codecs as an empty VectorNode is equivalent to requesting at all fields -in the record be encoded with the bitPackCodec. - -Other than the @c prototype and @c codecs attributes, the only other state -directly accessible is the number of children (records) in the -CompressedVectorNode. The read/write access to the contents of the -CompressedVectorNode is coordinated by two other Foundation API objects: -CompressedVectorReader and CompressedVectorWriter. - -@section CompressedVectorNode_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin CompressedVectorNode::checkInvariant -@skip checkInvariant( -@until end CompressedVectorNode::checkInvariant - -@see CompressedVectorReader, CompressedVectorWriter, Node -*/ - -/*! -@brief Create an empty CompressedVectorNode, for writing, that will store -records specified by the prototype. -@param [in] destImageFile The ImageFile where the new node will eventually be -stored. -@param [in] prototype A tree that describes the fields in each record of -the CompressedVectorNode. -@param [in] codecs A VectorNode describing which codecs should be used -for each field described in the prototype. -@details -The @a destImageFile indicates which ImageFile the CompressedVectorNode will -eventually be attached to. A node is attached to an ImageFile by adding it -underneath the predefined root of the ImageFile (gotten from ImageFile::root). -It is not an error to fail to attach the CompressedVectorNode to the -@a destImageFile. It is an error to attempt to attach the CompressedVectorNode -to a different ImageFile. The CompressedVectorNode may not be written to until -it is attached to the destImageFile tree. - -The @a prototype may be any tree consisting of only the following node types: -IntegerNode, ScaledIntegerNode, FloatNode, StringNode, StructureNode, or -VectorNode (i.e. CompressedVectorNode and BlobNode are not allowed). See -CompressedVectorNode for discussion about the @a prototype argument. - -The @a codecs must be a heterogeneous VectorNode with children as specified in -the ASTM E57 data format standard. Since currently only one codec is supported -(bitPackCodec), and it is the default, passing an empty VectorNode will specify -that all record fields will be encoded with bitPackCodec. - -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@pre The @a destImageFile must have been opened in write mode (i.e. -destImageFile.isWritable() must be true). -@pre @a prototype must be an unattached root node (i.e. -!prototype.isAttached() && prototype.isRoot()) -@pre @a prototype cannot contain BlobNodes or CompressedVectorNodes. -@pre @a codecs must be an unattached root node (i.e. !codecs.isAttached() && -codecs.isRoot()) -@post prototype.isAttached() -@post codecs.isAttached() -@return A smart CompressedVectorNode handle referencing the underlying object. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_BAD_PROTOTYPE -@throw ::E57_ERROR_BAD_CODECS -@throw ::E57_ERROR_ALREADY_HAS_PARENT -@throw ::E57_ERROR_DIFFERENT_DEST_IMAGEFILE -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see SourceDestBuffer, Node, CompressedVectorNode::reader, CompressedVectorNode::writer -*/ -CompressedVectorNode::CompressedVectorNode( ImageFile destImageFile, const Node &prototype, const VectorNode &codecs ) : - impl_( new CompressedVectorNodeImpl( destImageFile.impl() ) ) -{ - /// Because of shared_ptr quirks, can't set prototype,codecs in - /// CompressedVectorNodeImpl(), so set it afterwards - impl_->setPrototype( prototype.impl() ); - impl_->setCodecs( codecs.impl() ); -} - -//! @brief Is this a root node. -//! @copydetails Node::isRoot() -bool CompressedVectorNode::isRoot() const -{ - return impl_->isRoot(); -} - -//! @brief Return parent of node, or self if a root node. -//! @copydetails Node::parent() -Node CompressedVectorNode::parent() const -{ - return Node( impl_->parent() ); -} - -//! @brief Get absolute pathname of node. -//! @copydetails Node::pathName() -ustring CompressedVectorNode::pathName() const -{ - return impl_->pathName(); -} - -//! @brief Get elementName string, that identifies the node in its parent.. -//! @copydetails Node::elementName() -ustring CompressedVectorNode::elementName() const -{ - return impl_->elementName(); -} - -//! @brief Get the ImageFile that was declared as the destination for the node -//! when it was created. -//! @copydetails Node::destImageFile() -ImageFile CompressedVectorNode::destImageFile() const -{ - return ImageFile( impl_->destImageFile() ); -} - -//! @brief Has node been attached into the tree of an ImageFile. -//! @copydetails Node::isAttached() -bool CompressedVectorNode::isAttached() const -{ - return impl_->isAttached(); -} - -/*! -@brief Get current number of records in a CompressedVectorNode. -@details -For a CompressedVectorNode with an active CompressedVectorWriter, the returned -number will reflect any writes completed. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return Current number of records in CompressedVectorNode. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorNode::reader, CompressedVectorNode::writer -*/ -int64_t CompressedVectorNode::childCount() const -{ - return impl_->childCount(); -} - -/*! -@brief Get the prototype tree that describes the types in the record. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return A smart Node handle referencing the root of the prototype tree. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorNode::CompressedVectorNode, SourceDestBuffer, -CompressedVectorNode::reader, CompressedVectorNode::writer -*/ -Node CompressedVectorNode::prototype() const -{ - return Node( impl_->getPrototype() ); -} - -/*! -@brief Get the codecs tree that describes the encoder/decoder configuration of -the CompressedVectorNode. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return A smart VectorNode handle referencing the root of the codecs tree. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorNode::CompressedVectorNode, SourceDestBuffer, -CompressedVectorNode::reader, CompressedVectorNode::writer -*/ -VectorNode CompressedVectorNode::codecs() const -{ - return VectorNode( impl_->getCodecs() ); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void CompressedVectorNode::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void CompressedVectorNode::dump( int indent, std::ostream &os ) const -{ -} -#endif - -/*! -@brief Upcast a CompressedVectorNode handle to a generic Node handle. -@details An upcast is always safe, and the compiler can automatically insert it -for initializations of Node variables and Node function arguments. -@return A smart Node handle referencing the underlying object. -@throw No E57Exceptions. -@see explanation in Node, Node::type(), CompressedVectorNode(const Node&) -*/ -CompressedVectorNode::operator Node() const -{ - /// Implicitly upcast from shared_ptr to - /// SharedNodeImplPtr and construct a Node object - return Node( impl_ ); -} - -/*! -@brief Downcast a generic Node handle to a CompressedVectorNode handle. -@param [in] n The generic handle to downcast. -@details The handle @a n must be for an underlying CompressedVectorNode, -otherwise an exception is thrown. In designs that need to avoid the exception, -use Node::type() to determine the actual type of the @a n before downcasting. -This function must be explicitly called (c++ compiler cannot insert it -automatically). -@return A smart CompressedVectorNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_NODE_DOWNCAST -@see Node::type(), CompressedVectorNode::operator, Node() -*/ -CompressedVectorNode::CompressedVectorNode( const Node &n ) -{ - if ( n.type() != E57_COMPRESSED_VECTOR ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_NODE_DOWNCAST, "nodeType=" + toString( n.type() ) ); - } - - /// Set our shared_ptr to the downcast shared_ptr - impl_ = std::static_pointer_cast( n.impl() ); -} - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -CompressedVectorNode::CompressedVectorNode( std::shared_ptr ni ) : impl_( ni ) -{ -} -//! @endcond - -/*! -@brief Create an iterator object for writing a series of blocks of data to a -CompressedVectorNode. -@param [in] sbufs Vector of memory buffers that will hold data to be -written to a CompressedVectorNode. -@details -See CompressedVectorWriter::write(std::vector&, unsigned) for -discussion about restrictions on @a sbufs. - -The pathNames in the @a sbufs must match one-to-one with the terminal nodes -(i.e. nodes that can have no children: IntegerNode, ScaledIntegerNode, -FloatNode, StringNode) in this CompressedVectorNode's prototype. It is an error -for two SourceDestBuffers in @a dbufs to identify the same terminal node in the -prototype. - - -It is an error to call this function if the CompressedVectorNode already has any -records (i.e. a CompressedVectorNode cannot be set twice). - -@pre @a sbufs can't be empty (i.e. sbufs.length() > 0). -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@pre The @a destImageFile must have been opened in write mode (i.e. -destImageFile.isWritable()). -@pre The destination ImageFile can't have any readers or writers open -(destImageFile().readerCount()==0 && destImageFile().writerCount()==0) -@pre This CompressedVectorNode must be attached (i.e. isAttached()). -@pre This CompressedVectorNode must have no records (i.e. childCount() == -0). -@return A smart CompressedVectorWriter handle referencing the underlying -iterator object. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_SET_TWICE -@throw ::E57_ERROR_TOO_MANY_WRITERS -@throw ::E57_ERROR_TOO_MANY_READERS -@throw ::E57_ERROR_NODE_UNATTACHED -@throw ::E57_ERROR_PATH_UNDEFINED -@throw ::E57_ERROR_BUFFER_SIZE_MISMATCH -@throw ::E57_ERROR_BUFFER_DUPLICATE_PATHNAME -@throw ::E57_ERROR_NO_BUFFER_FOR_ELEMENT -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorWriter, SourceDestBuffer, CompressedVectorNode::CompressedVectorNode, -CompressedVectorNode::prototype -*/ -CompressedVectorWriter CompressedVectorNode::writer( std::vector &sbufs ) -{ - return CompressedVectorWriter( impl_->writer( sbufs ) ); -} - -/*! -@brief Create an iterator object for reading a series of blocks of data from a -CompressedVectorNode. -@param [in] dbufs Vector of memory buffers that will receive data read -from a CompressedVectorNode. -@details -The pathNames in the @a dbufs must identify terminal nodes (i.e. node that can -have no children: IntegerNode, ScaledIntegerNode, FloatNode, StringNode) in this -CompressedVectorNode's prototype. It is an error for two SourceDestBuffers in @a -dbufs to identify the same terminal node in the prototype. It is not an error to -create a CompressedVectorReader for an empty CompressedVectorNode. - -@pre @a dbufs can't be empty -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@pre The destination ImageFile can't have any writers open -(destImageFile().writerCount()==0) -@pre This CompressedVectorNode must be attached (i.e. isAttached()). -@return A smart CompressedVectorReader handle referencing the underlying -iterator object. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_TOO_MANY_WRITERS -@throw ::E57_ERROR_NODE_UNATTACHED -@throw ::E57_ERROR_PATH_UNDEFINED -@throw ::E57_ERROR_BUFFER_SIZE_MISMATCH -@throw ::E57_ERROR_BUFFER_DUPLICATE_PATHNAME -@throw ::E57_ERROR_BAD_CV_HEADER -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorReader, SourceDestBuffer, CompressedVectorNode::CompressedVectorNode, -CompressedVectorNode::prototype -*/ -CompressedVectorReader CompressedVectorNode::reader( const std::vector &dbufs ) -{ - return CompressedVectorReader( impl_->reader( dbufs ) ); -} - -//===================================================================================== -/*! -@class IntegerNode -@brief An E57 element encoding an integer value. -@details -An IntegerNode is a terminal node (i.e. having no children) that holds an -integer value, and minimum/maximum bounds. Once the IntegerNode value and -attributes are set at creation, they may not be modified. - -The minimum attribute may be a number in the interval [-2^63, 2^63). -The maximum attribute may be a number in the interval [minimum, 2^63). -The value may be a number in the interval [minimum, maximum]. - -See Node class discussion for discussion of the common functions that -StructureNode supports. - -@section IntegerNode_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin IntegerNode::checkInvariant -@skip checkInvariant( -@until end IntegerNode::checkInvariant - -@see Node, CompressedVector -*/ - -/*! -@brief Create an E57 element for storing a integer value. -@param [in] destImageFile The ImageFile where the new node will eventually -be stored. -@param [in] value The integer value of the element. -@param [in] minimum The smallest value that the element may take. -@param [in] maximum The largest value that the element may take. -@details -An IntegerNode stores an integer value, and a lower and upper bound. -The IntegerNode class corresponds to the ASTM E57 standard Integer element. -See the class discussion at bottom of IntegerNode page for more details. - -The @a destImageFile indicates which ImageFile the IntegerNode will eventually -be attached to. A node is attached to an ImageFile by adding it underneath the -predefined root of the ImageFile (gotten from ImageFile::root). It is not an -error to fail to attach the IntegerNode to the @a destImageFile. It is an error -to attempt to attach the IntegerNode to a different ImageFile. - -@b Warning: it is an error to give an @a value outside the @a minimum / @a -maximum bounds, even if the IntegerNode is destined to be used in a -CompressedVectorNode prototype (where the @a value will be ignored). If the -IntegerNode is to be used in a prototype, it is recommended to specify a @a -value = 0 if 0 is within bounds, or a @a value = @a minimum if 0 is not within -bounds. -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@pre The @a destImageFile must have been opened in write mode (i.e. -destImageFile.isWritable() must be true). -@pre minimum <= value <= maximum -@return A smart IntegerNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_VALUE_OUT_OF_BOUNDS -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see IntegerNode::value, Node, CompressedVectorNode, CompressedVectorNode::prototype -*/ -IntegerNode::IntegerNode( ImageFile destImageFile, int64_t value, int64_t minimum, int64_t maximum ) : - impl_( new IntegerNodeImpl( destImageFile.impl(), value, minimum, maximum ) ) -{ -} - -//! @brief Is this a root node. -//! @copydetails Node::isRoot() -bool IntegerNode::isRoot() const -{ - return impl_->isRoot(); -} - -//! @brief Return parent of node, or self if a root node. -//! @copydetails Node::parent() -Node IntegerNode::parent() const -{ - return Node( impl_->parent() ); -} - -//! @brief Get absolute pathname of node. -//! @copydetails Node::pathName() -ustring IntegerNode::pathName() const -{ - return impl_->pathName(); -} - -//! @brief Get elementName string, that identifies the node in its parent.. -//! @copydetails Node::elementName() -ustring IntegerNode::elementName() const -{ - return impl_->elementName(); -} - -//! @brief Get the ImageFile that was declared as the destination for the node -//! when it was created. -//! @copydetails Node::destImageFile() -ImageFile IntegerNode::destImageFile() const -{ - return ImageFile( impl_->destImageFile() ); -} - -//! @brief Has node been attached into the tree of an ImageFile. -//! @copydetails Node::isAttached() -bool IntegerNode::isAttached() const -{ - return impl_->isAttached(); -} - -/*! -@brief Get integer value stored. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return integer value stored. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see IntegerNode::minimum, IntegerNode::maximum -*/ -int64_t IntegerNode::value() const -{ - return impl_->value(); -} - -/*! -@brief Get the declared minimum that the value may take. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The declared minimum that the value may take. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see IntegerCreate.cpp example, IntegerNode::value -*/ -int64_t IntegerNode::minimum() const -{ - return impl_->minimum(); -} - -/*! -@brief Get the declared maximum that the value may take. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The declared maximum that the value may take. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see IntegerNode::value -*/ -int64_t IntegerNode::maximum() const -{ - return impl_->maximum(); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void IntegerNode::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void IntegerNode::dump( int indent, std::ostream &os ) const -{ -} -#endif - -/*! -@brief Upcast a IntegerNode handle to a generic Node handle. -@details An upcast is always safe, and the compiler can automatically insert it -for initializations of Node variables and Node function arguments. -@return A smart Node handle referencing the underlying object. -@throw No E57Exceptions. -@see explanation in Node, Node::type(), IntegerNode(const Node&) -*/ -IntegerNode::operator Node() const -{ - /// Upcast from shared_ptr to SharedNodeImplPtr and - /// construct a Node object - return Node( impl_ ); -} - -/*! -@brief Downcast a generic Node handle to a IntegerNode handle. -@param [in] n The generic handle to downcast. -@details The handle @a n must be for an underlying IntegerNode, otherwise an -exception is thrown. In designs that need to avoid the exception, use -Node::type() to determine the actual type of the @a n before downcasting. This -function must be explicitly called (c++ compiler cannot insert it -automatically). -@return A smart IntegerNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_NODE_DOWNCAST -@see Node::type(), IntegerNode::operator Node() -*/ -IntegerNode::IntegerNode( const Node &n ) -{ - if ( n.type() != E57_INTEGER ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_NODE_DOWNCAST, "nodeType=" + toString( n.type() ) ); - } - - /// Set our shared_ptr to the downcast shared_ptr - impl_ = std::static_pointer_cast( n.impl() ); -} - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -IntegerNode::IntegerNode( std::shared_ptr ni ) : impl_( ni ) -{ -} -//! @endcond - -//===================================================================================== -/*! -@class ScaledIntegerNode -@brief An E57 element encoding a fixed point number. -@details -An ScaledIntegerNode is a terminal node (i.e. having no children) that holds a -fixed point number encoded by an integer @c rawValue, a double precision -floating point @c scale, an double precision floating point @c offset, and -integer minimum/maximum bounds. - -The @c minimum attribute may be a number in the interval [-2^63, 2^63). -The @c maximum attribute may be a number in the interval [minimum, 2^63). -The @c rawValue may be a number in the interval [minimum, maximum]. -The @c scaledValue is a calculated double precision floating point number -derived from: scaledValue = rawValue*scale + offset. - -See Node class discussion for discussion of the common functions that -StructureNode supports. - -@section ScaledIntegerNode_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin ScaledIntegerNode::checkInvariant -@skip checkInvariant( -@until end ScaledIntegerNode::checkInvariant - -@see Node -*/ - -/*! -@brief Create an E57 element for storing a fixed point number. -@param [in] destImageFile The ImageFile where the new node will eventually -be stored. -@param [in] rawValue The raw integer value of the element. -@param [in] minimum The smallest rawValue that the element may take. -@param [in] maximum The largest rawWalue that the element may take. -@param [in] scale The scaling factor used to compute scaledValue from -rawValue. -@param [in] offset The offset factor used to compute scaledValue from -rawValue. -@details -An ScaledIntegerNode stores an integer value, a lower and upper bound, and two -conversion factors. The ScaledIntegerNode class corresponds to the ASTM E57 -standard ScaledInteger element. See the class discussion at bottom of -ScaledIntegerNode page for more details. - -The @a destImageFile indicates which ImageFile the ScaledIntegerNode will -eventually be attached to. A node is attached to an ImageFile by adding it -underneath the predefined root of the ImageFile (gotten from ImageFile::root). -It is not an error to fail to attach the ScaledIntegerNode to the @a -destImageFile. It is an error to attempt to attach the ScaledIntegerNode to a -different ImageFile. - -@b Warning: it is an error to give an @a rawValue outside the @a minimum / @a -maximum bounds, even if the ScaledIntegerNode is destined to be used in a -CompressedVectorNode prototype (where the @a rawValue will be ignored). If the -ScaledIntegerNode is to be used in a prototype, it is recommended to specify a -@a rawValue = 0 if 0 is within bounds, or a @a rawValue = @a minimum if 0 is not -within bounds. -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@pre The @a destImageFile must have been opened in write mode (i.e. -destImageFile.isWritable() must be true). -@pre minimum <= rawValue <= maximum -@pre scale != 0 -@return A smart ScaledIntegerNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_VALUE_OUT_OF_BOUNDS -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode::rawValue, Node, CompressedVectorNode, CompressedVectorNode::prototype -*/ -ScaledIntegerNode::ScaledIntegerNode( ImageFile destImageFile, int64_t rawValue, int64_t minimum, int64_t maximum, - double scale, double offset ) : - impl_( new ScaledIntegerNodeImpl( destImageFile.impl(), rawValue, minimum, maximum, scale, offset ) ) -{ -} -ScaledIntegerNode::ScaledIntegerNode( ImageFile destImageFile, int rawValue, int64_t minimum, int64_t maximum, - double scale, double offset ) : - impl_( new ScaledIntegerNodeImpl( destImageFile.impl(), static_cast( rawValue ), minimum, maximum, scale, - offset ) ) -{ -} -ScaledIntegerNode::ScaledIntegerNode( ImageFile destImageFile, int rawValue, int minimum, int maximum, double scale, - double offset ) : - impl_( new ScaledIntegerNodeImpl( destImageFile.impl(), static_cast( rawValue ), - static_cast( minimum ), static_cast( maximum ), scale, offset ) ) -{ -} -/*! -@brief This second constructor create an E57 element for storing a fixed point -number but does the scaling for you. -@param [in] destImageFile The ImageFile where the new node will eventually -be stored. -@param [in] scaledValue The scaled integer value of the element. -@param [in] scaledMinimum The smallest scaledValue that the element may -take. -@param [in] scaledMaximum The largest scaledValue that the element may take. -@param [in] scale The scaling factor used to compute scaledValue from -rawValue. -@param [in] offset The offset factor used to compute scaledValue from -rawValue. -@details -An ScaledIntegerNode stores an integer value, a lower and upper bound, and two -conversion factors. This ScaledIntegerNode constructor calculates the rawValue, -minimum, and maximum by doing the floor((scaledValue - offset)/scale + .5) on -each scaled parameters. -@b Warning: it is an error to give an @a rawValue outside the @a minimum / @a -maximum bounds, even if the ScaledIntegerNode is destined to be used in a -CompressedVectorNode prototype (where the @a rawValue will be ignored). If the -ScaledIntegerNode is to be used in a prototype, it is recommended to specify a -@a rawValue = 0 if 0 is within bounds, or a @a rawValue = @a minimum if 0 is not -within bounds. -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@pre The @a destImageFile must have been opened in write mode (i.e. -destImageFile.isWritable() must be true). -@pre scaledMinimum <= scaledValue <= scaledMaximum -@pre scale != 0 -@return A smart ScaledIntegerNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_VALUE_OUT_OF_BOUNDS -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode::scaledValue, Node, CompressedVectorNode, CompressedVectorNode::prototype -*/ -ScaledIntegerNode::ScaledIntegerNode( ImageFile destImageFile, double scaledValue, double scaledMinimum, - double scaledMaximum, double scale, double offset ) : - impl_( new ScaledIntegerNodeImpl( destImageFile.impl(), scaledValue, scaledMinimum, scaledMaximum, scale, offset ) ) -{ -} -//! @brief Is this a root node. -//! @copydetails Node::isRoot() -bool ScaledIntegerNode::isRoot() const -{ - return impl_->isRoot(); -} - -//! @brief Return parent of node, or self if a root node. -//! @copydetails Node::parent() -Node ScaledIntegerNode::parent() const -{ - return Node( impl_->parent() ); -} - -//! @brief Get absolute pathname of node. -//! @copydetails Node::pathName() -ustring ScaledIntegerNode::pathName() const -{ - return impl_->pathName(); -} - -//! @brief Get elementName string, that identifies the node in its parent.. -//! @copydetails Node::elementName() -ustring ScaledIntegerNode::elementName() const -{ - return impl_->elementName(); -} - -//! @brief Get the ImageFile that was declared as the destination for the node -//! when it was created. -//! @copydetails Node::destImageFile() -ImageFile ScaledIntegerNode::destImageFile() const -{ - return ImageFile( impl_->destImageFile() ); -} - -//! @brief Has node been attached into the tree of an ImageFile. -//! @copydetails Node::isAttached() -bool ScaledIntegerNode::isAttached() const -{ - return impl_->isAttached(); -} - -/*! -@brief Get raw unscaled integer value of element. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The raw unscaled integer value stored. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode::scaledValue, ScaledIntegerNode::minimum, ScaledIntegerNode::maximum -*/ -int64_t ScaledIntegerNode::rawValue() const -{ - return impl_->rawValue(); -} - -/*! -@brief Get scaled value of element. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The scaled value (rawValue*scale + offset) calculated from the rawValue -stored. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode::rawValue -*/ -double ScaledIntegerNode::scaledValue() const -{ - return impl_->scaledValue(); -} - -/*! -@brief Get the declared minimum that the raw value may take. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The declared minimum that the rawValue may take. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode::maximum, ScaledIntegerNode::rawValue -*/ -int64_t ScaledIntegerNode::minimum() const -{ - return impl_->minimum(); -} -/*! -@brief Get the declared scaled minimum that the scaled value may take. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The declared minimum that the rawValue may take. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode::scaledMaximum, ScaledIntegerNode::scaledValue -*/ -double ScaledIntegerNode::scaledMinimum() const -{ - return impl_->scaledMinimum(); -} -/*! -@brief Get the declared maximum that the raw value may take. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The declared maximum that the rawValue may take. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode::minimum, ScaledIntegerNode::rawValue -*/ -int64_t ScaledIntegerNode::maximum() const -{ - return impl_->maximum(); -} -/*! -@brief Get the declared scaled maximum that the scaled value may take. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The declared maximum that the rawValue may take. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode::scaledMinimum, ScaledIntegerNode::scaledValue -*/ -double ScaledIntegerNode::scaledMaximum() const // Added by SC -{ - return impl_->scaledMaximum(); -} -/*! -@brief Get declared scaling factor. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The scaling factor used to compute scaledValue from rawValue. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode::scaledValue -*/ -double ScaledIntegerNode::scale() const -{ - return impl_->scale(); -} - -/*! -@brief Get declared offset. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The offset used to compute scaledValue from rawValue. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ScaledIntegerNode::scaledValue -*/ -double ScaledIntegerNode::offset() const -{ - return impl_->offset(); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void ScaledIntegerNode::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void ScaledIntegerNode::dump( int indent, std::ostream &os ) const -{ -} -#endif - -/*! -@brief Upcast a ScaledIntegerNode handle to a generic Node handle. -@details An upcast is always safe, and the compiler can automatically insert it -for initializations of Node variables and Node function arguments. -@return A smart Node handle referencing the underlying object. -@throw No E57Exceptions. -@see Explanation in Node, Node::type(), ScaledIntegerNode(const Node&) -*/ -ScaledIntegerNode::operator Node() const -{ - /// Upcast from shared_ptr to SharedNodeImplPtr and - /// construct a Node object - return Node( impl_ ); -} - -/*! -@brief Downcast a generic Node handle to an ScaledIntegerNode handle. -@param [in] n The generic handle to downcast. -@details The handle @a n must be for an underlying ScaledIntegerNode, otherwise -an exception is thrown. In designs that need to avoid the exception, use -Node::type() to determine the actual type of the @a n before downcasting. This -function must be explicitly called (c++ compiler cannot insert it -automatically). -@return A smart ScaledIntegerNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_NODE_DOWNCAST -@see Node::type(), ScaledIntegerNode::operator, Node() -*/ -ScaledIntegerNode::ScaledIntegerNode( const Node &n ) -{ - if ( n.type() != E57_SCALED_INTEGER ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_NODE_DOWNCAST, "nodeType=" + toString( n.type() ) ); - } - - /// Set our shared_ptr to the downcast shared_ptr - impl_ = std::static_pointer_cast( n.impl() ); -} - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -ScaledIntegerNode::ScaledIntegerNode( std::shared_ptr ni ) : impl_( ni ) -{ -} -//! @endcond - -//===================================================================================== -/*! -@class FloatNode -@brief An E57 element encoding a single or double precision IEEE floating -point number. -@details -An FloatNode is a terminal node (i.e. having no children) that holds an IEEE -floating point value, and minimum/maximum bounds. The precision of the floating -point value and attributes may be either single or double precision. Once the -FloatNode value and attributes are set at creation, they may not be modified. - -If the precision option of the FloatNode is E57_SINGLE: -The minimum attribute may be a number in the interval -[-3.402823466e+38, 3.402823466e+38]. The maximum attribute may be a number in -the interval [maximum, 3.402823466e+38]. The value may be a number in the -interval [minimum, maximum]. - -If the precision option of the FloatNode is E57_DOUBLE: -The minimum attribute may be a number in the interval -[-1.7976931348623158e+308, 1.7976931348623158e+308]. The maximum attribute may -be a number in the interval [maximum, 1.7976931348623158e+308]. The value may be -a number in the interval [minimum, maximum]. - -See Node class discussion for discussion of the common functions that -StructureNode supports. - -@section FloatNode_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin FloatNode::checkInvariant -@skip checkInvariant( -@until end FloatNode::checkInvariant - -@see Node -*/ - -/*! -@brief Create an E57 element for storing an double precision IEEE floating -point number. -@param [in] destImageFile The ImageFile where the new node will eventually -be stored. -@param [in] value The double precision IEEE floating point value of the -element. -@param [in] precision The precision of IEEE floating point to use. May be -E57_SINGLE or E57_DOUBLE. -@param [in] minimum The smallest value that the value may take. -@param [in] maximum The largest value that the value may take. -@details -An FloatNode stores an IEEE floating point number and a lower and upper bound. -The FloatNode class corresponds to the ASTM E57 standard Float element. -See the class discussion at bottom of FloatNode page for more details. - -The @a destImageFile indicates which ImageFile the FloatNode will eventually be -attached to. A node is attached to an ImageFile by adding it underneath the -predefined root of the ImageFile (gotten from ImageFile::root). It is not an -error to fail to attach the FloatNode to the @a destImageFile. It is an error to -attempt to attach the FloatNode to a different ImageFile. - -There is only one FloatNode constructor that handles both E57_SINGLE and -E57_DOUBLE precision cases. If @a precision = E57_SINGLE, then the object will -silently round the double precision @a value to the nearest representable single -precision value. In this case, the lower bits will be lost, and if the value is -outside the representable range of a single precision number, the exponent may -be changed. The same is true for the @a minimum and @a maximum arguments. - -@b Warning: it is an error to give an @a value outside the @a minimum / @a -maximum bounds, even if the FloatNode is destined to be used in a -CompressedVectorNode prototype (where the @a value will be ignored). If the -FloatNode is to be used in a prototype, it is recommended to specify a @a value -= 0 if 0 is within bounds, or a @a value = @a minimum if 0 is not within bounds. -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@pre The @a destImageFile must have been opened in write mode (i.e. -destImageFile.isWritable() must be true). -@pre minimum <= value <= maximum -@return A smart FloatNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_VALUE_OUT_OF_BOUNDS -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see FloatPrecision, FloatNode::value, Node, CompressedVectorNode, CompressedVectorNode::prototype -*/ -FloatNode::FloatNode( ImageFile destImageFile, double value, FloatPrecision precision, double minimum, - double maximum ) : - impl_( new FloatNodeImpl( destImageFile.impl(), value, precision, minimum, maximum ) ) -{ -} - -//! @brief Is this a root node. -//! @copydetails Node::isRoot() -bool FloatNode::isRoot() const -{ - return impl_->isRoot(); -} - -//! @brief Return parent of node, or self if a root node. -//! @copydetails Node::parent() -Node FloatNode::parent() const -{ - return Node( impl_->parent() ); -} - -//! @brief Get absolute pathname of node. -//! @copydetails Node::pathName() -ustring FloatNode::pathName() const -{ - return impl_->pathName(); -} - -//! @brief Get elementName string, that identifies the node in its parent.. -//! @copydetails Node::elementName() -ustring FloatNode::elementName() const -{ - return impl_->elementName(); -} - -//! @brief Get the ImageFile that was declared as the destination for the node -//! when it was created. -//! @copydetails Node::destImageFile() -ImageFile FloatNode::destImageFile() const -{ - return ImageFile( impl_->destImageFile() ); -} - -//! @brief Has node been attached into the tree of an ImageFile. -//! @copydetails Node::isAttached() -bool FloatNode::isAttached() const -{ - return impl_->isAttached(); -} - -/*! -@brief Get IEEE floating point value stored. -@details -If precision is E57_SINGLE, the single precision value is returned as a double. -If precision is E57_DOUBLE, the double precision value is returned as a double. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The IEEE floating point value stored, represented as a double. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see FloatNode::minimum, FloatNode::maximum -*/ -double FloatNode::value() const -{ - return impl_->value(); -} - -/*! -@brief Get declared precision of the floating point number. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The declared precision of the floating point number, either -::E57_SINGLE or ::E57_DOUBLE. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see FloatPrecision -*/ -FloatPrecision FloatNode::precision() const -{ - return impl_->precision(); -} - -/*! -@brief Get the declared minimum that the value may take. -@details -If precision is E57_SINGLE, the single precision minimum is returned as a -double. If precision is E57_DOUBLE, the double precision minimum is returned as -a double. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The declared minimum that the value may take. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see FloatNode::maximum, FloatNode::value -*/ -double FloatNode::minimum() const -{ - return impl_->minimum(); -} - -/*! -@brief Get the declared maximum that the value may take. -@details -If precision is E57_SINGLE, the single precision maximum is returned as a -double. If precision is E57_DOUBLE, the double precision maximum is returned as -a double. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The declared maximum that the value may take. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see FloatNode::minimum, FloatNode::value -*/ -double FloatNode::maximum() const -{ - return impl_->maximum(); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void FloatNode::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void FloatNode::dump( int indent, std::ostream &os ) const -{ -} -#endif - -/*! -@brief Upcast a FloatNode handle to a generic Node handle. -@details An upcast is always safe, and the compiler can automatically insert it -for initializations of Node variables and Node function arguments. -@return A smart Node handle referencing the underlying object. -@throw No E57Exceptions. -@see Explanation in Node, Node::type() -*/ -FloatNode::operator Node() const -{ - /// Upcast from shared_ptr to SharedNodeImplPtr and construct - /// a Node object - return Node( impl_ ); -} - -/*! -@brief Downcast a generic Node handle to a FloatNode handle. -@param [in] n The generic handle to downcast. -@details The handle @a n must be for an underlying FloatNode, otherwise an -exception is thrown. In designs that need to avoid the exception, use -Node::type() to determine the actual type of the @a n before downcasting. This -function must be explicitly called (c++ compiler cannot insert it -automatically). -@return A smart FloatNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_NODE_DOWNCAST -@see Node::type(), FloatNode::operator Node() -*/ -FloatNode::FloatNode( const Node &n ) -{ - if ( n.type() != E57_FLOAT ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_NODE_DOWNCAST, "nodeType=" + toString( n.type() ) ); - } - - /// Set our shared_ptr to the downcast shared_ptr - impl_ = std::static_pointer_cast( n.impl() ); -} - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -FloatNode::FloatNode( std::shared_ptr ni ) : impl_( ni ) -{ -} -//! @endcond - -//===================================================================================== -/*! -@class StringNode -@brief An E57 element encoding a Unicode character string value. -@details -A StringNode is a terminal node (i.e. having no children) that holds an Unicode -character string encoded in UTF-8. Once the StringNode value is set at creation, -it may not be modified. - -See Node class discussion for discussion of the common functions that -StructureNode supports. - -@section StringNode_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin StringNode::checkInvariant -@skip checkInvariant( -@until end StringNode::checkInvariant - -@see Node -*/ - -/*! -@brief Create an element storing a Unicode character string. -@param [in] destImageFile The ImageFile where the new node will eventually be -stored. -@param [in] value The Unicode character string value of the element, -in UTF-8 encoding. -@details -The StringNode class corresponds to the ASTM E57 standard String element. -See the class discussion at bottom of StringNode page for more details. - -The @a destImageFile indicates which ImageFile the StringNode will eventually be -attached to. A node is attached to an ImageFile by adding it underneath the -predefined root of the ImageFile (gotten from ImageFile::root). It is not an -error to fail to attach the StringNode to the @a destImageFile. It is an error -to attempt to attach the StringNode to a different ImageFile. - -If the StringNode is to be used in a CompressedVectorNode prototype, it is -recommended to specify a -@a value = "" (the default value). -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@pre The @a destImageFile must have been opened in write mode (i.e. -destImageFile.isWritable() must be true). -@return A smart StringNode handle referencing the underlying object. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see StringNode::value, Node, CompressedVectorNode, CompressedVectorNode::prototype -*/ -StringNode::StringNode( ImageFile destImageFile, const ustring &value ) : - impl_( new StringNodeImpl( destImageFile.impl(), value ) ) -{ -} - -//! @brief Is this a root node. -//! @copydetails Node::isRoot() -bool StringNode::isRoot() const -{ - return impl_->isRoot(); -} - -//! @brief Return parent of node, or self if a root node. -//! @copydetails Node::parent() -Node StringNode::parent() const -{ - return Node( impl_->parent() ); -} - -//! @brief Get absolute pathname of node. -//! @copydetails Node::pathName() -ustring StringNode::pathName() const -{ - return impl_->pathName(); -} - -//! @brief Get elementName string, that identifies the node in its parent.. -//! @copydetails Node::elementName() -ustring StringNode::elementName() const -{ - return impl_->elementName(); -} - -//! @brief Get the ImageFile that was declared as the destination for the node -//! when it was created. -//! @copydetails Node::destImageFile() -ImageFile StringNode::destImageFile() const -{ - return ImageFile( impl_->destImageFile() ); -} - -//! @brief Has node been attached into the tree of an ImageFile. -//! @copydetails Node::isAttached() -bool StringNode::isAttached() const -{ - return impl_->isAttached(); -} - -/*! -@brief Get Unicode character string value stored. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The Unicode character string value stored. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -*/ -ustring StringNode::value() const -{ - return impl_->value(); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void StringNode::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void StringNode::dump( int indent, std::ostream &os ) const -{ -} -#endif - -/*! -@brief Upcast a StringNode handle to a generic Node handle. -@details An upcast is always safe, and the compiler can automatically insert it -for initializations of Node variables and Node function arguments. -@return A smart Node handle referencing the underlying object. -@throw No E57Exceptions. -@see Explanation in Node, Node::type(), StringNode(const Node&) -*/ -StringNode::operator Node() const -{ - /// Upcast from shared_ptr to SharedNodeImplPtr and construct - /// a Node object - return Node( impl_ ); -} - -/*! -@brief Downcast a generic Node handle to a StringNode handle. -@param [in] n The generic handle to downcast. -@details The handle @a n must be for an underlying StringNode, otherwise an -exception is thrown. In designs that need to avoid the exception, use -Node::type() to determine the actual type of the @a n before downcasting. This -function must be explicitly called (c++ compiler cannot insert it -automatically). -@return A smart StringNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_NODE_DOWNCAST -@see Node::type(), StringNode::operator Node() -*/ -StringNode::StringNode( const Node &n ) -{ - if ( n.type() != E57_STRING ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_NODE_DOWNCAST, "nodeType=" + toString( n.type() ) ); - } - - /// Set our shared_ptr to the downcast shared_ptr - impl_ = std::static_pointer_cast( n.impl() ); -} - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -StringNode::StringNode( std::shared_ptr ni ) : impl_( ni ) -{ -} -//! @endcond - -//===================================================================================== -/*! -@class BlobNode -@brief An E57 element encoding an fixed-length sequence of bytes with an -opaque format. -@details -A BlobNode is a terminal node (i.e. having no children) that holds an opaque, -fixed-length sequence of bytes. The number of bytes in the BlobNode is declared -at creation time. The content of the blob is stored within the E57 file in an -efficient binary format (but not compressed). The BlobNode cannot grow after it -is created. There is no ordering constraints on how content of a BlobNode may be -accessed (i.e. it is random access). BlobNodes in an ImageFile opened for -reading are read-only. - -There are two categories of BlobNodes, distinguished by their usage: private -BlobNodes and public BlobNodes. In a private BlobNode, the format of its content -bytes is not published. This is useful for storing proprietary data that a -writer does not wish to share with all readers. Rather than put this information -in a separate file, the writer can embed the file inside the E57 file so it -cannot be lost. - -In a public BlobNode, the format is published or follows some industry standard -format (e.g. JPEG). Rather than reinvent the wheel in applications that are -already well-served by an existing format standard, an E57 file writer can just -embed an existing file as an "attachment" in a BlobNode. The internal format of -a public BlobNode is not enforced by the Foundation API. It is recommended that -there be some mechanism for a reader to know ahead of time which format the -BlobNode content adheres to (either specified by a document, or encoded by some -scheme in the E57 Element tree). - -The BlobNode is the one node type where the set-once policy is not strictly -enforced. It is possible to write the same byte location in a BlobNode several -times. However it is not recommended. - -See Node class discussion for discussion of the common functions that -StructureNode supports. - -@section BlobNode_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or, can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin BlobNode::checkInvariant -@skip checkInvariant( -@until end BlobNode::checkInvariant - -@see Node -*/ - -/*! -@brief Create an element for storing a sequence of bytes with an opaque -format. -@param [in] destImageFile The ImageFile where the new node will eventually be -stored. -@param [in] byteCount The number of bytes reserved in the ImageFile for -holding the blob. -@details -The BlobNode class corresponds to the ASTM E57 standard Blob element. -See the class discussion at bottom of BlobNode page for more details. - -The E57 Foundation Implementation may pre-allocate disk space in the ImageFile -to store the declared length of the blob. The disk must have enough free space -to store @a byteCount bytes of data. The data of a newly created BlobNode is -initialized to zero. - -The @a destImageFile indicates which ImageFile the BlobNode will eventually be -attached to. A node is attached to an ImageFile by adding it underneath the -predefined root of the ImageFile (gotten from ImageFile::root). It is not an -error to fail to attach the BlobNode to the @a destImageFile. It is an error to -attempt to attach the BlobNode to a different ImageFile. -@pre The @a destImageFile must be open (i.e. destImageFile.isOpen() must be -true). -@pre The @a destImageFile must have been opened in write mode (i.e. -destImageFile.isWritable() must be true). -@pre byteCount >= 0 -@return A smart BlobNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see Node, BlobNode::read, BlobNode::write -*/ -BlobNode::BlobNode( ImageFile destImageFile, int64_t byteCount ) : - impl_( new BlobNodeImpl( destImageFile.impl(), byteCount ) ) -{ -} - -//! @brief Is this a root node. -//! @copydetails Node::isRoot() -bool BlobNode::isRoot() const -{ - return impl_->isRoot(); -} - -//! @brief Return parent of node, or self if a root node. -//! @copydetails Node::parent() -Node BlobNode::parent() const -{ - return Node( impl_->parent() ); -} - -//! @brief Get absolute pathname of node. -//! @copydetails Node::pathName() -ustring BlobNode::pathName() const -{ - return impl_->pathName(); -} - -//! @brief Get elementName string, that identifies the node in its parent.. -//! @copydetails Node::elementName() -ustring BlobNode::elementName() const -{ - return impl_->elementName(); -} - -//! @brief Get the ImageFile that was declared as the destination for the node -//! when it was created. -//! @copydetails Node::destImageFile() -ImageFile BlobNode::destImageFile() const -{ - return ImageFile( impl_->destImageFile() ); -} - -//! @brief Has node been attached into the tree of an ImageFile. -//! @copydetails Node::isAttached() -bool BlobNode::isAttached() const -{ - return impl_->isAttached(); -} - -/*! -@brief Get size of blob declared when it was created. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@post No visible state is modified. -@return The declared size of the blob when it was created. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see BlobNode::read, BlobNode::write -*/ -int64_t BlobNode::byteCount() const -{ - return impl_->byteCount(); -} - -/*! -@brief Read a buffer of bytes from a blob. -@param [in] buf A memory buffer to store bytes read from the blob. -@param [in] start The index of the first byte in blob to read. -@param [in] count The number of bytes to read. -@details -The memory buffer @a buf must be able to store at least @a count bytes. -The data is stored in a binary section of the ImageFile with checksum -protection, so undetected corruption is very unlikely. It is an error to attempt -to read outside the declared size of the Blob. The format of the data read is -opaque (unspecified by the ASTM E57 data format standard). Since @a buf is a -byte buffer, byte ordering is irrelevant (it will come out in the same order -that it went in). There is no constraint on the ordering of reads. Any part of -the Blob data can be read zero or more times. -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@pre buf != NULL -@pre 0 <= @a start < byteCount() -@pre 0 <= count -@pre (@a start + @a count) < byteCount() -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_LSEEK_FAILED -@throw ::E57_ERROR_READ_FAILED -@throw ::E57_ERROR_BAD_CHECKSUM -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see BlobNode::byteCount, BlobNode::write -*/ -void BlobNode::read( uint8_t *buf, int64_t start, size_t count ) -{ - impl_->read( buf, start, count ); -} - -/*! -@brief Write a buffer of bytes to a blob. -@param [in] buf A memory buffer of bytes to write to the blob. -@param [in] start The index of the first byte in blob to write to. -@param [in] count The number of bytes to write. -@details -The memory buffer @a buf must store at least @a count bytes. -The data is stored in a binary section of the ImageFile with checksum -protection, so undetected corruption is very unlikely. It is an error to attempt -to write outside the declared size of the Blob. The format of the data written -is opaque (unspecified by the ASTM E57 data format standard). Since @a buf is a -byte buffer, byte ordering is irrelevant (it will come out in the same order -that it went in). There is no constraint on the ordering of writes. It is not an -error to write a portion of the BlobNode data more than once, or not at all. -Initially all the BlobNode data is zero, so if a portion is not written, it will -remain zero. The BlobNode is one of the two node types that must be attached to -the root of a write mode ImageFile before write operations can be performed (the -other type is CompressedVectorNode). -@pre The destination ImageFile must be open (i.e. destImageFile().isOpen()). -@pre The associated destImageFile must have been opened in write mode (i.e. -destImageFile().isWritable()). -@pre The BlobNode must be attached to an ImageFile (i.e. isAttached()). -@pre buf != NULL -@pre 0 <= @a start < byteCount() -@pre 0 <= count -@pre (@a start + @a count) < byteCount() -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_NODE_UNATTACHED -@throw ::E57_ERROR_LSEEK_FAILED -@throw ::E57_ERROR_READ_FAILED -@throw ::E57_ERROR_WRITE_FAILED -@throw ::E57_ERROR_BAD_CHECKSUM -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see BlobNode::byteCount, BlobNode::read -*/ -void BlobNode::write( uint8_t *buf, int64_t start, size_t count ) -{ - impl_->write( buf, start, count ); -} - -//! @brief Diagnostic function to print internal state of object to output -//! stream in an indented format. -//! @copydetails Node::dump() -#ifdef E57_DEBUG -void BlobNode::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void BlobNode::dump( int indent, std::ostream &os ) const -{ -} -#endif - -/*! -@brief Upcast a BlobNode handle to a generic Node handle. -@details An upcast is always safe, and the compiler can automatically insert it -for initializations of Node variables and Node function arguments. -@return A smart Node handle referencing the underlying object. -@throw No E57Exceptions. -@see Explanation in Node, Node::type(), BlobNode(const Node&) -*/ -BlobNode::operator Node() const -{ - /// Upcast from shared_ptr to SharedNodeImplPtr and construct - /// a Node object - return Node( impl_ ); -} - -/*! -@brief Downcast a generic Node handle to a BlobNode handle. -@param [in] n The generic handle to downcast. -@details The handle @a n must be for an underlying BlobNode, otherwise an -exception is thrown. In designs that need to avoid the exception, use -Node::type() to determine the actual type of the @a n before downcasting. This -function must be explicitly called (c++ compiler cannot insert it -automatically). -@return A smart BlobNode handle referencing the underlying object. -@throw ::E57_ERROR_BAD_NODE_DOWNCAST -@see Node::type(), BlobNode::operator Node() -*/ -BlobNode::BlobNode( const Node &n ) -{ - if ( n.type() != E57_BLOB ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_NODE_DOWNCAST, "nodeType=" + toString( n.type() ) ); - } - - /// Set our shared_ptr to the downcast shared_ptr - impl_ = std::static_pointer_cast( n.impl() ); -} - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -BlobNode::BlobNode( ImageFile destImageFile, int64_t fileOffset, int64_t length ) : - impl_( new BlobNodeImpl( destImageFile.impl(), fileOffset, length ) ) -{ -} - -BlobNode::BlobNode( std::shared_ptr ni ) : impl_( ni ) -{ -} -//! @endcond - -//===================================================================================== -/*! -@class ImageFile -@brief An ASTM E57 3D format file object. -@details -@section imagefile_ClassOverview Class overview -The ImageFile class represents the state of an ASTM E57 format data file. -An ImageFile may be created from an E57 file on the disk (read mode). -An new ImageFile may be created to write an E57 file to disk (write mode). - -E57 files are organized in a tree structure. -Each ImageFile object has a predefined root node (of type StructureNode). -In a write mode ImageFile, the root node is initially empty. -In a read mode ImageFile, the root node is populated by the tree stored in the -.e57 file on disk. - -@section imagefile_OpenClose The open/close state -An ImageFile object, opened in either mode (read/write), can be in one of two -states: open or closed. An ImageFile in the open state is ready to perform -transfers of data and to be interrogated. An ImageFile in the closed state -cannot perform any further transfers, and has very limited ability to be -interrogated. Note entering the closed state is different than destroying the -ImageFile object. An ImageFile object can still exist and be in the closed -state. When created, the ImageFile is initially open. - -The ImageFile state can transition to the closed state in two ways. -The programmer can call ImageFile::close after all required processing has -completed. The programmer can call ImageFile::cancel if it is determined that -the ImageFile is no longer needed. - -@section imagefile_Extensions Extensions - -Basically in an E57 file, "extension = namespace + rules + meaning". -The "namespace" ensures that element names don't collide. -The "rules" may be written on paper, or partly codified in a computer grammar. -The "meaning" is a definition of what was measured, what the numbers in the file -mean. - -Extensions are identified by URIs. -Extensions are not identified by prefixes. -Prefixes are a shorthand, used in a particular file, to make the element names -more palatable for humans. When thinking about a prefixed element name, in your -mind you should immediately substitute the URI for the prefix. For example, -think "http://www.example.com/DemoExtension:extra2" rather than "demo:extra2", -if the prefix "demo" is declared in the file to be a shorthand for the URI -"http://www.example.com/DemoExtension". - -The rules are statements of: what is valid, what element names are possible, -what values are possible. The rules establish the answer to the following yes/no -question: "Is this extended E57 file valid?". The rules divide all possible -files into two sets: valid files and invalid files. - -The "meanings" part of the above equation defines what the files in the first -set, the valid files, actually mean. This definition usually comes in the form -of documentation of the content of each new element in the format and how they -relate to the other elements. - -An element name in an E57 file is a member of exactly one namespace (either the -default namespace defined in the ASTM standard, or an extension namespace). -Rules about the structure of an E57 extension (what element names can appear -where), are implicitly assumed only to govern the element names within the -namespace of the extension. Element names in other namespaces are unconstrained. -This is because a reader is required to ignore elements in namespaces that are -unfamiliar (to treat them as if they didn't exist). This enables a writer to -"tack on" new elements into pre-defined structures (e.g. structures defined in -the ASTM standard), without fear that it will confuse a reader that is only -familiar with the old format. This allows an extension designer to communicate -to two sets of readers: the old readers that will understand the information in -the old base format, and the new-fangled readers that will be able to read the -base format and the extra information stored in element names in the extended -namespace. - -@section ImageFile_invariant Class Invariant -A class invariant is a list of statements about an object that are always true -before and after any operation on the object. An invariant is useful for testing -correct operation of an implementation. Statements in an invariant can involve -only externally visible state, or can refer to internal implementation-specific -state that is not visible to the API user. The following C++ code checks -externally visible state for consistency and throws an exception if the -invariant is violated: -@dontinclude E57Format.cpp -@skip begin ImageFile::checkInvariant -@skip checkInvariant( -@until end ImageFile::checkInvariant -*/ - -/*! -@brief Open an ASTM E57 imaging data file for reading/writing. -@param [in] fname File name to open. -Support of '\' as a directory separating character is system dependent. -For maximum portability, it is recommended that '/' be used as a directory -separator in file names. Special device file name support are implementation -dependent (e.g. "\\.\PhysicalDrive3" or -"/dev/hd3"). It is recommended that files that meet all of the requirements for -a legal ASTM E57 file format use the extension @c ".e57". It is recommended that -files that utilize the low-level E57 element data types, but do not have all the -required element names required by ASTM E57 file format standard use the file -extension @c "._e57". -@param [in] mode Either "w" for writing or "r" for reading. -@param [in] checksumPolicy The percentage of checksums we compute and verify -as an int. Clamped to 0-100. -@details - -@par Write Mode -In write mode, the file cannot be already open. -A file with name given by @a fname is immediately created on the disk. -This file may grow as a result of operations on the ImageFile. -Which API functions write data to the file are implementation dependent. -Thus any API operation that stores data may fail as a result of insufficient -free disk space. Read API operations are legal for an ImageFile opened in write -mode. - -@par Read Mode -Read mode files may be shared. -Write API operations are not legal for an ImageFile opened in read mode (i.e. -the ImageFile is read-only). There is no API support for appending data onto an -existing E57 data file. - -@post Resulting ImageFile is in @c open state if constructor succeeds (no -exception thrown). -@return A smart ImageFile handle referencing the underlying object. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_OPEN_FAILED -@throw ::E57_ERROR_LSEEK_FAILED -@throw ::E57_ERROR_READ_FAILED -@throw ::E57_ERROR_WRITE_FAILED -@throw ::E57_ERROR_BAD_CHECKSUM -@throw ::E57_ERROR_BAD_FILE_SIGNATURE -@throw ::E57_ERROR_UNKNOWN_FILE_VERSION -@throw ::E57_ERROR_BAD_FILE_LENGTH -@throw ::E57_ERROR_XML_PARSER_INIT -@throw ::E57_ERROR_XML_PARSER -@throw ::E57_ERROR_BAD_XML_FORMAT -@throw ::E57_ERROR_BAD_CONFIGURATION -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see IntegerNode, ScaledIntegerNode, FloatNode, -StringNode, BlobNode, StructureNode, VectorNode, CompressedVectorNode, -E57Exception, E57Utilities::E57Utilities -*/ -ImageFile::ImageFile( const ustring &fname, const ustring &mode, ReadChecksumPolicy checksumPolicy ) : - impl_( new ImageFileImpl( checksumPolicy ) ) -{ - /// Do second phase of construction, now that ImageFile object is complete. - impl_->construct2( fname, mode ); -} - -ImageFile::ImageFile( const char *input, const uint64_t size, ReadChecksumPolicy checksumPolicy ) : - impl_( new ImageFileImpl( checksumPolicy ) ) -{ - impl_->construct2( input, size ); -} - -/*! -@brief Get the pre-established root StructureNode of the E57 ImageFile. -@details The root node of an ImageFile always exists and is always type -StructureNode. The root node is empty in a newly created write mode ImageFile. -@pre This ImageFile must be open (i.e. isOpen()). -@return A smart StructureNode handle referencing the underlying object. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see StructureNode. -*/ -StructureNode ImageFile::root() const -{ - return StructureNode( impl_->root() ); -} - -/*! -@brief Complete any write operations on an ImageFile, and close the file on -the disk. -@details -Completes the writing of the state of the ImageFile to the disk. -Some API implementations may store significant portions of the state of the -ImageFile in memory. This state is moved into the disk file before it is closed. -Any errors in finishing the writing are reported by throwing an exception. -If an exception is thrown, depending on the error code, the ImageFile may enter -the closed state. If no exception is thrown, then the file on disk will be an -accurate representation of the ImageFile. - -@b Warning: if the ImageFile::close function is not called, and the ImageFile -destructor is invoked with the ImageFile in the open state, the associated disk -file will be deleted and the ImageFile will @em not be saved to the disk (the -same outcome as calling ImageFile::cancel). The reason for this is that any -error conditions can't be reported from a destructor, so the user can't be -assured that the destruction/close completed successfully. It is strongly -recommended that this close function be called before the ImageFile is -destroyed. - -It is not an error if ImageFile is already closed. -@post ImageFile is in @c closed state. -@throw ::E57_ERROR_LSEEK_FAILED -@throw ::E57_ERROR_READ_FAILED -@throw ::E57_ERROR_WRITE_FAILED -@throw ::E57_ERROR_CLOSE_FAILED -@throw ::E57_ERROR_BAD_CHECKSUM -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ImageFile::cancel, ImageFile::isOpen -*/ -void ImageFile::close() -{ - impl_->close(); -} - -/*! -@brief Stop I/O operations and delete a partially written ImageFile on the -disk. -@details -If the ImageFile is write mode, the associated file on the disk is closed and -deleted, and the ImageFile goes to the closed state. If the ImageFile is read -mode, the behavior is same as calling ImageFile::close, but no exceptions are -thrown. It is not an error if ImageFile is already closed. -@post ImageFile is in @c closed state. -@throw No E57Exceptions. -@see ImageFile::ImageFile, ImageFile::close, ImageFile::isOpen -*/ -void ImageFile::cancel() -{ - impl_->cancel(); -} - -/*! -@brief Test whether ImageFile is still open for accessing. -@post No visible state is modified. -@return true if ImageFile is in @c open state. -@throw No E57Exceptions. -@see ImageFile::ImageFile, ImageFile::close -*/ -bool ImageFile::isOpen() const -{ - return impl_->isOpen(); -} - -/*! -@brief Test whether ImageFile was opened in write mode. -@post No visible state is modified. -@return true if ImageFile was opened in write mode. -@throw No E57Exceptions. -@see ImageFile::ImageFile, ImageFile::isOpen -*/ -bool ImageFile::isWritable() const -{ - return impl_->isWriter(); -} - -/*! -@brief Get the file name the ImageFile was created with. -@post No visible state is modified. -@return The file name the ImageFile was created with. -@throw No E57Exceptions. -@see Cancel.cpp example, ImageFile::ImageFile -*/ -ustring ImageFile::fileName() const -{ - return impl_->fileName(); -} - -/*! -@brief Get current number of open CompressedVectorWriter objects writing to -ImageFile. -@details -CompressedVectorWriter objects that still exist, but are in the closed state -aren't counted. CompressedVectorWriter objects are created by the -CompressedVectorNode::writer function. -@pre This ImageFile must be open (i.e. isOpen()). -@post No visible state is modified. -@return The current number of open CompressedVectorWriter objects writing to -ImageFile. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorNode::writer, CompressedVectorWriter -*/ -int ImageFile::writerCount() const -{ - return impl_->writerCount(); -} - -/*! -@brief Get current number of open CompressedVectorReader objects reading from -ImageFile. -@details -CompressedVectorReader objects that still exist, but are in the closed state -aren't counted. CompressedVectorReader objects are created by the -CompressedVectorNode::reader function. -@pre This ImageFile must be open (i.e. isOpen()). -@post No visible state is modified. -@return The current number of open CompressedVectorReader objects reading from -ImageFile. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see CompressedVectorNode::reader, CompressedVectorReader -*/ -int ImageFile::readerCount() const -{ - return impl_->readerCount(); -} - -/*! -@brief Declare the use of an E57 extension in an ImageFile being written. -@param [in] prefix The shorthand name of the extension to use in element -names. -@param [in] uri The Uniform Resource Identifier string to associate with -the prefix in the ImageFile. -@details -The (@a prefix, @a uri) pair is registered in the known extensions of the -ImageFile. Both @a prefix and @a uri must be unique in the ImageFile. It is not -legal to declare a URI associated with the default namespace (@a prefix = ""). -It is not an error to declare a namespace and not use it in an element name. -It is an error to use a namespace prefix in an element name that is not declared -beforehand. - -A writer is free to "hard code" the prefix names in the element name strings -that it uses (since it established the prefix declarations in the file). A -reader cannot assume that any given prefix is always mapped to the same URI or -vice versa. A reader might check an ImageFile, and if the prefixes aren't the -way it likes, the reader could give up. - -A better scheme would be to lookup the URI that the reader is familiar with, and -store the prefix that the particular file uses in a variable. Then every time -the reader needs to form a prefixed element name, it can assemble the full -element name from the stored prefix variable and the constant documented base -name string. This is less convenient than using a single "hard coded" string -constant for an element name, but it is robust against any choice of prefix/URI -combination. - -See the class discussion at bottom of ImageFile page for more details about -namespaces. -@pre This ImageFile must be open (i.e. isOpen()). -@pre ImageFile must have been opened in write mode (i.e. isWritable()). -@pre prefix != "" -@pre uri != "" -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_FILE_IS_READ_ONLY -@throw ::E57_ERROR_DUPLICATE_NAMESPACE_PREFIX -@throw ::E57_ERROR_DUPLICATE_NAMESPACE_URI -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ImageFile::extensionsCount, ImageFile::extensionsLookupPrefix, ImageFile::extensionsLookupUri -*/ -void ImageFile::extensionsAdd( const ustring &prefix, const ustring &uri ) -{ - impl_->extensionsAdd( prefix, uri ); -} - -/*! -@brief Get URI associated with an E57 extension prefix in the ImageFile. -@param [in] prefix The shorthand name of the extension to look up. -@param [out] uri The URI that was associated with the given @a prefix. -@details -If @a prefix = "", then @a uri is set to the default namespace URI, and the -function returns true. if @a prefix is declared in the ImageFile, then @a uri is -set the corresponding URI, and the function returns true. It is an error if @a -prefix contains an illegal character combination for E57 namespace prefixes. It -is not an error if @a prefix is well-formed, but not defined in the ImageFile -(the function just returns false). -@pre This ImageFile must be open (i.e. isOpen()). -@post No visible state is modified. -@return true if prefix is declared in the ImageFile. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ImageFile::extensionsLookupUri -*/ -bool ImageFile::extensionsLookupPrefix( const ustring &prefix, ustring &uri ) const -{ - return impl_->extensionsLookupPrefix( prefix, uri ); -} - -/*! -@brief Get an E57 extension prefix associated with a URI in the ImageFile. -@param [in] uri The URI of the extension to look up. -@param [out] prefix The shorthand prefix that was associated with the given -@a uri. -@details -If @a uri is declared in the ImageFile, then @a prefix is set the corresponding -prefix, and the function returns true. It is an error if @a uri contains an -illegal character combination for E57 namespace URIs. It is not an error if @a -uri is well-formed, but not defined in the ImageFile (the function just returns -false). -@pre This ImageFile must be open (i.e. isOpen()). -@pre uri != "" -@post No visible state is modified. -@return true if URI is declared in the ImageFile. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ImageFile::extensionsLookupPrefix -*/ -bool ImageFile::extensionsLookupUri( const ustring &uri, ustring &prefix ) const -{ - return impl_->extensionsLookupUri( uri, prefix ); -} - -/*! -@brief Get number of E57 extensions declared in the ImageFile. -@details -The default E57 namespace does not count as an extension. -@pre This ImageFile must be open (i.e. isOpen()). -@post No visible state is modified. -@return The number of E57 extensions defined in the ImageFile. -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ImageFile::extensionsPrefix, ImageFile::extensionsUri -*/ -size_t ImageFile::extensionsCount() const -{ - return impl_->extensionsCount(); -} - -/*! -@brief Get an E57 extension prefix declared in an ImageFile by index. -@param [in] index The index of the prefix to get, starting at 0. -@details -The order that the prefixes are stored in is not necessarily the same as the -order they were created. However the prefix order will correspond to the URI -order. The default E57 namespace is not counted as an extension. -@pre This ImageFile must be open (i.e. isOpen()). -@pre 0 <= index < extensionsCount() -@post No visible state is modified. -@return The E57 extension prefix at the given index. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ImageFile::extensionsCount, ImageFile::extensionsUri -*/ -ustring ImageFile::extensionsPrefix( const size_t index ) const -{ - return impl_->extensionsPrefix( index ); -} - -/*! -@brief Get an E57 extension URI declared in an ImageFile by index. -@param [in] index The index of the URI to get, starting at 0. -@details -The order that the URIs are stored is not necessarily the same as the order they -were created. However the URI order will correspond to the prefix order. The -default E57 namespace is not counted as an extension. -@pre This ImageFile must be open (i.e. isOpen()). -@pre 0 <= index < extensionsCount() -@post No visible state is modified. -@return The E57 extension URI at the given index. -@throw ::E57_ERROR_BAD_API_ARGUMENT -@throw ::E57_ERROR_IMAGEFILE_NOT_OPEN -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ImageFile::extensionsCount, ImageFile::extensionsPrefix -*/ -ustring ImageFile::extensionsUri( const size_t index ) const -{ - return impl_->extensionsUri( index ); -} - -/*! -@brief Test whether an E57 element name has an extension prefix. -@details -The element name has a prefix if the function -elementNameParse(elementName,prefix,dummy) would succeed, and returned prefix != -"". -@param [in] elementName The string element name to test. -@post No visible state is modified. -@return True if the E57 element name has an extension prefix. -@throw No E57Exceptions. -*/ -bool ImageFile::isElementNameExtended( const ustring &elementName ) const -{ - return impl_->isElementNameExtended( elementName ); -} - -/*! -@brief Parse element name into prefix and localPart substrings. -@param [in] elementName The string element name to parse into prefix and -local parts. -@param [out] prefix The prefix (if any) in the @a elementName. -@param [out] localPart The part of the element name after the prefix. -@details -A legal element name may be in prefixed (ID:ID) or unprefixed (ID) form, -where ID is a string whose first character is in {a-z,A-Z,_} followed by zero or -more characters in {a-z,A-Z,_,0-9,-,.}. If in prefixed form, the prefix does not -have to be declared in the ImageFile. -@post No visible state is modified. -@throw ::E57_ERROR_BAD_PATH_NAME -@throw ::E57_ERROR_INTERNAL All objects in undocumented state -@see ImageFile::isElementNameExtended -*/ -void ImageFile::elementNameParse( const ustring &elementName, ustring &prefix, ustring &localPart ) const -{ - impl_->elementNameParse( elementName, prefix, localPart ); -} - -/*! -@brief Diagnostic function to print internal state of object to output stream -in an indented format. -@copydetails Node::dump() -*/ -#ifdef E57_DEBUG -void ImageFile::dump( int indent, std::ostream &os ) const -{ - impl_->dump( indent, os ); -} -#else -void ImageFile::dump( int indent, std::ostream &os ) const -{ -} -#endif - -/*! -@brief Test if two ImageFile handles refer to the same underlying ImageFile -@param [in] imf2 The ImageFile to compare this ImageFile with -@post No visible object state is modified. -@return @c true if ImageFile handles refer to the same underlying ImageFile. -@throw No E57Exceptions -*/ -bool ImageFile::operator==( ImageFile imf2 ) const -{ - return ( impl_ == imf2.impl_ ); -} - -/*! -@brief Test if two ImageFile handles refer to different underlying ImageFile -@param [in] imf2 The ImageFile to compare this ImageFile with -@post No visible object state is modified. -@return @c true if ImageFile handles refer to different underlying ImageFiles. -@throw No E57Exceptions -*/ -bool ImageFile::operator!=( ImageFile imf2 ) const -{ - return ( impl_ != imf2.impl_ ); -} - -//! @cond documentNonPublic The following isn't part of the API, and isn't -//! documented. -ImageFile::ImageFile( ImageFileImplSharedPtr imfi ) : impl_( imfi ) -{ -} -//! @endcond diff --git a/src/3rdParty/libE57Format/src/E57SimpleData.cpp b/src/3rdParty/libE57Format/src/E57SimpleData.cpp deleted file mode 100644 index 20de2084ec..0000000000 --- a/src/3rdParty/libE57Format/src/E57SimpleData.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// Copyright (c) 2020 PTC Inc. - -// for M_PI. This needs to be first, otherwise we might already include math header -// without M_PI and we would get nothing because of the header guards. -#define _USE_MATH_DEFINES -#include - -#include "E57SimpleData.h" - -namespace e57 -{ - - // To avoid exposing M_PI, we define the constructor here. - SphericalBounds::SphericalBounds() - { - rangeMinimum = 0.; - rangeMaximum = E57_DOUBLE_MAX; - azimuthStart = -M_PI; - azimuthEnd = M_PI; - elevationMinimum = -M_PI / 2.; - elevationMaximum = M_PI / 2.; - } - -} // end namespace e57 diff --git a/src/3rdParty/libE57Format/src/E57SimpleReader.cpp b/src/3rdParty/libE57Format/src/E57SimpleReader.cpp deleted file mode 100644 index b2ca2207f1..0000000000 --- a/src/3rdParty/libE57Format/src/E57SimpleReader.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2010 Stan Coleby (scoleby@intelisum.com) - * Copyright (c) 2020 PTC Inc. - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "E57SimpleReader.h" -#include "ReaderImpl.h" - -namespace e57 -{ - - Reader::Reader( const ustring &filePath ) : impl_( new ReaderImpl( filePath ) ) - { - } - - bool Reader::IsOpen() const - { - return impl_->IsOpen(); - }; - - bool Reader::Close() - { - return impl_->Close(); - }; - - bool Reader::GetE57Root( E57Root &fileHeader ) const - { - return impl_->GetE57Root( fileHeader ); - }; - - int64_t Reader::GetImage2DCount() const - { - return impl_->GetImage2DCount(); - }; - - bool Reader::ReadImage2D( int64_t imageIndex, Image2D &image2DHeader ) const - { - return impl_->ReadImage2D( imageIndex, image2DHeader ); - }; - - bool Reader::GetImage2DSizes( int64_t imageIndex, Image2DProjection &imageProjection, Image2DType &imageType, - int64_t &imageWidth, int64_t &imageHeight, int64_t &imageSize, - Image2DType &imageMaskType, Image2DType &imageVisualType ) const - { - return impl_->GetImage2DSizes( imageIndex, imageProjection, imageType, imageWidth, imageHeight, imageSize, - imageMaskType, imageVisualType ); - }; - - int64_t Reader::ReadImage2DData( int64_t imageIndex, Image2DProjection imageProjection, Image2DType imageType, - void *pBuffer, int64_t start, int64_t count ) const - { - return impl_->ReadImage2DData( imageIndex, imageProjection, imageType, pBuffer, start, count ); - }; - - int64_t Reader::GetData3DCount() const - { - return impl_->GetData3DCount(); - }; - - ImageFile Reader::GetRawIMF() const - { - return impl_->GetRawIMF(); - } - - StructureNode Reader::GetRawE57Root() const - { - return impl_->GetRawE57Root(); - }; - - VectorNode Reader::GetRawData3D() const - { - return impl_->GetRawData3D(); - }; - - VectorNode Reader::GetRawImages2D() const - { - return impl_->GetRawImages2D(); - }; - - bool Reader::ReadData3D( int64_t dataIndex, Data3D &data3DHeader ) const - { - return impl_->ReadData3D( dataIndex, data3DHeader ); - } - - bool Reader::GetData3DSizes( int64_t dataIndex, int64_t &rowMax, int64_t &columnMax, int64_t &pointsSize, - int64_t &groupsSize, int64_t &countSize, bool &bColumnIndex ) const - { - return impl_->GetData3DSizes( dataIndex, rowMax, columnMax, pointsSize, groupsSize, countSize, bColumnIndex ); - } - - bool Reader::ReadData3DGroupsData( int64_t dataIndex, int64_t groupCount, int64_t *idElementValue, - int64_t *startPointIndex, int64_t *pointCount ) const - { - return impl_->ReadData3DGroupsData( dataIndex, groupCount, idElementValue, startPointIndex, pointCount ); - } - - CompressedVectorReader Reader::SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData &buffers ) const - { - return impl_->SetUpData3DPointsData( dataIndex, pointCount, buffers ); - } - - CompressedVectorReader Reader::SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData_d &buffers ) const - { - return impl_->SetUpData3DPointsData( dataIndex, pointCount, buffers ); - } - -} // end namespace e57 diff --git a/src/3rdParty/libE57Format/src/E57SimpleWriter.cpp b/src/3rdParty/libE57Format/src/E57SimpleWriter.cpp deleted file mode 100644 index c2c1fa7620..0000000000 --- a/src/3rdParty/libE57Format/src/E57SimpleWriter.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2010 Stan Coleby (scoleby@intelisum.com) - * Copyright (c) 2020 PTC Inc. - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "E57SimpleWriter.h" -#include "WriterImpl.h" - -namespace e57 -{ - - Writer::Writer( const ustring &filePath, const ustring &coordinateMetaData ) : - impl_( new WriterImpl( filePath, coordinateMetaData ) ) - { - } - - bool Writer::IsOpen() const - { - return impl_->IsOpen(); - }; - - bool Writer::Close() - { - return impl_->Close(); - }; - - ImageFile Writer::GetRawIMF() - { - return impl_->GetRawIMF(); - } - - StructureNode Writer::GetRawE57Root() - { - return impl_->GetRawE57Root(); - }; - - VectorNode Writer::GetRawData3D() - { - return impl_->GetRawData3D(); - }; - - VectorNode Writer::GetRawImages2D() - { - return impl_->GetRawImages2D(); - }; - - int64_t Writer::NewImage2D( Image2D &image2DHeader ) - { - return impl_->NewImage2D( image2DHeader ); - }; - - int64_t Writer::WriteImage2DData( int64_t imageIndex, Image2DType imageType, Image2DProjection imageProjection, - void *pBuffer, int64_t start, int64_t count ) - { - return impl_->WriteImage2DData( imageIndex, imageType, imageProjection, pBuffer, start, count ); - }; - - int64_t Writer::NewData3D( Data3D &data3DHeader ) - { - return impl_->NewData3D( data3DHeader ); - }; - - CompressedVectorWriter Writer::SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData &buffers ) - { - return impl_->SetUpData3DPointsData( dataIndex, pointCount, buffers ); - } - - CompressedVectorWriter Writer::SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData_d &buffers ) - { - return impl_->SetUpData3DPointsData( dataIndex, pointCount, buffers ); - } - - bool Writer::WriteData3DGroupsData( int64_t dataIndex, int64_t groupCount, int64_t *idElementValue, - int64_t *startPointIndex, int64_t *pointCount ) - { - return impl_->WriteData3DGroupsData( dataIndex, groupCount, idElementValue, startPointIndex, pointCount ); - } - -} // end namespace e57 diff --git a/src/3rdParty/libE57Format/src/E57Version.h b/src/3rdParty/libE57Format/src/E57Version.h deleted file mode 100644 index 925b2cbd12..0000000000 --- a/src/3rdParty/libE57Format/src/E57Version.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -// SPDX-License-Identifier: MIT -// Copyright 2020 Andy Maloney - -#include - -namespace e57 -{ - /// Version numbers of ASTM standard that this library supports - constexpr uint32_t E57_FORMAT_MAJOR = 1; - constexpr uint32_t E57_FORMAT_MINOR = 0; -} diff --git a/src/3rdParty/libE57Format/src/E57XmlParser.cpp b/src/3rdParty/libE57Format/src/E57XmlParser.cpp deleted file mode 100644 index eecc2ea289..0000000000 --- a/src/3rdParty/libE57Format/src/E57XmlParser.cpp +++ /dev/null @@ -1,919 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include - -#include -#include - -#include "BlobNodeImpl.h" -#include "CheckedFile.h" -#include "CompressedVectorNodeImpl.h" -#include "E57XmlParser.h" -#include "FloatNodeImpl.h" -#include "ImageFileImpl.h" -#include "IntegerNodeImpl.h" -#include "ScaledIntegerNodeImpl.h" -#include "StringNodeImpl.h" -#include "VectorNodeImpl.h" - -#if __GNUC__ >= 11 -#include -#endif - -using namespace e57; -using namespace XERCES_CPP_NAMESPACE; - -// define convenient constants for the attribute names -static const XMLCh att_minimum[] = { - chLatin_m, chLatin_i, chLatin_n, chLatin_i, chLatin_m, chLatin_u, chLatin_m, chNull -}; -static const XMLCh att_maximum[] = { - chLatin_m, chLatin_a, chLatin_x, chLatin_i, chLatin_m, chLatin_u, chLatin_m, chNull -}; -static const XMLCh att_scale[] = { chLatin_s, chLatin_c, chLatin_a, chLatin_l, chLatin_e, chNull }; -static const XMLCh att_offset[] = { chLatin_o, chLatin_f, chLatin_f, chLatin_s, chLatin_e, chLatin_t, chNull }; -static const XMLCh att_precision[] = { chLatin_p, chLatin_r, chLatin_e, chLatin_c, chLatin_i, - chLatin_s, chLatin_i, chLatin_o, chLatin_n, chNull }; -static const XMLCh att_allowHeterogeneousChildren[] = { - chLatin_a, chLatin_l, chLatin_l, chLatin_o, chLatin_w, chLatin_H, chLatin_e, chLatin_t, chLatin_e, - chLatin_r, chLatin_o, chLatin_g, chLatin_e, chLatin_n, chLatin_e, chLatin_o, chLatin_u, chLatin_s, - chLatin_C, chLatin_h, chLatin_i, chLatin_l, chLatin_d, chLatin_r, chLatin_e, chLatin_n, chNull -}; -static const XMLCh att_fileOffset[] = { chLatin_f, chLatin_i, chLatin_l, chLatin_e, chLatin_O, chLatin_f, - chLatin_f, chLatin_s, chLatin_e, chLatin_t, chNull }; - -static const XMLCh att_type[] = { chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull }; -static const XMLCh att_length[] = { chLatin_l, chLatin_e, chLatin_n, chLatin_g, chLatin_t, chLatin_h, chNull }; -static const XMLCh att_recordCount[] = { chLatin_r, chLatin_e, chLatin_c, chLatin_o, chLatin_r, chLatin_d, - chLatin_C, chLatin_o, chLatin_u, chLatin_n, chLatin_t, chNull }; - -inline int64_t convertStrToLL( const std::string &inStr ) -{ -#if defined( _MSC_VER ) - return _atoi64( inStr.c_str() ); -#elif defined( __GNUC__ ) - return strtoll( inStr.c_str(), nullptr, 10 ); -#else -#error "Need to define string to long long conversion for this compiler" -#endif -} - -//============================================================================= -// E57FileInputStream - -class E57FileInputStream : public BinInputStream -{ -public: - E57FileInputStream( CheckedFile *cf, uint64_t logicalStart, uint64_t logicalLength ); - ~E57FileInputStream() override = default; - - E57FileInputStream( const E57FileInputStream & ) = delete; - E57FileInputStream &operator=( const E57FileInputStream & ) = delete; - - XMLFilePos curPos() const override - { - return ( logicalPosition_ ); - } - XMLSize_t readBytes( XMLByte *const toFill, const XMLSize_t maxToRead ) override; - const XMLCh *getContentType() const override - { - return nullptr; - } - -private: - //??? lifetime of cf_ must be longer than this object! - CheckedFile *cf_; - uint64_t logicalStart_; - uint64_t logicalLength_; - uint64_t logicalPosition_; -}; - -E57FileInputStream::E57FileInputStream( CheckedFile *cf, uint64_t logicalStart, uint64_t logicalLength ) : - cf_( cf ), logicalStart_( logicalStart ), logicalLength_( logicalLength ), logicalPosition_( logicalStart ) -{ -} - -XMLSize_t E57FileInputStream::readBytes( XMLByte *const toFill, const XMLSize_t maxToRead ) -{ - if ( logicalPosition_ > logicalStart_ + logicalLength_ ) - { - return ( 0 ); - } - - int64_t available = logicalStart_ + logicalLength_ - logicalPosition_; - if ( available <= 0 ) - { - return ( 0 ); - } - - /// size_t and XMLSize_t should be compatible, should get compiler warning - /// here if not - size_t maxToRead_size = maxToRead; - - /// Be careful if size_t is smaller than int64_t - size_t available_size; - if ( sizeof( size_t ) >= sizeof( int64_t ) ) - { - /// size_t is at least as big as int64_t - available_size = static_cast( available ); - } - else - { - /// size_t is smaller than int64_t, Calc max that size_t can hold - const int64_t size_max = std::numeric_limits::max(); - - /// read smaller of size_max, available - ///??? redo - if ( size_max < available ) - { - available_size = static_cast( size_max ); - } - else - { - available_size = static_cast( available ); - } - } - - size_t readCount = std::min( maxToRead_size, available_size ); - - cf_->seek( logicalPosition_ ); - cf_->read( reinterpret_cast( toFill ), readCount ); //??? cast ok? - logicalPosition_ += readCount; - return ( readCount ); -} - -//============================================================================= -// E57XmlFileInputSource - -E57XmlFileInputSource::E57XmlFileInputSource( CheckedFile *cf, uint64_t logicalStart, uint64_t logicalLength ) : - InputSource( "E57File", - XMLPlatformUtils::fgMemoryManager ), //??? what if want to use our own - // memory - // manager?, what bufid is good? - cf_( cf ), logicalStart_( logicalStart ), logicalLength_( logicalLength ) -{ -} - -BinInputStream *E57XmlFileInputSource::makeStream() const -{ - return new E57FileInputStream( cf_, logicalStart_, logicalLength_ ); -} - -//============================================================================= -// E57XmlParser::ParseInfo - -E57XmlParser::ParseInfo::ParseInfo() : - nodeType( static_cast( 0 ) ), minimum( 0 ), maximum( 0 ), scale( 0 ), offset( 0 ), - precision( static_cast( 0 ) ), floatMinimum( 0 ), floatMaximum( 0 ), fileOffset( 0 ), length( 0 ), - allowHeterogeneousChildren( false ), recordCount( 0 ) -{ -} - -void E57XmlParser::ParseInfo::dump( int indent, std::ostream &os ) const -{ - os << space( indent ) << "nodeType: " << nodeType << std::endl; - os << space( indent ) << "minimum: " << minimum << std::endl; - os << space( indent ) << "maximum: " << maximum << std::endl; - os << space( indent ) << "scale: " << scale << std::endl; - os << space( indent ) << "offset: " << offset << std::endl; - os << space( indent ) << "precision: " << precision << std::endl; - os << space( indent ) << "floatMinimum: " << floatMinimum << std::endl; - os << space( indent ) << "floatMaximum: " << floatMaximum << std::endl; - os << space( indent ) << "fileOffset: " << fileOffset << std::endl; - os << space( indent ) << "length: " << length << std::endl; - os << space( indent ) << "allowHeterogeneousChildren: " << allowHeterogeneousChildren << std::endl; - os << space( indent ) << "recordCount: " << recordCount << std::endl; - if ( container_ni ) - { - os << space( indent ) << "container_ni: " << std::endl; - } - else - { - os << space( indent ) << "container_ni: " << std::endl; - } - os << space( indent ) << "childText: \"" << childText << "\"" << std::endl; -} - -//============================================================================= -// E57XmlParser - -E57XmlParser::E57XmlParser( ImageFileImplSharedPtr imf ) : imf_( imf ), xmlReader( nullptr ) -{ -} - -E57XmlParser::~E57XmlParser() -{ - delete xmlReader; - - xmlReader = nullptr; - - XMLPlatformUtils::Terminate(); -} - -void E57XmlParser::init() -{ - // Initialize the XML4C2 system - try - { - XMLPlatformUtils::Initialize(); - } - catch ( const XMLException &ex ) - { - /// Turn parser exception into E57Exception - throw E57_EXCEPTION2( E57_ERROR_XML_PARSER_INIT, - "parserMessage=" + ustring( XMLString::transcode( ex.getMessage() ) ) ); - } - - xmlReader = XMLReaderFactory::createXMLReader(); //??? auto_ptr? - - if ( !xmlReader ) - { - throw E57_EXCEPTION2( E57_ERROR_XML_PARSER_INIT, "could not create the xml reader" ); - } - - //??? check these are right - xmlReader->setFeature( XMLUni::fgSAX2CoreValidation, true ); - xmlReader->setFeature( XMLUni::fgXercesDynamic, true ); - xmlReader->setFeature( XMLUni::fgSAX2CoreNameSpaces, true ); - xmlReader->setFeature( XMLUni::fgXercesSchema, true ); - xmlReader->setFeature( XMLUni::fgXercesSchemaFullChecking, true ); - xmlReader->setFeature( XMLUni::fgSAX2CoreNameSpacePrefixes, true ); - - xmlReader->setContentHandler( this ); - xmlReader->setErrorHandler( this ); -} - -void E57XmlParser::parse( InputSource &inputSource ) -{ - xmlReader->parse( inputSource ); -} - -void E57XmlParser::startElement( const XMLCh *const uri, const XMLCh *const localName, const XMLCh *const qName, - const Attributes &attributes ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "startElement" << std::endl; - std::cout << space( 2 ) << "URI: " << toUString( uri ) << std::endl; - std::cout << space( 2 ) << "localName: " << toUString( localName ) << std::endl; - std::cout << space( 2 ) << "qName: " << toUString( qName ) << std::endl; - - for ( size_t i = 0; i < attributes.getLength(); i++ ) - { - std::cout << space( 2 ) << "Attribute[" << i << "]" << std::endl; - std::cout << space( 4 ) << "URI: " << toUString( attributes.getURI( i ) ) << std::endl; - std::cout << space( 4 ) << "localName: " << toUString( attributes.getLocalName( i ) ) << std::endl; - std::cout << space( 4 ) << "qName: " << toUString( attributes.getQName( i ) ) << std::endl; - std::cout << space( 4 ) << "value: " << toUString( attributes.getValue( i ) ) << std::endl; - } -#endif - /// Get Type attribute - ustring node_type = lookupAttribute( attributes, att_type ); - - //??? check to make sure not in primitive type (can only nest inside compound - // types). - - ParseInfo pi; - - if ( node_type == "Integer" ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "got a Integer" << std::endl; -#endif - //??? check validity of numeric strings - pi.nodeType = E57_INTEGER; - - if ( isAttributeDefined( attributes, att_minimum ) ) - { - ustring minimum_str = lookupAttribute( attributes, att_minimum ); - - pi.minimum = convertStrToLL( minimum_str ); - } - else - { - /// Not defined defined in XML, so defaults to E57_INT64_MIN - pi.minimum = E57_INT64_MIN; - } - - if ( isAttributeDefined( attributes, att_maximum ) ) - { - ustring maximum_str = lookupAttribute( attributes, att_maximum ); - - pi.maximum = convertStrToLL( maximum_str ); - } - else - { - /// Not defined defined in XML, so defaults to E57_INT64_MAX - pi.maximum = E57_INT64_MAX; - } - - /// Push info so far onto stack - stack_.push( pi ); - } - else if ( node_type == "ScaledInteger" ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "got a ScaledInteger" << std::endl; -#endif - pi.nodeType = E57_SCALED_INTEGER; - - //??? check validity of numeric strings - if ( isAttributeDefined( attributes, att_minimum ) ) - { - ustring minimum_str = lookupAttribute( attributes, att_minimum ); - - pi.minimum = convertStrToLL( minimum_str ); - } - else - { - /// Not defined defined in XML, so defaults to E57_INT64_MIN - pi.minimum = E57_INT64_MIN; - } - - if ( isAttributeDefined( attributes, att_maximum ) ) - { - ustring maximum_str = lookupAttribute( attributes, att_maximum ); - - pi.maximum = convertStrToLL( maximum_str ); - } - else - { - /// Not defined defined in XML, so defaults to E57_INT64_MAX - pi.maximum = E57_INT64_MAX; - } - - if ( isAttributeDefined( attributes, att_scale ) ) - { - ustring scale_str = lookupAttribute( attributes, att_scale ); - pi.scale = atof( scale_str.c_str() ); //??? use exact rounding library - } - else - { - /// Not defined defined in XML, so defaults to 1.0 - pi.scale = 1.0; - } - - if ( isAttributeDefined( attributes, att_offset ) ) - { - ustring offset_str = lookupAttribute( attributes, att_offset ); - pi.offset = atof( offset_str.c_str() ); //??? use exact rounding library - } - else - { - /// Not defined defined in XML, so defaults to 0.0 - pi.offset = 0.0; - } - - /// Push info so far onto stack - stack_.push( pi ); - } - else if ( node_type == "Float" ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "got a Float" << std::endl; -#endif - pi.nodeType = E57_FLOAT; - - if ( isAttributeDefined( attributes, att_precision ) ) - { - ustring precision_str = lookupAttribute( attributes, att_precision ); - if ( precision_str == "single" ) - { - pi.precision = E57_SINGLE; - } - else if ( precision_str == "double" ) - { - pi.precision = E57_DOUBLE; - } - else - { - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, - "precisionString=" + precision_str + " fileName=" + imf_->fileName() + - " uri=" + toUString( uri ) + " localName=" + toUString( localName ) + - " qName=" + toUString( qName ) ); - } - } - else - { - /// Not defined defined in XML, so defaults to double - pi.precision = E57_DOUBLE; - } - - if ( isAttributeDefined( attributes, att_minimum ) ) - { - ustring minimum_str = lookupAttribute( attributes, att_minimum ); - pi.floatMinimum = atof( minimum_str.c_str() ); //??? use exact rounding library - } - else - { - /// Not defined defined in XML, so defaults to E57_FLOAT_MIN or - /// E57_DOUBLE_MIN - if ( pi.precision == E57_SINGLE ) - { - pi.floatMinimum = E57_FLOAT_MIN; - } - else - { - pi.floatMinimum = E57_DOUBLE_MIN; - } - } - - if ( isAttributeDefined( attributes, att_maximum ) ) - { - ustring maximum_str = lookupAttribute( attributes, att_maximum ); - pi.floatMaximum = atof( maximum_str.c_str() ); //??? use exact rounding library - } - else - { - /// Not defined defined in XML, so defaults to FLOAT_MAX or DOUBLE_MAX - if ( pi.precision == E57_SINGLE ) - { - pi.floatMaximum = E57_FLOAT_MAX; - } - else - { - pi.floatMaximum = E57_DOUBLE_MAX; - } - } - - /// Push info so far onto stack - stack_.push( pi ); - } - else if ( node_type == "String" ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "got a String" << std::endl; -#endif - pi.nodeType = E57_STRING; - - /// Push info so far onto stack - stack_.push( pi ); - } - else if ( node_type == "Blob" ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "got a Blob" << std::endl; -#endif - pi.nodeType = E57_BLOB; - - //??? check validity of numeric strings - - /// fileOffset is required to be defined - ustring fileOffset_str = lookupAttribute( attributes, att_fileOffset ); - - pi.fileOffset = convertStrToLL( fileOffset_str ); - - /// length is required to be defined - ustring length_str = lookupAttribute( attributes, att_length ); - - pi.length = convertStrToLL( length_str ); - - /// Push info so far onto stack - stack_.push( pi ); - } - else if ( node_type == "Structure" ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "got a Structure" << std::endl; -#endif - pi.nodeType = E57_STRUCTURE; - - /// Read name space decls, if e57Root element - if ( toUString( localName ) == "e57Root" ) - { - /// Search attributes for namespace declarations (only allowed in - /// E57Root structure) - bool gotDefault = false; - for ( size_t i = 0; i < attributes.getLength(); i++ ) - { - /// Check if declaring the default namespace - if ( toUString( attributes.getQName( i ) ) == "xmlns" ) - { -#ifdef E57_VERBOSE - std::cout << "declared default namespace, URI=" << toUString( attributes.getValue( i ) ) << std::endl; -#endif - imf_->extensionsAdd( "", toUString( attributes.getValue( i ) ) ); - gotDefault = true; - } - - /// Check if declaring a namespace - if ( toUString( attributes.getURI( i ) ) == "http://www.w3.org/2000/xmlns/" ) - { -#ifdef E57_VERBOSE - std::cout << "declared extension, prefix=" << toUString( attributes.getLocalName( i ) ) - << " URI=" << toUString( attributes.getValue( i ) ) << std::endl; -#endif - imf_->extensionsAdd( toUString( attributes.getLocalName( i ) ), toUString( attributes.getValue( i ) ) ); - } - } - - /// If didn't declare a default namespace, have error - if ( !gotDefault ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, - "fileName=" + imf_->fileName() + " uri=" + toUString( uri ) + - " localName=" + toUString( localName ) + " qName=" + toUString( qName ) ); - } - } - - /// Create container now, so can hold children - std::shared_ptr s_ni( new StructureNodeImpl( imf_ ) ); - pi.container_ni = s_ni; - - /// After have Structure, check again if E57Root, if so mark attached so - /// all children will be attached when added - if ( toUString( localName ) == "e57Root" ) - { - s_ni->setAttachedRecursive(); - } - - /// Push info so far onto stack - stack_.push( pi ); - } - else if ( node_type == "Vector" ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "got a Vector" << std::endl; -#endif - pi.nodeType = E57_VECTOR; - - if ( isAttributeDefined( attributes, att_allowHeterogeneousChildren ) ) - { - ustring allowHetero_str = lookupAttribute( attributes, att_allowHeterogeneousChildren ); - - int64_t i64 = convertStrToLL( allowHetero_str ); - - if ( i64 == 0 ) - { - pi.allowHeterogeneousChildren = false; - } - else if ( i64 == 1 ) - { - pi.allowHeterogeneousChildren = true; - } - else - { - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, - "allowHeterogeneousChildren=" + toString( i64 ) + "fileName=" + imf_->fileName() + - " uri=" + toUString( uri ) + " localName=" + toUString( localName ) + - " qName=" + toUString( qName ) ); - } - } - else - { - /// Not defined defined in XML, so defaults to false - pi.allowHeterogeneousChildren = false; - } - - /// Create container now, so can hold children - std::shared_ptr v_ni( new VectorNodeImpl( imf_, pi.allowHeterogeneousChildren ) ); - pi.container_ni = v_ni; - - /// Push info so far onto stack - stack_.push( pi ); - } - else if ( node_type == "CompressedVector" ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "got a CompressedVector" << std::endl; -#endif - pi.nodeType = E57_COMPRESSED_VECTOR; - - /// fileOffset is required to be defined - ustring fileOffset_str = lookupAttribute( attributes, att_fileOffset ); - - pi.fileOffset = convertStrToLL( fileOffset_str ); - - /// recordCount is required to be defined - ustring recordCount_str = lookupAttribute( attributes, att_recordCount ); - - pi.recordCount = convertStrToLL( recordCount_str ); - - /// Create container now, so can hold children - std::shared_ptr cv_ni( new CompressedVectorNodeImpl( imf_ ) ); - cv_ni->setRecordCount( pi.recordCount ); - cv_ni->setBinarySectionLogicalStart( - imf_->file_->physicalToLogical( pi.fileOffset ) ); //??? what if file_ is NULL? - pi.container_ni = cv_ni; - - /// Push info so far onto stack - stack_.push( pi ); - } - else - { - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, - "nodeType=" + node_type + " fileName=" + imf_->fileName() + " uri=" + toUString( uri ) + - " localName=" + toUString( localName ) + " qName=" + toUString( qName ) ); - } -#ifdef E57_MAX_VERBOSE - pi.dump( 4 ); -#endif -} - -void E57XmlParser::endElement( const XMLCh *const uri, const XMLCh *const localName, const XMLCh *const qName ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "endElement" << std::endl; -#endif - - /// Pop the node that just ended - ParseInfo pi = stack_.top(); //??? really want to make a copy here? - stack_.pop(); -#ifdef E57_MAX_VERBOSE - pi.dump( 4 ); -#endif - - /// We should now have all the info we need to create the node - NodeImplSharedPtr current_ni; - - switch ( pi.nodeType ) - { - case E57_STRUCTURE: - case E57_VECTOR: - current_ni = pi.container_ni; - break; - case E57_COMPRESSED_VECTOR: - { - /// Verify that both prototype and codecs child elements were defined - /// ??? - current_ni = pi.container_ni; - } - break; - case E57_INTEGER: - { - /// Convert child text (if any) to value, else default to 0.0 - int64_t intValue; - if ( pi.childText.length() > 0 ) - { - intValue = convertStrToLL( pi.childText ); - } - else - { - intValue = 0; - } - std::shared_ptr i_ni( new IntegerNodeImpl( imf_, intValue, pi.minimum, pi.maximum ) ); - current_ni = i_ni; - } - break; - case E57_SCALED_INTEGER: - { - /// Convert child text (if any) to value, else default to 0.0 - int64_t intValue; - if ( pi.childText.length() > 0 ) - { - intValue = convertStrToLL( pi.childText ); - } - else - { - intValue = 0; - } - std::shared_ptr si_ni( - new ScaledIntegerNodeImpl( imf_, intValue, pi.minimum, pi.maximum, pi.scale, pi.offset ) ); - current_ni = si_ni; - } - break; - case E57_FLOAT: - { - /// Convert child text (if any) to value, else default to 0.0 - double floatValue; - if ( pi.childText.length() > 0 ) - { - floatValue = atof( pi.childText.c_str() ); - } - else - { - floatValue = 0.0; - } - std::shared_ptr f_ni( - new FloatNodeImpl( imf_, floatValue, pi.precision, pi.floatMinimum, pi.floatMaximum ) ); - current_ni = f_ni; - } - break; - case E57_STRING: - { - std::shared_ptr s_ni( new StringNodeImpl( imf_, pi.childText ) ); - current_ni = s_ni; - } - break; - case E57_BLOB: - { - std::shared_ptr b_ni( new BlobNodeImpl( imf_, pi.fileOffset, pi.length ) ); - current_ni = b_ni; - } - break; - default: - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "nodeType=" + toString( pi.nodeType ) + - " fileName=" + imf_->fileName() + " uri=" + toUString( uri ) + - " localName=" + toUString( localName ) + - " qName=" + toUString( qName ) ); - } -#ifdef E57_MAX_VERBOSE - current_ni->dump( 4 ); -#endif - - /// If first node in file ended, we are all done - if ( stack_.empty() ) - { - /// Top level should be Structure - if ( current_ni->type() != E57_STRUCTURE ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, - "currentType=" + toString( current_ni->type() ) + " fileName=" + imf_->fileName() + - " uri=" + toUString( uri ) + " localName=" + toUString( localName ) + - " qName=" + toUString( qName ) ); - } - imf_->root_ = std::static_pointer_cast( current_ni ); - return; - } - - /// Get next level up node (when entered function), which should be a - /// container. - NodeImplSharedPtr parent_ni = stack_.top().container_ni; - - if ( !parent_ni ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, "fileName=" + imf_->fileName() + " uri=" + toUString( uri ) + - " localName=" + toUString( localName ) + - " qName=" + toUString( qName ) ); - } - - /// Add current node into parent at top of stack - switch ( parent_ni->type() ) - { - case E57_STRUCTURE: - { - std::shared_ptr struct_ni = std::static_pointer_cast( parent_ni ); - - /// Add named child to structure - struct_ni->set( toUString( qName ), current_ni ); - } - break; - case E57_VECTOR: - { - std::shared_ptr vector_ni = std::static_pointer_cast( parent_ni ); - - /// Add unnamed child to vector - vector_ni->append( current_ni ); - } - break; - case E57_COMPRESSED_VECTOR: - { - std::shared_ptr cv_ni = - std::static_pointer_cast( parent_ni ); - ustring uQName = toUString( qName ); - - /// n can be either prototype or codecs - if ( uQName == "prototype" ) - { - cv_ni->setPrototype( current_ni ); - } - else if ( uQName == "codecs" ) - { - if ( current_ni->type() != E57_VECTOR ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, - "currentType=" + toString( current_ni->type() ) + " fileName=" + imf_->fileName() + - " uri=" + toUString( uri ) + " localName=" + toUString( localName ) + - " qName=" + toUString( qName ) ); - } - std::shared_ptr vi = std::static_pointer_cast( current_ni ); - - /// Check VectorNode is hetero - if ( !vi->allowHeteroChildren() ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, - "currentType=" + toString( current_ni->type() ) + " fileName=" + imf_->fileName() + - " uri=" + toUString( uri ) + " localName=" + toUString( localName ) + - " qName=" + toUString( qName ) ); - } - - cv_ni->setCodecs( vi ); - } - else - { - /// Found unknown XML child element of CompressedVector, not - /// prototype or codecs - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, - +"fileName=" + imf_->fileName() + " uri=" + toUString( uri ) + - " localName=" + toUString( localName ) + " qName=" + toUString( qName ) ); - } - } - break; - default: - /// Have bad XML nesting, parent should have been a container. - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, - "parentType=" + toString( parent_ni->type() ) + " fileName=" + imf_->fileName() + - " uri=" + toUString( uri ) + " localName=" + toUString( localName ) + - " qName=" + toUString( qName ) ); - } -} - -void E57XmlParser::characters( const XMLCh *const chars, const XMLSize_t length ) -{ - (void)length; -//??? use length to make ustring -#ifdef E57_MAX_VERBOSE - std::cout << "characters, chars=\"" << toUString( chars ) << "\" length=" << length << std::endl; -#endif - /// Get active element - ParseInfo &pi = stack_.top(); - - /// Check if child text is allowed for current E57 element type - switch ( pi.nodeType ) - { - case E57_STRUCTURE: - case E57_VECTOR: - case E57_COMPRESSED_VECTOR: - case E57_BLOB: - { - /// If characters aren't whitespace, have an error, else ignore - ustring s = toUString( chars ); - if ( s.find_first_not_of( " \t\n\r" ) != std::string::npos ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, "chars=" + toUString( chars ) ); - } - } - break; - default: - /// Append to any previous characters - pi.childText += toUString( chars ); - } -} - -void E57XmlParser::error( const SAXParseException &ex ) -{ - throw E57_EXCEPTION2( E57_ERROR_XML_PARSER, "systemId=" + ustring( XMLString::transcode( ex.getSystemId() ) ) + - " xmlLine=" + toString( ex.getLineNumber() ) + - " xmlColumn=" + toString( ex.getColumnNumber() ) + " parserMessage=" + - ustring( XMLString::transcode( ex.getMessage() ) ) ); -} - -void E57XmlParser::fatalError( const SAXParseException &ex ) -{ - throw E57_EXCEPTION2( E57_ERROR_XML_PARSER, "systemId=" + ustring( XMLString::transcode( ex.getSystemId() ) ) + - " xmlLine=" + toString( ex.getLineNumber() ) + - " xmlColumn=" + toString( ex.getColumnNumber() ) + " parserMessage=" + - ustring( XMLString::transcode( ex.getMessage() ) ) ); -} - -void E57XmlParser::warning( const SAXParseException &ex ) -{ - /// Don't take any action on warning from parser, just report - std::cerr << "**** XML parser warning: " << ustring( XMLString::transcode( ex.getMessage() ) ) << std::endl; - std::cerr << " Debug info:" << std::endl; - std::cerr << " systemId=" << XMLString::transcode( ex.getSystemId() ) << std::endl; - std::cerr << ", xmlLine=" << ex.getLineNumber() << std::endl; - std::cerr << ", xmlColumn=" << ex.getColumnNumber() << std::endl; -} - -ustring E57XmlParser::toUString( const XMLCh *const xml_str ) -{ - ustring u_str; - if ( xml_str && *xml_str ) - { - TranscodeToStr UTF8Transcoder( xml_str, "UTF-8" ); - u_str = ustring( reinterpret_cast( UTF8Transcoder.str() ) ); - } - return ( u_str ); -} - -ustring E57XmlParser::lookupAttribute( const Attributes &attributes, const XMLCh *attribute_name ) -{ - XMLSize_t attr_index; - if ( !attributes.getIndex( attribute_name, attr_index ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_XML_FORMAT, "attributeName=" + toUString( attribute_name ) ); - } - return ( toUString( attributes.getValue( attr_index ) ) ); -} - -bool E57XmlParser::isAttributeDefined( const Attributes &attributes, const XMLCh *attribute_name ) -{ - XMLSize_t attr_index; - return ( attributes.getIndex( attribute_name, attr_index ) ); -} diff --git a/src/3rdParty/libE57Format/src/E57XmlParser.h b/src/3rdParty/libE57Format/src/E57XmlParser.h deleted file mode 100644 index 910aef8fc1..0000000000 --- a/src/3rdParty/libE57Format/src/E57XmlParser.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include -#include - -#include -#include - -#include "Common.h" - -using namespace XERCES_CPP_NAMESPACE; - -namespace XERCES_CPP_NAMESPACE -{ - class SAX2XMLReader; -} - -namespace e57 -{ - class CheckedFile; - - class E57XmlParser : public DefaultHandler - { - public: - E57XmlParser( ImageFileImplSharedPtr imf ); - ~E57XmlParser() override; - - void init(); - - void parse( InputSource &inputSource ); - - private: - /// SAX interface - void startElement( const XMLCh *const uri, const XMLCh *const localName, const XMLCh *const qName, - const Attributes &attributes ) override; - void endElement( const XMLCh *const uri, const XMLCh *const localName, const XMLCh *const qName ) override; - void characters( const XMLCh *const chars, const XMLSize_t length ) override; - - /// SAX error interface - void warning( const SAXParseException &ex ) override; - void error( const SAXParseException &ex ) override; - void fatalError( const SAXParseException &ex ) override; - - ustring toUString( const XMLCh *const xml_str ); - ustring lookupAttribute( const Attributes &attributes, const XMLCh *attribute_name ); - bool isAttributeDefined( const Attributes &attributes, const XMLCh *attribute_name ); - - ImageFileImplSharedPtr imf_; /// Image file we are reading - - struct ParseInfo - { - /// All the fields need to remember while parsing the XML - /// Not all fields are used at same time, depends on node type - /// Needed because not all info is available at one time to create the - /// node. - NodeType nodeType; // used by all types - int64_t minimum; // used in E57_INTEGER, E57_SCALED_INTEGER - int64_t maximum; // used in E57_INTEGER, E57_SCALED_INTEGER - double scale; // used in E57_SCALED_INTEGER - double offset; // used in E57_SCALED_INTEGER - FloatPrecision precision; // used in E57_FLOAT - double floatMinimum; // used in E57_FLOAT - double floatMaximum; // used in E57_FLOAT - int64_t fileOffset; // used in E57_BLOB, E57_COMPRESSED_VECTOR - int64_t length; // used in E57_BLOB - bool allowHeterogeneousChildren; // used in E57_VECTOR - int64_t recordCount; // used in E57_COMPRESSED_VECTOR - ustring childText; // used by all types, accumulates all child text between tags - - /// Holds node for Structure, Vector, and CompressedVector so can append - /// child elements - NodeImplSharedPtr container_ni; - - ParseInfo(); // default ctor - void dump( int indent = 0, std::ostream &os = std::cout ) const; - }; - std::stack stack_; /// Stores the current path in tree we are reading - - SAX2XMLReader *xmlReader; - }; - - class E57XmlFileInputSource : public InputSource - { - public: - E57XmlFileInputSource( CheckedFile *cf, uint64_t logicalStart, uint64_t logicalLength ); - ~E57XmlFileInputSource() override = default; - - E57XmlFileInputSource( const E57XmlFileInputSource & ) = delete; - E57XmlFileInputSource &operator=( const E57XmlFileInputSource & ) = delete; - - BinInputStream *makeStream() const override; - - private: - //??? lifetime of cf_ must be longer than this object! - CheckedFile *cf_; - uint64_t logicalStart_; - uint64_t logicalLength_; - }; -} diff --git a/src/3rdParty/libE57Format/src/Encoder.cpp b/src/3rdParty/libE57Format/src/Encoder.cpp deleted file mode 100644 index a561643d36..0000000000 --- a/src/3rdParty/libE57Format/src/Encoder.cpp +++ /dev/null @@ -1,977 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include - -#include "CompressedVectorNodeImpl.h" -#include "Encoder.h" -#include "FloatNodeImpl.h" -#include "ImageFileImpl.h" -#include "IntegerNodeImpl.h" -#include "Packet.h" -#include "ScaledIntegerNodeImpl.h" -#include "SourceDestBufferImpl.h" - -using namespace e57; - -std::shared_ptr Encoder::EncoderFactory( unsigned bytestreamNumber, - std::shared_ptr cVector, - std::vector &sbufs, ustring & /*codecPath*/ ) -{ - //??? For now, only handle one input - if ( sbufs.size() != 1 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "sbufsSize=" + toString( sbufs.size() ) ); - } - - SourceDestBuffer sbuf = sbufs.at( 0 ); - - /// Get node we are going to encode from the CompressedVector's prototype - NodeImplSharedPtr prototype = cVector->getPrototype(); - ustring path = sbuf.pathName(); - NodeImplSharedPtr encodeNode = prototype->get( path ); - -#ifdef E57_MAX_VERBOSE - std::cout << "Node to encode:" << std::endl; //??? - encodeNode->dump( 2 ); -#endif - switch ( encodeNode->type() ) - { - case E57_INTEGER: - { - std::shared_ptr ini = - std::static_pointer_cast( encodeNode ); // downcast to correct type - - /// Get pointer to parent ImageFileImpl, to call bitsNeeded() - ImageFileImplSharedPtr imf( encodeNode->destImageFile_ ); //??? should be function for this, - // imf->parentFile() - //--> ImageFile? - - unsigned bitsPerRecord = imf->bitsNeeded( ini->minimum(), ini->maximum() ); - - //!!! need to pick smarter channel buffer sizes, here and elsewhere - /// Construct Integer encoder with appropriate register size, based on - /// number of bits stored. - if ( bitsPerRecord == 0 ) - { - std::shared_ptr encoder( new ConstantIntegerEncoder( bytestreamNumber, sbuf, ini->minimum() ) ); - - return encoder; - } - - if ( bitsPerRecord <= 8 ) - { - std::shared_ptr encoder( new BitpackIntegerEncoder( - false, bytestreamNumber, sbuf, DATA_PACKET_MAX /*!!!*/, ini->minimum(), ini->maximum(), 1.0, 0.0 ) ); - return encoder; - } - - if ( bitsPerRecord <= 16 ) - { - std::shared_ptr encoder( new BitpackIntegerEncoder( - false, bytestreamNumber, sbuf, DATA_PACKET_MAX /*!!!*/, ini->minimum(), ini->maximum(), 1.0, 0.0 ) ); - return encoder; - } - - if ( bitsPerRecord <= 32 ) - { - std::shared_ptr encoder( new BitpackIntegerEncoder( - false, bytestreamNumber, sbuf, DATA_PACKET_MAX /*!!!*/, ini->minimum(), ini->maximum(), 1.0, 0.0 ) ); - return encoder; - } - - std::shared_ptr encoder( new BitpackIntegerEncoder( - false, bytestreamNumber, sbuf, DATA_PACKET_MAX /*!!!*/, ini->minimum(), ini->maximum(), 1.0, 0.0 ) ); - return encoder; - } - - case E57_SCALED_INTEGER: - { - std::shared_ptr sini = - std::static_pointer_cast( encodeNode ); // downcast to correct type - - /// Get pointer to parent ImageFileImpl, to call bitsNeeded() - ImageFileImplSharedPtr imf( encodeNode->destImageFile_ ); //??? should be function for this, - // imf->parentFile() - //--> ImageFile? - - unsigned bitsPerRecord = imf->bitsNeeded( sini->minimum(), sini->maximum() ); - - //!!! need to pick smarter channel buffer sizes, here and elsewhere - /// Construct ScaledInteger encoder with appropriate register size, - /// based on number of bits stored. - if ( bitsPerRecord == 0 ) - { - std::shared_ptr encoder( new ConstantIntegerEncoder( bytestreamNumber, sbuf, sini->minimum() ) ); - - return encoder; - } - - if ( bitsPerRecord <= 8 ) - { - std::shared_ptr encoder( - new BitpackIntegerEncoder( true, bytestreamNumber, sbuf, DATA_PACKET_MAX /*!!!*/, - sini->minimum(), sini->maximum(), sini->scale(), sini->offset() ) ); - return encoder; - } - - if ( bitsPerRecord <= 16 ) - { - std::shared_ptr encoder( - new BitpackIntegerEncoder( true, bytestreamNumber, sbuf, DATA_PACKET_MAX /*!!!*/, - sini->minimum(), sini->maximum(), sini->scale(), sini->offset() ) ); - return encoder; - } - - if ( bitsPerRecord <= 32 ) - { - std::shared_ptr encoder( - new BitpackIntegerEncoder( true, bytestreamNumber, sbuf, DATA_PACKET_MAX /*!!!*/, - sini->minimum(), sini->maximum(), sini->scale(), sini->offset() ) ); - return encoder; - } - - std::shared_ptr encoder( - new BitpackIntegerEncoder( true, bytestreamNumber, sbuf, DATA_PACKET_MAX /*!!!*/, sini->minimum(), - sini->maximum(), sini->scale(), sini->offset() ) ); - return encoder; - } - - case E57_FLOAT: - { - std::shared_ptr fni = - std::static_pointer_cast( encodeNode ); // downcast to correct type - - //!!! need to pick smarter channel buffer sizes, here and elsewhere - std::shared_ptr encoder( - new BitpackFloatEncoder( bytestreamNumber, sbuf, DATA_PACKET_MAX /*!!!*/, fni->precision() ) ); - return encoder; - } - - case E57_STRING: - { - std::shared_ptr encoder( - new BitpackStringEncoder( bytestreamNumber, sbuf, DATA_PACKET_MAX /*!!!*/ ) ); - - return encoder; - } - - default: - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PROTOTYPE, "nodeType=" + toString( encodeNode->type() ) ); - } - } -} - -Encoder::Encoder( unsigned bytestreamNumber ) : bytestreamNumber_( bytestreamNumber ) -{ -} - -#ifdef E57_DEBUG -void Encoder::dump( int indent, std::ostream &os ) const -{ - os << space( indent ) << "bytestreamNumber: " << bytestreamNumber_ << std::endl; -} -#endif - -///================ - -BitpackEncoder::BitpackEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize, - unsigned alignmentSize ) : - Encoder( bytestreamNumber ), - sourceBuffer_( sbuf.impl() ), outBuffer_( outputMaxSize ), outBufferFirst_( 0 ), outBufferEnd_( 0 ), - outBufferAlignmentSize_( alignmentSize ), currentRecordIndex_( 0 ) -{ -} - -unsigned BitpackEncoder::sourceBufferNextIndex() -{ - return ( sourceBuffer_->nextIndex() ); -} - -uint64_t BitpackEncoder::currentRecordIndex() -{ - return ( currentRecordIndex_ ); -} - -size_t BitpackEncoder::outputAvailable() const -{ - return outBufferEnd_ - outBufferFirst_; -} - -void BitpackEncoder::outputRead( char *dest, const size_t byteCount ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "BitpackEncoder::outputRead() called, dest=" << dest << " byteCount=" << byteCount << std::endl; //??? -#endif - - /// Check we have enough bytes in queue - if ( byteCount > outputAvailable() ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "byteCount=" + toString( byteCount ) + - " outputAvailable=" + toString( outputAvailable() ) ); - } - - /// Copy output bytes to caller - memcpy( dest, &outBuffer_[outBufferFirst_], byteCount ); - -#ifdef E57_MAX_VERBOSE - { - unsigned i; - for ( i = 0; i < byteCount && i < 20; i++ ) - { - std::cout << " outBuffer[" << outBufferFirst_ + i - << "]=" << static_cast( static_cast( outBuffer_[outBufferFirst_ + i] ) ) - << std::endl; //??? - } - - if ( i < byteCount ) - { - std::cout << " " << byteCount - 1 << " bytes unprinted..." << std::endl; - } - } -#endif - - /// Advance head pointer. - outBufferFirst_ += byteCount; - - /// Don't slide remaining data down now, wait until do some more processing - /// (that's when data needs to be aligned). -} - -void BitpackEncoder::outputClear() -{ - outBufferFirst_ = 0; - outBufferEnd_ = 0; -} - -void BitpackEncoder::sourceBufferSetNew( std::vector &sbufs ) -{ - /// Verify that this encoder only has single input buffer - if ( sbufs.size() != 1 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "sbufsSize=" + toString( sbufs.size() ) ); - } - - sourceBuffer_ = sbufs.at( 0 ).impl(); -} - -size_t BitpackEncoder::outputGetMaxSize() -{ - /// Its size that matters here, not capacity - return ( outBuffer_.size() ); -} - -void BitpackEncoder::outputSetMaxSize( unsigned byteCount ) -{ - /// Ignore if trying to shrink buffer (queue might get messed up). - if ( byteCount > outBuffer_.size() ) - { - outBuffer_.resize( byteCount ); - } -} - -void BitpackEncoder::outBufferShiftDown() -{ - /// Move data down closer to beginning of outBuffer_. - /// But keep outBufferEnd_ as a multiple of outBufferAlignmentSize_. - /// This ensures that writes into buffer can occur on natural boundaries. - /// Otherwise some CPUs will fault. - - if ( outBufferFirst_ == outBufferEnd_ ) - { - /// Buffer is empty, reset indices to 0 - outBufferFirst_ = 0; - outBufferEnd_ = 0; - return; - } - - /// Round newEnd up to nearest multiple of outBufferAlignmentSize_. - size_t newEnd = outputAvailable(); - size_t remainder = newEnd % outBufferAlignmentSize_; - if ( remainder > 0 ) - { - newEnd += outBufferAlignmentSize_ - remainder; - } - size_t newFirst = outBufferFirst_ - ( outBufferEnd_ - newEnd ); - size_t byteCount = outBufferEnd_ - outBufferFirst_; - - /// Double check round up worked - if ( newEnd % outBufferAlignmentSize_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "newEnd=" + toString( newEnd ) + - " outBufferAlignmentSize=" + toString( outBufferAlignmentSize_ ) ); - } - - /// Be paranoid before memory copy - if ( newFirst + byteCount > outBuffer_.size() ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "newFirst=" + toString( newFirst ) + - " byteCount=" + toString( byteCount ) + - " outBufferSize=" + toString( outBuffer_.size() ) ); - } - - /// Move available data down closer to beginning of outBuffer_. Overlapping - /// regions ok with memmove(). - memmove( &outBuffer_[newFirst], &outBuffer_[outBufferFirst_], byteCount ); - - /// Update indexes - outBufferFirst_ = newFirst; - outBufferEnd_ = newEnd; -} - -#ifdef E57_DEBUG -void BitpackEncoder::dump( int indent, std::ostream &os ) const -{ - Encoder::dump( indent, os ); - os << space( indent ) << "sourceBuffer:" << std::endl; - sourceBuffer_->dump( indent + 4, os ); - os << space( indent ) << "outBuffer.size: " << outBuffer_.size() << std::endl; - os << space( indent ) << "outBufferFirst: " << outBufferFirst_ << std::endl; - os << space( indent ) << "outBufferEnd: " << outBufferEnd_ << std::endl; - os << space( indent ) << "outBufferAlignmentSize: " << outBufferAlignmentSize_ << std::endl; - os << space( indent ) << "currentRecordIndex: " << currentRecordIndex_ << std::endl; - os << space( indent ) << "outBuffer:" << std::endl; - unsigned i; - for ( i = 0; i < outBuffer_.size() && i < 20; i++ ) - { - os << space( indent + 4 ) << "outBuffer[" << i - << "]: " << static_cast( static_cast( outBuffer_.at( i ) ) ) << std::endl; - } - if ( i < outBuffer_.size() ) - { - os << space( indent + 4 ) << outBuffer_.size() - i << " more unprinted..." << std::endl; - } -} -#endif - -//================ - -BitpackFloatEncoder::BitpackFloatEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize, - FloatPrecision precision ) : - BitpackEncoder( bytestreamNumber, sbuf, outputMaxSize, - ( precision == E57_SINGLE ) ? sizeof( float ) : sizeof( double ) ), - precision_( precision ) -{ -} - -uint64_t BitpackFloatEncoder::processRecords( size_t recordCount ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << " BitpackFloatEncoder::processRecords() called, recordCount=" << recordCount << std::endl; //??? -#endif - - /// Before we add any more, try to shift current contents of outBuffer_ down - /// to beginning of buffer. This leaves outBufferEnd_ at a natural boundary. - outBufferShiftDown(); - - size_t typeSize = ( precision_ == E57_SINGLE ) ? sizeof( float ) : sizeof( double ); - -#ifdef E57_DEBUG - /// Verify that outBufferEnd_ is multiple of typeSize (so transfers of floats - /// are aligned naturally in memory). - if ( outBufferEnd_ % typeSize ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, - "outBufferEnd=" + toString( outBufferEnd_ ) + " typeSize=" + toString( typeSize ) ); - } -#endif - - /// Figure out how many records will fit in output. - size_t maxOutputRecords = ( outBuffer_.size() - outBufferEnd_ ) / typeSize; - - /// Can't process more records than will safely fit in output stream - if ( recordCount > maxOutputRecords ) - { - recordCount = maxOutputRecords; - } - - if ( precision_ == E57_SINGLE ) - { - /// Form the starting address for next available location in outBuffer - auto outp = reinterpret_cast( &outBuffer_[outBufferEnd_] ); - - /// Copy floats from sourceBuffer_ to outBuffer_ - for ( unsigned i = 0; i < recordCount; i++ ) - { - outp[i] = sourceBuffer_->getNextFloat(); -#ifdef E57_MAX_VERBOSE - std::cout << "encoding float: " << outp[i] << std::endl; -#endif - } - } - else - { /// E57_DOUBLE precision - /// Form the starting address for next available location in outBuffer - auto outp = reinterpret_cast( &outBuffer_[outBufferEnd_] ); - - /// Copy doubles from sourceBuffer_ to outBuffer_ - for ( unsigned i = 0; i < recordCount; i++ ) - { - outp[i] = sourceBuffer_->getNextDouble(); -#ifdef E57_MAX_VERBOSE - std::cout << "encoding double: " << outp[i] << std::endl; -#endif - } - } - - /// Update end of outBuffer - outBufferEnd_ += recordCount * typeSize; - - /// Update counts of records processed - currentRecordIndex_ += recordCount; - - return ( currentRecordIndex_ ); -} - -bool BitpackFloatEncoder::registerFlushToOutput() -{ - /// Since have no registers in encoder, return success - return ( true ); -} - -float BitpackFloatEncoder::bitsPerRecord() -{ - return ( ( precision_ == E57_SINGLE ) ? 32.0F : 64.0F ); -} - -#ifdef E57_DEBUG -void BitpackFloatEncoder::dump( int indent, std::ostream &os ) const -{ - BitpackEncoder::dump( indent, os ); - if ( precision_ == E57_SINGLE ) - { - os << space( indent ) << "precision: E57_SINGLE" << std::endl; - } - else - { - os << space( indent ) << "precision: E57_DOUBLE" << std::endl; - } -} -#endif - -//================ - -BitpackStringEncoder::BitpackStringEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, - unsigned outputMaxSize ) : - BitpackEncoder( bytestreamNumber, sbuf, outputMaxSize, 1 ), - totalBytesProcessed_( 0 ), isStringActive_( false ), prefixComplete_( false ), currentCharPosition_( 0 ) -{ -} - -uint64_t BitpackStringEncoder::processRecords( size_t recordCount ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << " BitpackStringEncoder::processRecords() called, recordCount=" << recordCount << std::endl; //??? -#endif - - /// Before we add any more, try to shift current contents of outBuffer_ down - /// to beginning of buffer. - outBufferShiftDown(); - - /// Figure out how many bytes outBuffer can accept. - size_t bytesFree = outBuffer_.size() - outBufferEnd_; - - /// Form the starting address for next available location in outBuffer - char *outp = &outBuffer_[outBufferEnd_]; - unsigned recordsProcessed = 0; - - /// Don't start loop unless have at least 8 bytes for worst case string - /// length prefix - while ( recordsProcessed < recordCount && bytesFree >= 8 ) - { //??? should be able to proceed if only 1 byte free - if ( isStringActive_ && !prefixComplete_ ) - { - /// Calc the length prefix, either 1 byte or 8 bytes - size_t len = currentString_.length(); - if ( len <= 127 ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "encoding short string: (len=" << len - << ") " - "" - << currentString_ - << "" - "" - << std::endl; -#endif - /// We can use the short length prefix: b0=0, b7-b1=len - auto lengthPrefix = static_cast( len << 1 ); - *outp++ = lengthPrefix; - bytesFree--; - } - else - { -#ifdef E57_DEBUG - /// Double check have space - if ( bytesFree < 8 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "bytesFree=" + toString( bytesFree ) ); - } -#endif -#ifdef E57_MAX_VERBOSE - std::cout << "encoding long string: (len=" << len - << ") " - "" - << currentString_ - << "" - "" - << std::endl; -#endif - /// We use the long length prefix: b0=1, b63-b1=len, and store in - /// little endian order Shift the length and set the least - /// significant bit, b0=1. - uint64_t lengthPrefix = ( static_cast( len ) << 1 ) | 1LL; - *outp++ = static_cast( lengthPrefix ); - *outp++ = static_cast( lengthPrefix >> ( 1 * 8 ) ); - *outp++ = static_cast( lengthPrefix >> ( 2 * 8 ) ); - *outp++ = static_cast( lengthPrefix >> ( 3 * 8 ) ); - *outp++ = static_cast( lengthPrefix >> ( 4 * 8 ) ); - *outp++ = static_cast( lengthPrefix >> ( 5 * 8 ) ); - *outp++ = static_cast( lengthPrefix >> ( 6 * 8 ) ); - *outp++ = static_cast( lengthPrefix >> ( 7 * 8 ) ); - bytesFree -= 8; - } - prefixComplete_ = true; - currentCharPosition_ = 0; - } - if ( isStringActive_ ) - { - /// Copy as much string as will fit in outBuffer - size_t bytesToProcess = std::min( currentString_.length() - currentCharPosition_, bytesFree ); - - for ( size_t i = 0; i < bytesToProcess; i++ ) - { - *outp++ = currentString_[currentCharPosition_ + i]; - } - - currentCharPosition_ += bytesToProcess; - totalBytesProcessed_ += bytesToProcess; - bytesFree -= bytesToProcess; - - /// Check if finished string - if ( currentCharPosition_ == currentString_.length() ) - { - isStringActive_ = false; - recordsProcessed++; - } - } - if ( !isStringActive_ && recordsProcessed < recordCount ) - { - /// Get next string from sourceBuffer - currentString_ = sourceBuffer_->getNextString(); - isStringActive_ = true; - prefixComplete_ = false; - currentCharPosition_ = 0; -#ifdef E57_MAX_VERBOSE - std::cout << "getting next string, length=" << currentString_.length() << std::endl; -#endif - } - } - - /// Update end of outBuffer - outBufferEnd_ = outBuffer_.size() - bytesFree; - - /// Update counts of records processed - currentRecordIndex_ += recordsProcessed; - - return ( currentRecordIndex_ ); -} - -bool BitpackStringEncoder::registerFlushToOutput() -{ - /// Since have no registers in encoder, return success - return ( true ); -} - -float BitpackStringEncoder::bitsPerRecord() -{ - /// Return average number of bits in strings + 8 bits for prefix - if ( currentRecordIndex_ > 0 ) - { - return ( 8.0f * totalBytesProcessed_ ) / currentRecordIndex_ + 8; - } - - /// We haven't completed a record yet, so guess 100 bytes per record - return 100 * 8.0f; -} - -#ifdef E57_DEBUG -void BitpackStringEncoder::dump( int indent, std::ostream &os ) const -{ - BitpackEncoder::dump( indent, os ); - os << space( indent ) << "totalBytesProcessed: " << totalBytesProcessed_ << std::endl; - os << space( indent ) << "isStringActive: " << isStringActive_ << std::endl; - os << space( indent ) << "prefixComplete: " << prefixComplete_ << std::endl; - os << space( indent ) << "currentString: " << currentString_ << std::endl; - os << space( indent ) << "currentCharPosition: " << currentCharPosition_ << std::endl; -} -#endif - -//================================================================ - -template -BitpackIntegerEncoder::BitpackIntegerEncoder( bool isScaledInteger, unsigned bytestreamNumber, - SourceDestBuffer &sbuf, unsigned outputMaxSize, - int64_t minimum, int64_t maximum, double scale, - double offset ) : - BitpackEncoder( bytestreamNumber, sbuf, outputMaxSize, sizeof( RegisterT ) ) -{ - /// Get pointer to parent ImageFileImpl - ImageFileImplSharedPtr imf( sbuf.impl()->destImageFile() ); //??? should be function for this, - // imf->parentFile() --> ImageFile? - - isScaledInteger_ = isScaledInteger; - minimum_ = minimum; - maximum_ = maximum; - scale_ = scale; - offset_ = offset; - bitsPerRecord_ = imf->bitsNeeded( minimum_, maximum_ ); - sourceBitMask_ = ( bitsPerRecord_ == 64 ) ? ~0 : ( 1ULL << bitsPerRecord_ ) - 1; - registerBitsUsed_ = 0; - register_ = 0; -} - -template uint64_t BitpackIntegerEncoder::processRecords( size_t recordCount ) -{ - //??? what are state guarantees if get an exception during transfer? -#ifdef E57_MAX_VERBOSE - std::cout << "BitpackIntegerEncoder::processRecords() called, sizeof(RegisterT)=" << sizeof( RegisterT ) - << " recordCount=" << recordCount << std::endl; - dump( 4 ); -#endif -#ifdef E57_MAX_DEBUG - /// Double check that register will hold at least one input records worth of - /// bits - if ( 8 * sizeof( RegisterT ) < bitsPerRecord_ ) - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "bitsPerRecord=" + toString( bitsPerRecord_ ) ); -#endif - - /// Before we add any more, try to shift current contents of outBuffer_ down - /// to beginning of buffer. This leaves outBufferEnd_ at a natural boundary. - outBufferShiftDown(); - -#ifdef E57_DEBUG - /// Verify that outBufferEnd_ is multiple of sizeof(RegisterT) (so transfers - /// of RegisterT are aligned naturally in memory). - if ( outBufferEnd_ % sizeof( RegisterT ) ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "outBufferEnd=" + toString( outBufferEnd_ ) ); - } - size_t transferMax = ( outBuffer_.size() - outBufferEnd_ ) / sizeof( RegisterT ); -#endif - - /// Precalculate exact maximum number of records that will fit in output - /// before overflow. - size_t outputWordCapacity = ( outBuffer_.size() - outBufferEnd_ ) / sizeof( RegisterT ); - size_t maxOutputRecords = - ( outputWordCapacity * 8 * sizeof( RegisterT ) + 8 * sizeof( RegisterT ) - registerBitsUsed_ - 1 ) / - bitsPerRecord_; - - /// Number of transfers is the smaller of what was requested and what will - /// fit. - recordCount = std::min( recordCount, maxOutputRecords ); -#ifdef E57_MAX_VERBOSE - std::cout << " outputWordCapacity=" << outputWordCapacity << " maxOutputRecords=" << maxOutputRecords - << " recordCount=" << recordCount << std::endl; -#endif - - /// Form the starting address for next available location in outBuffer - auto outp = reinterpret_cast( &outBuffer_[outBufferEnd_] ); - unsigned outTransferred = 0; - - /// Copy bits from sourceBuffer_ to outBuffer_ - for ( unsigned i = 0; i < recordCount; i++ ) - { - int64_t rawValue; - - /// The parameter isScaledInteger_ determines which version of - /// getNextInt64 gets called - if ( isScaledInteger_ ) - { - rawValue = sourceBuffer_->getNextInt64( scale_, offset_ ); - } - else - { - rawValue = sourceBuffer_->getNextInt64(); - } - - /// Enforce min/max specification on value - if ( rawValue < minimum_ || maximum_ < rawValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_OUT_OF_BOUNDS, "rawValue=" + toString( rawValue ) + - " minimum=" + toString( minimum_ ) + - " maximum=" + toString( maximum_ ) ); - } - - auto uValue = static_cast( rawValue - minimum_ ); - -#ifdef E57_MAX_VERBOSE - std::cout << "encoding integer rawValue=" << binaryString( rawValue ) << " = " << hexString( rawValue ) - << std::endl; - std::cout << " uValue =" << binaryString( uValue ) << " = " << hexString( uValue ) << std::endl; -#endif -#ifdef E57_DEBUG - /// Double check that no bits outside of the mask are set - if ( uValue & ~static_cast( sourceBitMask_ ) ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "uValue=" + toString( uValue ) ); - } -#endif - /// Mask off upper bits (just in case) - uValue &= static_cast( sourceBitMask_ ); - - /// See if uValue bits will fit in register - unsigned newRegisterBitsUsed = registerBitsUsed_ + bitsPerRecord_; -#ifdef E57_MAX_VERBOSE - std::cout << " registerBitsUsed=" << registerBitsUsed_ << " newRegisterBitsUsed=" << newRegisterBitsUsed - << std::endl; -#endif - if ( newRegisterBitsUsed > 8 * sizeof( RegisterT ) ) - { - /// Have more than one registers worth, fill register, transfer, then - /// fill some more - register_ |= static_cast( uValue ) << registerBitsUsed_; -#ifdef E57_DEBUG - /// Before transfer, double check address within bounds - if ( outTransferred >= transferMax ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "outTransferred=" + toString( outTransferred ) + " transferMax" + - toString( transferMax ) ); - } -#endif - outp[outTransferred] = register_; - - outTransferred++; - - register_ = static_cast( uValue ) >> ( 8 * sizeof( RegisterT ) - registerBitsUsed_ ); - registerBitsUsed_ = newRegisterBitsUsed - 8 * sizeof( RegisterT ); - } - else if ( newRegisterBitsUsed == 8 * sizeof( RegisterT ) ) - { - /// Input will exactly fill register, insert value, then transfer - register_ |= static_cast( uValue ) << registerBitsUsed_; -#ifdef E57_DEBUG - /// Before transfer, double check address within bounds - if ( outTransferred >= transferMax ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "outTransferred=" + toString( outTransferred ) + " transferMax" + - toString( transferMax ) ); - } -#endif - outp[outTransferred] = register_; - - outTransferred++; - - register_ = 0; - registerBitsUsed_ = 0; - } - else - { - /// There is extra room in register, insert value, but don't do - /// transfer yet - register_ |= static_cast( uValue ) << registerBitsUsed_; - registerBitsUsed_ = newRegisterBitsUsed; - } -#ifdef E57_MAX_VERBOSE - std::cout << " After " << outTransferred << " transfers and " << i + 1 << " records, encoder:" << std::endl; - dump( 4 ); -#endif - } - - /// Update tail of output buffer - outBufferEnd_ += outTransferred * sizeof( RegisterT ); -#ifdef E57_DEBUG - /// Double check end is ok - if ( outBufferEnd_ > outBuffer_.size() ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "outBufferEnd=" + toString( outBufferEnd_ ) + - " outBuffersize=" + toString( outBuffer_.size() ) ); - } -#endif - - /// Update counts of records processed - currentRecordIndex_ += recordCount; - - return ( currentRecordIndex_ ); -} - -template bool BitpackIntegerEncoder::registerFlushToOutput() -{ -#ifdef E57_MAX_VERBOSE - std::cout << "BitpackIntegerEncoder::registerFlushToOutput() called, " - "sizeof(RegisterT)=" - << sizeof( RegisterT ) << std::endl; - dump( 4 ); -#endif - /// If have any used bits in register, transfer to output, padded in MSBits - /// with zeros to RegisterT boundary - if ( registerBitsUsed_ > 0 ) - { - if ( outBufferEnd_ < outBuffer_.size() - sizeof( RegisterT ) ) - { - auto outp = reinterpret_cast( &outBuffer_[outBufferEnd_] ); - *outp = register_; - register_ = 0; - registerBitsUsed_ = 0; - outBufferEnd_ += sizeof( RegisterT ); - return true; // flush succeeded ??? is this used? correctly? - } - - return false; // flush didn't complete (not enough room). - } - - return true; -} - -template float BitpackIntegerEncoder::bitsPerRecord() -{ - return ( static_cast( bitsPerRecord_ ) ); -} - -#ifdef E57_DEBUG -template void BitpackIntegerEncoder::dump( int indent, std::ostream &os ) const -{ - BitpackEncoder::dump( indent, os ); - os << space( indent ) << "isScaledInteger: " << isScaledInteger_ << std::endl; - os << space( indent ) << "minimum: " << minimum_ << std::endl; - os << space( indent ) << "maximum: " << maximum_ << std::endl; - os << space( indent ) << "scale: " << scale_ << std::endl; - os << space( indent ) << "offset: " << offset_ << std::endl; - os << space( indent ) << "bitsPerRecord: " << bitsPerRecord_ << std::endl; - os << space( indent ) << "sourceBitMask: " << binaryString( sourceBitMask_ ) << " " << hexString( sourceBitMask_ ) - << std::endl; - os << space( indent ) << "register: " << binaryString( register_ ) << " " << hexString( register_ ) - << std::endl; - os << space( indent ) << "registerBitsUsed: " << registerBitsUsed_ << std::endl; -} -#endif - -//================================================================ - -ConstantIntegerEncoder::ConstantIntegerEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, int64_t minimum ) : - Encoder( bytestreamNumber ), sourceBuffer_( sbuf.impl() ), currentRecordIndex_( 0 ), minimum_( minimum ) -{ -} - -uint64_t ConstantIntegerEncoder::processRecords( size_t recordCount ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "ConstantIntegerEncoder::processRecords() called, recordCount=" << recordCount << std::endl; - dump( 4 ); -#endif - - /// Check that all source values are == minimum_ - for ( unsigned i = 0; i < recordCount; i++ ) - { - int64_t nextInt64 = sourceBuffer_->getNextInt64(); - if ( nextInt64 != minimum_ ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_OUT_OF_BOUNDS, - "nextInt64=" + toString( nextInt64 ) + " minimum=" + toString( minimum_ ) ); - } - } - - /// Update counts of records processed - currentRecordIndex_ += recordCount; - - return ( currentRecordIndex_ ); -} - -unsigned ConstantIntegerEncoder::sourceBufferNextIndex() -{ - return ( sourceBuffer_->nextIndex() ); -} - -uint64_t ConstantIntegerEncoder::currentRecordIndex() -{ - return ( currentRecordIndex_ ); -} - -float ConstantIntegerEncoder::bitsPerRecord() -{ - /// We don't produce any output - return ( 0.0 ); -} - -bool ConstantIntegerEncoder::registerFlushToOutput() -{ - return ( true ); -} - -size_t ConstantIntegerEncoder::outputAvailable() const -{ - /// We don't produce any output - return 0; -} - -void ConstantIntegerEncoder::outputRead( char * /*dest*/, const size_t byteCount ) -{ - /// Should never request any output data - if ( byteCount > 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "byteCount=" + toString( byteCount ) ); - } -} - -void ConstantIntegerEncoder::outputClear() -{ -} - -void ConstantIntegerEncoder::sourceBufferSetNew( std::vector &sbufs ) -{ - /// Verify that this encoder only has single input buffer - if ( sbufs.size() != 1 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "sbufsSize=" + toString( sbufs.size() ) ); - } - - sourceBuffer_ = sbufs.at( 0 ).impl(); -} - -size_t ConstantIntegerEncoder::outputGetMaxSize() -{ - /// We don't produce any output - return ( 0 ); -} - -void ConstantIntegerEncoder::outputSetMaxSize( unsigned /*byteCount*/ ) -{ - /// Ignore, since don't produce any output -} - -#ifdef E57_DEBUG -void ConstantIntegerEncoder::dump( int indent, std::ostream &os ) const -{ - Encoder::dump( indent, os ); - os << space( indent ) << "currentRecordIndex: " << currentRecordIndex_ << std::endl; - os << space( indent ) << "minimum: " << minimum_ << std::endl; - os << space( indent ) << "sourceBuffer:" << std::endl; - sourceBuffer_->dump( indent + 4, os ); -} -#endif diff --git a/src/3rdParty/libE57Format/src/Encoder.h b/src/3rdParty/libE57Format/src/Encoder.h deleted file mode 100644 index 5bcea0c01e..0000000000 --- a/src/3rdParty/libE57Format/src/Encoder.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include "Common.h" - -namespace e57 -{ - class Encoder - { - public: - static std::shared_ptr EncoderFactory( unsigned bytestreamNumber, - std::shared_ptr cVector, - std::vector &sbuf, ustring &codecPath ); - - virtual ~Encoder() = default; - - virtual uint64_t processRecords( size_t recordCount ) = 0; - virtual unsigned sourceBufferNextIndex() = 0; - virtual uint64_t currentRecordIndex() = 0; - virtual float bitsPerRecord() = 0; - virtual bool registerFlushToOutput() = 0; - - virtual size_t outputAvailable() const = 0; /// number of bytes that can be read - virtual void outputRead( char *dest, const size_t byteCount ) = 0; /// get data from encoder - virtual void outputClear() = 0; - - virtual void sourceBufferSetNew( std::vector &sbufs ) = 0; - virtual size_t outputGetMaxSize() = 0; - virtual void outputSetMaxSize( unsigned byteCount ) = 0; - - unsigned bytestreamNumber() const - { - return bytestreamNumber_; - } - -#ifdef E57_DEBUG - virtual void dump( int indent = 0, std::ostream &os = std::cout ) const; -#endif - protected: - Encoder( unsigned bytestreamNumber ); - - unsigned bytestreamNumber_; - }; - - class BitpackEncoder : public Encoder - { - public: - uint64_t processRecords( size_t recordCount ) override = 0; - unsigned sourceBufferNextIndex() override; - uint64_t currentRecordIndex() override; - float bitsPerRecord() override = 0; - bool registerFlushToOutput() override = 0; - - size_t outputAvailable() const override; /// number of bytes that can be read - void outputRead( char *dest, - const size_t byteCount ) override; /// get data from encoder - void outputClear() override; - - void sourceBufferSetNew( std::vector &sbufs ) override; - size_t outputGetMaxSize() override; - void outputSetMaxSize( unsigned byteCount ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - protected: - BitpackEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize, - unsigned alignmentSize ); - - void outBufferShiftDown(); - - std::shared_ptr sourceBuffer_; - - std::vector outBuffer_; - size_t outBufferFirst_; - size_t outBufferEnd_; - size_t outBufferAlignmentSize_; - - uint64_t currentRecordIndex_; - }; - - class BitpackFloatEncoder : public BitpackEncoder - { - public: - BitpackFloatEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize, - FloatPrecision precision ); - - uint64_t processRecords( size_t recordCount ) override; - bool registerFlushToOutput() override; - float bitsPerRecord() override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - protected: - FloatPrecision precision_; - }; - - class BitpackStringEncoder : public BitpackEncoder - { - public: - BitpackStringEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize ); - - uint64_t processRecords( size_t recordCount ) override; - bool registerFlushToOutput() override; - float bitsPerRecord() override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - protected: - uint64_t totalBytesProcessed_; - bool isStringActive_; - bool prefixComplete_; - ustring currentString_; - size_t currentCharPosition_; - }; - - template class BitpackIntegerEncoder : public BitpackEncoder - { - public: - BitpackIntegerEncoder( bool isScaledInteger, unsigned bytestreamNumber, SourceDestBuffer &sbuf, - unsigned outputMaxSize, int64_t minimum, int64_t maximum, double scale, double offset ); - - uint64_t processRecords( size_t recordCount ) override; - bool registerFlushToOutput() override; - float bitsPerRecord() override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - protected: - bool isScaledInteger_; - int64_t minimum_; - int64_t maximum_; - double scale_; - double offset_; - unsigned bitsPerRecord_; - uint64_t sourceBitMask_; - unsigned registerBitsUsed_; - RegisterT register_; - }; - - class ConstantIntegerEncoder : public Encoder - { - public: - ConstantIntegerEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, int64_t minimum ); - uint64_t processRecords( size_t recordCount ) override; - unsigned sourceBufferNextIndex() override; - uint64_t currentRecordIndex() override; - float bitsPerRecord() override; - bool registerFlushToOutput() override; - - size_t outputAvailable() const override; /// number of bytes that can be read - void outputRead( char *dest, - const size_t byteCount ) override; /// get data from encoder - void outputClear() override; - - void sourceBufferSetNew( std::vector &sbufs ) override; - size_t outputGetMaxSize() override; - void outputSetMaxSize( unsigned byteCount ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - protected: - std::shared_ptr sourceBuffer_; - uint64_t currentRecordIndex_; - int64_t minimum_; - }; -} diff --git a/src/3rdParty/libE57Format/src/FloatNodeImpl.cpp b/src/3rdParty/libE57Format/src/FloatNodeImpl.cpp deleted file mode 100644 index 7bdb15fa45..0000000000 --- a/src/3rdParty/libE57Format/src/FloatNodeImpl.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "FloatNodeImpl.h" -#include "CheckedFile.h" - -namespace e57 -{ - FloatNodeImpl::FloatNodeImpl( ImageFileImplWeakPtr destImageFile, double value, FloatPrecision precision, - double minimum, double maximum ) : - NodeImpl( destImageFile ), - value_( value ), precision_( precision ), minimum_( minimum ), maximum_( maximum ) - { - // don't checkImageFileOpen, NodeImpl() will do it - - /// Since this ctor also used to construct single precision, and defaults for - /// minimum/maximum are for double precision, adjust bounds smaller if - /// single. - if ( precision_ == E57_SINGLE ) - { - if ( minimum_ < E57_FLOAT_MIN ) - { - minimum_ = E57_FLOAT_MIN; - } - if ( maximum_ > E57_FLOAT_MAX ) - { - maximum_ = E57_FLOAT_MAX; - } - } - - /// Enforce the given bounds on raw value - if ( value < minimum || maximum < value ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_OUT_OF_BOUNDS, - "this->pathName=" + this->pathName() + " value=" + toString( value ) + - " minimum=" + toString( minimum ) + " maximum=" + toString( maximum ) ); - } - } - - bool FloatNodeImpl::isTypeEquivalent( NodeImplSharedPtr ni ) - { - // don't checkImageFileOpen - - /// Same node type? - if ( ni->type() != E57_FLOAT ) - { - return ( false ); - } - - /// Downcast to shared_ptr - std::shared_ptr fi( std::static_pointer_cast( ni ) ); - - /// precision must match - if ( precision_ != fi->precision_ ) - { - return ( false ); - } - - /// minimum must match - if ( minimum_ != fi->minimum_ ) - { - return ( false ); - } - - /// maximum must match - if ( maximum_ != fi->maximum_ ) - { - return ( false ); - } - - /// ignore value_, doesn't have to match - - /// Types match - return ( true ); - } - - bool FloatNodeImpl::isDefined( const ustring &pathName ) - { - // don't checkImageFileOpen - - /// We have no sub-structure, so if path not empty return false - return pathName.empty(); - } - - double FloatNodeImpl::value() const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return value_; - } - - FloatPrecision FloatNodeImpl::precision() const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return precision_; - } - - double FloatNodeImpl::minimum() const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return minimum_; - } - - double FloatNodeImpl::maximum() const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return maximum_; - } - - void FloatNodeImpl::checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) - { - // don't checkImageFileOpen - - /// We are a leaf node, so verify that we are listed in set (either relative - /// or absolute form) - if ( pathNames.find( relativePathName( origin ) ) == pathNames.end() && - pathNames.find( pathName() ) == pathNames.end() ) - { - throw E57_EXCEPTION2( E57_ERROR_NO_BUFFER_FOR_ELEMENT, "this->pathName=" + this->pathName() ); - } - } - - void FloatNodeImpl::writeXml( ImageFileImplSharedPtr /*imf*/, CheckedFile &cf, int indent, - const char *forcedFieldName ) - { - // don't checkImageFileOpen - - ustring fieldName; - if ( forcedFieldName ) - { - fieldName = forcedFieldName; - } - else - { - fieldName = elementName_; - } - - cf << space( indent ) << "<" << fieldName << " type=\"Float\""; - if ( precision_ == E57_SINGLE ) - { - cf << " precision=\"single\""; - - /// Don't need to write if are default values - if ( minimum_ > E57_FLOAT_MIN ) - { - cf << " minimum=\"" << static_cast( minimum_ ) << "\""; - } - if ( maximum_ < E57_FLOAT_MAX ) - { - cf << " maximum=\"" << static_cast( maximum_ ) << "\""; - } - - /// Write value as child text, unless it is the default value - if ( value_ != 0.0 ) - { - cf << ">" << static_cast( value_ ) << "\n"; - } - else - { - cf << "/>\n"; - } - } - else - { - /// Don't need to write precision="double", because that's the default - - /// Don't need to write if are default values - if ( minimum_ > E57_DOUBLE_MIN ) - { - cf << " minimum=\"" << minimum_ << "\""; - } - if ( maximum_ < E57_DOUBLE_MAX ) - { - cf << " maximum=\"" << maximum_ << "\""; - } - - /// Write value as child text, unless it is the default value - if ( value_ != 0.0 ) - { - cf << ">" << value_ << "\n"; - } - else - { - cf << "/>\n"; - } - } - } - -#ifdef E57_DEBUG - void FloatNodeImpl::dump( int indent, std::ostream &os ) const - { - // don't checkImageFileOpen - os << space( indent ) << "type: Float" - << " (" << type() << ")" << std::endl; - NodeImpl::dump( indent, os ); - os << space( indent ) << "precision: "; - if ( precision() == E57_SINGLE ) - { - os << "single" << std::endl; - } - else - { - os << "double" << std::endl; - } - - /// Save old stream config - const std::streamsize oldPrecision = os.precision(); - const std::ios_base::fmtflags oldFlags = os.flags(); - - os << space( indent ) << std::scientific << std::setprecision( 17 ) << "value: " << value_ << std::endl; - os << space( indent ) << "minimum: " << minimum_ << std::endl; - os << space( indent ) << "maximum: " << maximum_ << std::endl; - - /// Restore old stream config - os.precision( oldPrecision ); - os.flags( oldFlags ); - } -#endif -} diff --git a/src/3rdParty/libE57Format/src/FloatNodeImpl.h b/src/3rdParty/libE57Format/src/FloatNodeImpl.h deleted file mode 100644 index 67b0be5d34..0000000000 --- a/src/3rdParty/libE57Format/src/FloatNodeImpl.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "NodeImpl.h" - -namespace e57 -{ - class FloatNodeImpl : public NodeImpl - { - public: - FloatNodeImpl( ImageFileImplWeakPtr destImageFile, double value = 0, FloatPrecision precision = E57_DOUBLE, - double minimum = E57_DOUBLE_MIN, double maximum = E57_DOUBLE_MAX ); - ~FloatNodeImpl() override = default; - - NodeType type() const override - { - return E57_FLOAT; - } - bool isTypeEquivalent( NodeImplSharedPtr ni ) override; - bool isDefined( const ustring &pathName ) override; - - double value() const; - FloatPrecision precision() const; - double minimum() const; - double maximum() const; - - void checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) override; - - void writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, - const char *forcedFieldName = nullptr ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - - private: - double value_; - FloatPrecision precision_; - double minimum_; - double maximum_; - }; -} diff --git a/src/3rdParty/libE57Format/src/ImageFileImpl.cpp b/src/3rdParty/libE57Format/src/ImageFileImpl.cpp deleted file mode 100644 index fbc9c5924e..0000000000 --- a/src/3rdParty/libE57Format/src/ImageFileImpl.cpp +++ /dev/null @@ -1,945 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "ImageFileImpl.h" -#include "CheckedFile.h" -#include "E57Version.h" -#include "E57XmlParser.h" -#include "StructureNodeImpl.h" - -namespace e57 -{ - struct NameSpace - { - ustring prefix; - ustring uri; - - NameSpace( const ustring &prefix0, const ustring &uri0 ) : prefix( prefix0 ), uri( uri0 ) - { - } - }; - - struct E57FileHeader - { - char fileSignature[8] = {}; - uint32_t majorVersion = 0; - uint32_t minorVersion = 0; - uint64_t filePhysicalLength = 0; - uint64_t xmlPhysicalOffset = 0; - uint64_t xmlLogicalLength = 0; - uint64_t pageSize = 0; - // char e57LibraryVersion[8]; //Not in V1.0 Standard - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const; -#endif - }; - -#ifdef E57_DEBUG - void E57FileHeader::dump( int indent, std::ostream &os ) const - { - os << space( indent ) << "fileSignature: "; - os.write( fileSignature, sizeof( fileSignature ) ); - os << std::endl; - os << space( indent ) << "majorVersion: " << majorVersion << std::endl; - os << space( indent ) << "minorVersion: " << minorVersion << std::endl; - os << space( indent ) << "filePhysicalLength: " << filePhysicalLength << std::endl; - os << space( indent ) << "xmlPhysicalOffset: " << xmlPhysicalOffset << std::endl; - os << space( indent ) << "xmlLogicalLength: " << xmlLogicalLength << std::endl; - os << space( indent ) << "pageSize: " << pageSize << std::endl; - } -#endif - - ImageFileImpl::ImageFileImpl( ReadChecksumPolicy policy ) : - isWriter_( false ), writerCount_( 0 ), readerCount_( 0 ), - checksumPolicy( std::max( 0, std::min( policy, 100 ) ) ), file_( nullptr ), xmlLogicalOffset_( 0 ), - xmlLogicalLength_( 0 ), unusedLogicalStart_( 0 ) - { - /// First phase of construction, can't do much until have the ImageFile - /// object. See ImageFileImpl::construct2() for second phase. - } - - void ImageFileImpl::construct2( const ustring &fileName, const ustring &mode ) - { - /// Second phase of construction, now we have a well-formed ImageFile object. - -#ifdef E57_MAX_VERBOSE - std::cout << "ImageFileImpl() called, fileName=" << fileName << " mode=" << mode << std::endl; -#endif - unusedLogicalStart_ = sizeof( E57FileHeader ); - fileName_ = fileName; - - /// Get shared_ptr to this object - ImageFileImplSharedPtr imf = shared_from_this(); - - // Accept "w" or "r" modes - isWriter_ = ( mode == "w" ); - - if ( !isWriter_ && ( mode != "r" ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_API_ARGUMENT, "mode=" + ustring( mode ) ); - } - - file_ = nullptr; - - // Writing - if ( isWriter_ ) - { - try - { - /// Open file for writing, truncate if already exists. - file_ = new CheckedFile( fileName_, CheckedFile::WriteCreate, checksumPolicy ); - - std::shared_ptr root( new StructureNodeImpl( imf ) ); - root_ = root; - root_->setAttachedRecursive(); - - unusedLogicalStart_ = sizeof( E57FileHeader ); - xmlLogicalOffset_ = 0; - xmlLogicalLength_ = 0; - } - catch ( ... ) - { - delete file_; - file_ = nullptr; - - throw; - } - - return; - } - - // Reading - try - { - /// Open file for reading. - file_ = new CheckedFile( fileName_, CheckedFile::ReadOnly, checksumPolicy ); - - std::shared_ptr root( new StructureNodeImpl( imf ) ); - root_ = root; - root_->setAttachedRecursive(); - - E57FileHeader header; - readFileHeader( file_, header ); - - xmlLogicalOffset_ = file_->physicalToLogical( header.xmlPhysicalOffset ); - xmlLogicalLength_ = header.xmlLogicalLength; - } - catch ( ... ) - { - delete file_; - file_ = nullptr; - - throw; - } - - try - { - /// Create parser state, attach its event handers to the SAX2 reader - E57XmlParser parser( imf ); - - parser.init(); - - /// Create input source (XML section of E57 file turned into a stream). - E57XmlFileInputSource xmlSection( file_, xmlLogicalOffset_, xmlLogicalLength_ ); - - unusedLogicalStart_ = sizeof( E57FileHeader ); - - /// Do the parse, building up the node tree - parser.parse( xmlSection ); - } - catch ( ... ) - { - delete file_; - file_ = nullptr; - - throw; - } - } - - void ImageFileImpl::construct2( const char *input, const uint64_t size ) - { - /// Second phase of construction, now we have a well-formed ImageFile object. - -#ifdef E57_MAX_VERBOSE - std::cout << "ImageFileImpl() called, fileName= mode=r" << std::endl; -#endif - unusedLogicalStart_ = sizeof( E57FileHeader ); - fileName_ = ""; - - /// Get shared_ptr to this object - ImageFileImplSharedPtr imf = shared_from_this(); - - isWriter_ = false; - file_ = nullptr; - - try - { - /// Open file for reading. - file_ = new CheckedFile( input, size, checksumPolicy ); - - std::shared_ptr root( new StructureNodeImpl( imf ) ); - root_ = root; - root_->setAttachedRecursive(); - - E57FileHeader header; - readFileHeader( file_, header ); - - xmlLogicalOffset_ = file_->physicalToLogical( header.xmlPhysicalOffset ); - xmlLogicalLength_ = header.xmlLogicalLength; - } - catch ( ... ) - { - delete file_; - file_ = nullptr; - - throw; - } - - try - { - /// Create parser state, attach its event handers to the SAX2 reader - E57XmlParser parser( imf ); - - parser.init(); - - /// Create input source (XML section of E57 file turned into a stream). - E57XmlFileInputSource xmlSection( file_, xmlLogicalOffset_, xmlLogicalLength_ ); - - unusedLogicalStart_ = sizeof( E57FileHeader ); - - /// Do the parse, building up the node tree - parser.parse( xmlSection ); - } - catch ( ... ) - { - delete file_; - file_ = nullptr; - - throw; - } - } - - void ImageFileImpl::incrWriterCount() - { - writerCount_++; - } - - void ImageFileImpl::decrWriterCount() - { - writerCount_--; -#ifdef E57_MAX_DEBUG - if ( writerCount_ < 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "fileName=" + fileName_ + - " writerCount=" + toString( writerCount_ ) + - " readerCount=" + toString( readerCount_ ) ); - } -#endif - } - - void ImageFileImpl::incrReaderCount() - { - readerCount_++; - } - - void ImageFileImpl::decrReaderCount() - { - readerCount_--; -#ifdef E57_MAX_DEBUG - if ( readerCount_ < 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "fileName=" + fileName_ + - " writerCount=" + toString( writerCount_ ) + - " readerCount=" + toString( readerCount_ ) ); - } -#endif - } - - std::shared_ptr ImageFileImpl::root() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - return root_; - } - - void ImageFileImpl::close() - { - /// If file already closed, have nothing to do - if ( !file_ ) - { - return; - } - - if ( isWriter_ ) - { - /// Go to end of file, note physical position - xmlLogicalOffset_ = unusedLogicalStart_; - file_->seek( xmlLogicalOffset_, CheckedFile::Logical ); - uint64_t xmlPhysicalOffset = file_->position( CheckedFile::Physical ); - *file_ << "\n"; -#ifdef E57_OXYGEN_SUPPORT /*//??? \ - //??? *file_ << "\n";*/ -#endif - - //??? need to add name space attributes to e57Root - root_->writeXml( shared_from_this(), *file_, 0, "e57Root" ); - - /// Pad XML section so length is multiple of 4 - while ( ( file_->position( CheckedFile::Logical ) - xmlLogicalOffset_ ) % 4 != 0 ) - { - *file_ << " "; - } - - /// Note logical length - xmlLogicalLength_ = file_->position( CheckedFile::Logical ) - xmlLogicalOffset_; - - /// Init header contents - E57FileHeader header; - - memcpy( &header.fileSignature, "ASTM-E57", 8 ); - - header.majorVersion = E57_FORMAT_MAJOR; - header.minorVersion = E57_FORMAT_MINOR; - header.filePhysicalLength = file_->length( CheckedFile::Physical ); - header.xmlPhysicalOffset = xmlPhysicalOffset; - header.xmlLogicalLength = xmlLogicalLength_; - header.pageSize = CheckedFile::physicalPageSize; -#ifdef E57_MAX_VERBOSE - header.dump(); -#endif - - /// Write header at beginning of file - file_->seek( 0 ); - file_->write( reinterpret_cast( &header ), sizeof( header ) ); - - file_->close(); - } - - delete file_; - file_ = nullptr; - } - - void ImageFileImpl::cancel() - { - /// If file already closed, have nothing to do - if ( !file_ ) - { - return; - } - - /// Close the file and ulink (delete) it. - /// It is legal to cancel a read file, but file isn't deleted. - if ( isWriter_ ) - { - file_->unlink(); - } - else - { - file_->close(); - } - - delete file_; - file_ = nullptr; - } - - bool ImageFileImpl::isOpen() const - { - return ( file_ != nullptr ); - } - - bool ImageFileImpl::isWriter() const - { - return isWriter_; - } - - int ImageFileImpl::writerCount() const - { - return writerCount_; - } - - int ImageFileImpl::readerCount() const - { - return readerCount_; - } - - ImageFileImpl::~ImageFileImpl() - { - /// Try to cancel if not already closed, but don't allow any exceptions to - /// propagate to caller (because in dtor). If writing, this will unlink the - /// file, so make sure call ImageFileImpl::close explicitly before dtor runs. - try - { - cancel(); - } - catch ( ... ) - { - }; - - /// Just in case cancel failed without freeing file_, do free here. - delete file_; - file_ = nullptr; - } - - uint64_t ImageFileImpl::allocateSpace( uint64_t byteCount, bool doExtendNow ) - { - uint64_t oldLogicalStart = unusedLogicalStart_; - - /// Reserve space at end of file - unusedLogicalStart_ += byteCount; - - /// If caller won't write to file immediately, it should request that the - /// file be extended with zeros here - if ( doExtendNow ) - { - file_->extend( unusedLogicalStart_ ); - } - - return oldLogicalStart; - } - - CheckedFile *ImageFileImpl::file() const - { - return file_; - } - - ustring ImageFileImpl::fileName() const - { - // don't checkImageFileOpen, since need to get fileName to report not open - return fileName_; - } - - void ImageFileImpl::extensionsAdd( const ustring &prefix, const ustring &uri ) - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - //??? check if prefix characters ok, check if uri has a double quote char - //(others?) - - /// Check to make sure that neither prefix or uri is already defined. - ustring dummy; - - if ( extensionsLookupPrefix( prefix, dummy ) ) - { - throw E57_EXCEPTION2( E57_ERROR_DUPLICATE_NAMESPACE_PREFIX, "prefix=" + prefix + " uri=" + uri ); - } - - if ( extensionsLookupUri( uri, dummy ) ) - { - throw E57_EXCEPTION2( E57_ERROR_DUPLICATE_NAMESPACE_URI, "prefix=" + prefix + " uri=" + uri ); - ; - } - - /// Append at end of list - nameSpaces_.emplace_back( prefix, uri ); - } - - bool ImageFileImpl::extensionsLookupPrefix( const ustring &prefix, ustring &uri ) const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - /// Linear search for matching prefix - std::vector::const_iterator it; - - for ( it = nameSpaces_.begin(); it < nameSpaces_.end(); ++it ) - { - if ( it->prefix == prefix ) - { - uri = it->uri; - return true; - } - } - - return false; - } - - bool ImageFileImpl::extensionsLookupUri( const ustring &uri, ustring &prefix ) const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - /// Linear search for matching URI - std::vector::const_iterator it; - - for ( it = nameSpaces_.begin(); it < nameSpaces_.end(); ++it ) - { - if ( it->uri == uri ) - { - prefix = it->prefix; - return true; - } - } - - return false; - } - - size_t ImageFileImpl::extensionsCount() const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - return nameSpaces_.size(); - } - - ustring ImageFileImpl::extensionsPrefix( const size_t index ) const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - return nameSpaces_[index].prefix; //??? throw e57 exception here if out of bounds? - } - - ustring ImageFileImpl::extensionsUri( const size_t index ) const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - return nameSpaces_[index].uri; //??? throw e57 exception here if out of bounds? - } - - bool ImageFileImpl::isElementNameExtended( const ustring &elementName ) - { - /// don't checkImageFileOpen - - /// Make sure doesn't have any "/" in it - size_t found = elementName.find_first_of( '/' ); - - if ( found != std::string::npos ) - { - return false; - } - - ustring prefix, localPart; - - try - { - /// Throws if elementName bad - elementNameParse( elementName, prefix, localPart ); - } - catch ( E57Exception & /*ex*/ ) - { - return false; - } - - /// If get here, the name was good, so test if found a prefix part - return ( prefix.length() > 0 ); - } - - bool ImageFileImpl::isElementNameLegal( const ustring &elementName, bool allowNumber ) - { -#ifdef E57_MAX_VERBOSE - // cout << "isElementNameLegal elementName=""" << elementName << """" << - // std::endl; -#endif - try - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - /// Throws if elementName bad - checkElementNameLegal( elementName, allowNumber ); - } - catch ( E57Exception & /*ex*/ ) - { - return false; - } - - /// If get here, the name was good - return true; - } - - bool ImageFileImpl::isPathNameLegal( const ustring &pathName ) - { -#ifdef E57_MAX_VERBOSE - // cout << "isPathNameLegal elementName=""" << pathName << """" << std::endl; -#endif - try - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - /// Throws if pathName bad - pathNameCheckWellFormed( pathName ); - } - catch ( E57Exception & /*ex*/ ) - { - return false; - } - - /// If get here, the name was good - return true; - } - - void ImageFileImpl::checkElementNameLegal( const ustring &elementName, bool allowNumber ) - { - /// no checkImageFileOpen(__FILE__, __LINE__, __FUNCTION__) - - ustring prefix; - ustring localPart; - - /// Throws if bad elementName - elementNameParse( elementName, prefix, localPart, allowNumber ); - - /// If has prefix, it must be registered - ustring uri; - - if ( prefix.length() > 0 && !extensionsLookupPrefix( prefix, uri ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName + " prefix=" + prefix ); - } - } - - void ImageFileImpl::elementNameParse( const ustring &elementName, ustring &prefix, ustring &localPart, - bool allowNumber ) - { - /// no checkImageFileOpen(__FILE__, __LINE__, __FUNCTION__) - - //??? check if elementName is good UTF-8? - - size_t len = elementName.length(); - - /// Empty name is bad - if ( len == 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName ); - } - - unsigned char c = elementName[0]; - - /// If allowing numeric element name, check if first char is digit - if ( allowNumber && '0' <= c && c <= '9' ) - { - /// All remaining characters must be digits - for ( size_t i = 1; i < len; i++ ) - { - c = elementName[i]; - - if ( !( '0' <= c && c <= '9' ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName ); - } - } - - return; - } - - /// If first char is ASCII (< 128), check for legality - /// Don't test any part of a multi-byte code point sequence (c >= 128). - /// Don't allow ':' as first char. - if ( c < 128 && !( ( 'a' <= c && c <= 'z' ) || ( 'A' <= c && c <= 'Z' ) || c == '_' ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName ); - } - - /// If each following char is ASCII (<128), check for legality - /// Don't test any part of a multi-byte code point sequence (c >= 128). - for ( size_t i = 1; i < len; i++ ) - { - c = elementName[i]; - - if ( c < 128 && !( ( 'a' <= c && c <= 'z' ) || ( 'A' <= c && c <= 'Z' ) || c == '_' || c == ':' || - ( '0' <= c && c <= '9' ) || c == '-' || c == '.' ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName ); - } - } - - /// Check if has at least one colon, try to split it into prefix & localPart - size_t found = elementName.find_first_of( ':' ); - - if ( found != std::string::npos ) - { - /// Check doesn't have two colons - if ( elementName.find_first_of( ':', found + 1 ) != std::string::npos ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName ); - } - - /// Split element name at the colon - /// ??? split before check first/subsequent char legal? - prefix = elementName.substr( 0, found ); - localPart = elementName.substr( found + 1 ); - - if ( prefix.length() == 0 || localPart.length() == 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, - "elementName=" + elementName + " prefix=" + prefix + " localPart=" + localPart ); - } - } - else - { - prefix = ""; - localPart = elementName; - } - } - - void ImageFileImpl::pathNameCheckWellFormed( const ustring &pathName ) - { - /// no checkImageFileOpen(__FILE__, __LINE__, __FUNCTION__) - - /// Just call pathNameParse() which throws if not well formed - bool isRelative = false; - StringList fields; - - pathNameParse( pathName, isRelative, fields ); - } - - void ImageFileImpl::pathNameParse( const ustring &pathName, bool &isRelative, StringList &fields ) - { -#ifdef E57_MAX_VERBOSE - std::cout << "pathNameParse pathname=" - "" - << pathName - << "" - "" - << std::endl; -#endif - /// no checkImageFileOpen(__FILE__, __LINE__, __FUNCTION__) - - /// Clear previous contents of fields vector - fields.clear(); - - size_t start = 0; - - /// Check if absolute path - if ( pathName[start] == '/' ) - { - isRelative = false; - start = 1; - } - else - { - isRelative = true; - } - - /// Save strings in between each forward slash '/' - /// Don't ignore whitespace - while ( start < pathName.size() ) - { - size_t slash = pathName.find_first_of( '/', start ); - - /// Get element name from in between '/', check valid - ustring elementName = pathName.substr( start, slash - start ); - - if ( !isElementNameLegal( elementName ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "pathName=" + pathName + " elementName=" + elementName ); - } - - /// Add to list - fields.push_back( elementName ); - - if ( slash == std::string::npos ) - { - break; - } - - /// Handle case when pathname ends in /, e.g. "/foo/", add empty field at - /// end of list - if ( slash == pathName.size() - 1 ) - { - fields.emplace_back( "" ); - break; - } - - /// Skip over the slash and keep going - start = slash + 1; - } - - /// Empty relative path is not allowed - if ( isRelative && fields.empty() ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "pathName=" + pathName ); - } - -#ifdef E57_MAX_VERBOSE - std::cout << "pathNameParse returning: isRelative=" << isRelative << " fields.size()=" << fields.size() - << " fields="; - for ( size_t i = 0; i < fields.size(); i++ ) - { - std::cout << fields[i] << ","; - } - std::cout << std::endl; -#endif - } - - ustring ImageFileImpl::pathNameUnparse( bool isRelative, const std::vector &fields ) - { - ustring path; - - if ( !isRelative ) - { - path.push_back( '/' ); - } - - for ( unsigned i = 0; i < fields.size(); ++i ) - { - path.append( fields.at( i ) ); - - if ( i < fields.size() - 1 ) - { - path.push_back( '/' ); - } - } - - return path; - } - - void ImageFileImpl::readFileHeader( CheckedFile *file, E57FileHeader &header ) - { - /// Double check that compiler thinks sizeof header is what it is supposed to - /// be - static_assert( sizeof( E57FileHeader ) == 48, "Unexpected size of E57FileHeader" ); - - /// Fetch the file header - file->read( reinterpret_cast( &header ), sizeof( header ) ); - -#ifdef E57_MAX_VERBOSE - header.dump(); -#endif - - /// Check signature - if ( strncmp( header.fileSignature, "ASTM-E57", 8 ) != 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_FILE_SIGNATURE, "fileName=" + file->fileName() ); - } - - /// Check file version compatibility - if ( header.majorVersion > E57_FORMAT_MAJOR ) - { - throw E57_EXCEPTION2( E57_ERROR_UNKNOWN_FILE_VERSION, - "fileName=" + file->fileName() + - " header.majorVersion=" + toString( header.majorVersion ) + - " header.minorVersion=" + toString( header.minorVersion ) ); - } - - /// If is a prototype version (majorVersion==0), then minorVersion has to - /// match too. In production versions (majorVersion==E57_FORMAT_MAJOR), - /// should be able to handle any minor version. - if ( header.majorVersion == E57_FORMAT_MAJOR && header.minorVersion > E57_FORMAT_MINOR ) - { - throw E57_EXCEPTION2( E57_ERROR_UNKNOWN_FILE_VERSION, - "fileName=" + file->fileName() + - " header.majorVersion=" + toString( header.majorVersion ) + - " header.minorVersion=" + toString( header.minorVersion ) ); - } - - /// Check if file length matches actual physical length - if ( header.filePhysicalLength != file->length( CheckedFile::Physical ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_FILE_LENGTH, - "fileName=" + file->fileName() + - " header.filePhysicalLength=" + toString( header.filePhysicalLength ) + - " file->length=" + toString( file->length( CheckedFile::Physical ) ) ); - } - - /// Check that page size is correct constant - if ( header.majorVersion != 0 && header.pageSize != CheckedFile::physicalPageSize ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_FILE_LENGTH, "fileName=" + file->fileName() ); - } - } - - void ImageFileImpl::checkImageFileOpen( const char *srcFileName, int srcLineNumber, - const char *srcFunctionName ) const - { - if ( !isOpen() ) - { - throw E57Exception( E57_ERROR_IMAGEFILE_NOT_OPEN, "fileName=" + fileName(), srcFileName, srcLineNumber, - srcFunctionName ); - } - } - -#ifdef E57_DEBUG - void ImageFileImpl::dump( int indent, std::ostream &os ) const - { - /// no checkImageFileOpen(__FILE__, __LINE__, __FUNCTION__) - os << space( indent ) << "fileName: " << fileName_ << std::endl; - os << space( indent ) << "writerCount: " << writerCount_ << std::endl; - os << space( indent ) << "readerCount: " << readerCount_ << std::endl; - os << space( indent ) << "isWriter: " << isWriter_ << std::endl; - for ( size_t i = 0; i < extensionsCount(); i++ ) - { - os << space( indent ) << "nameSpace[" << i << "]: prefix=" << extensionsPrefix( i ) - << " uri=" << extensionsUri( i ) << std::endl; - } - os << space( indent ) << "root: " << std::endl; - root_->dump( indent + 2, os ); - } -#endif - - unsigned ImageFileImpl::bitsNeeded( int64_t minimum, int64_t maximum ) - { - /// Relatively quick way to compute ceil(log2(maximum - minimum + 1))); - /// Uses only integer operations and is machine independent (no assembly - /// code). Find the bit position of the first 1 (from left) in the binary - /// form of stateCountMinus1. - ///??? move to E57Utility? - - uint64_t stateCountMinus1 = maximum - minimum; - - unsigned log2 = 0; - - if ( stateCountMinus1 & 0xFFFFFFFF00000000LL ) - { - stateCountMinus1 >>= 32; - log2 += 32; - } - - if ( stateCountMinus1 & 0xFFFF0000LL ) - { - stateCountMinus1 >>= 16; - log2 += 16; - } - - if ( stateCountMinus1 & 0xFF00LL ) - { - stateCountMinus1 >>= 8; - log2 += 8; - } - - if ( stateCountMinus1 & 0xF0LL ) - { - stateCountMinus1 >>= 4; - log2 += 4; - } - - if ( stateCountMinus1 & 0xCLL ) - { - stateCountMinus1 >>= 2; - log2 += 2; - } - - if ( stateCountMinus1 & 0x2LL ) - { - stateCountMinus1 >>= 1; - log2 += 1; - } - - if ( stateCountMinus1 & 1LL ) - { - log2++; - } - - return log2; - } -} diff --git a/src/3rdParty/libE57Format/src/ImageFileImpl.h b/src/3rdParty/libE57Format/src/ImageFileImpl.h deleted file mode 100644 index 6085960944..0000000000 --- a/src/3rdParty/libE57Format/src/ImageFileImpl.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include - -#include "Common.h" - -namespace e57 -{ - class CheckedFile; - - struct E57FileHeader; - struct NameSpace; - - class ImageFileImpl : public std::enable_shared_from_this - { - public: - ImageFileImpl( ReadChecksumPolicy policy ); - void construct2( const ustring &fileName, const ustring &mode ); - void construct2( const char *input, const uint64_t size ); - std::shared_ptr root(); - void close(); - void cancel(); - bool isOpen() const; - bool isWriter() const; - int writerCount() const; - int readerCount() const; - ~ImageFileImpl(); - - uint64_t allocateSpace( uint64_t byteCount, bool doExtendNow ); - CheckedFile *file() const; - ustring fileName() const; - - /// Manipulate registered extensions in the file - void extensionsAdd( const ustring &prefix, const ustring &uri ); - bool extensionsLookupPrefix( const ustring &prefix, ustring &uri ) const; - bool extensionsLookupUri( const ustring &uri, ustring &prefix ) const; - size_t extensionsCount() const; - ustring extensionsPrefix( const size_t index ) const; - ustring extensionsUri( const size_t index ) const; - - /// Utility functions: - bool isElementNameExtended( const ustring &elementName ); - bool isElementNameLegal( const ustring &elementName, bool allowNumber = true ); - bool isPathNameLegal( const ustring &pathName ); - void checkElementNameLegal( const ustring &elementName, bool allowNumber = true ); - void elementNameParse( const ustring &elementName, ustring &prefix, ustring &localPart, bool allowNumber = true ); - - void pathNameCheckWellFormed( const ustring &pathName ); - void pathNameParse( const ustring &pathName, bool &isRelative, StringList &fields ); - ustring pathNameUnparse( bool isRelative, const StringList &fields ); - - unsigned bitsNeeded( int64_t minimum, int64_t maximum ); - void incrWriterCount(); - void decrWriterCount(); - void incrReaderCount(); - void decrReaderCount(); - - /// Diagnostic functions: -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const; -#endif - - private: - friend class E57XmlParser; - friend class BlobNodeImpl; - friend class CompressedVectorWriterImpl; - friend class CompressedVectorReaderImpl; //??? add file() instead of - // accessing file_, others - // friends too - - static void readFileHeader( CheckedFile *file, E57FileHeader &header ); - - void checkImageFileOpen( const char *srcFileName, int srcLineNumber, const char *srcFunctionName ) const; - - ustring fileName_; - bool isWriter_; - int writerCount_; - int readerCount_; - - ReadChecksumPolicy checksumPolicy; - - CheckedFile *file_; - - /// Read file attributes - uint64_t xmlLogicalOffset_; - uint64_t xmlLogicalLength_; - - /// Write file attributes - uint64_t unusedLogicalStart_; - - /// Bidirectional map from namespace prefix to uri - std::vector nameSpaces_; - - /// Smart pointer to metadata tree - std::shared_ptr root_; - }; -} diff --git a/src/3rdParty/libE57Format/src/IntegerNodeImpl.cpp b/src/3rdParty/libE57Format/src/IntegerNodeImpl.cpp deleted file mode 100644 index 492baab0ae..0000000000 --- a/src/3rdParty/libE57Format/src/IntegerNodeImpl.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "IntegerNodeImpl.h" -#include "CheckedFile.h" - -namespace e57 -{ - IntegerNodeImpl::IntegerNodeImpl( ImageFileImplWeakPtr destImageFile, int64_t value, int64_t minimum, - int64_t maximum ) : - NodeImpl( destImageFile ), - value_( value ), minimum_( minimum ), maximum_( maximum ) - { - // don't checkImageFileOpen, NodeImpl() will do it - - /// Enforce the given bounds - if ( value < minimum || maximum < value ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_OUT_OF_BOUNDS, - "this->pathName=" + this->pathName() + " value=" + toString( value ) + - " minimum=" + toString( minimum ) + " maximum=" + toString( maximum ) ); - } - } - - bool IntegerNodeImpl::isTypeEquivalent( NodeImplSharedPtr ni ) - { - // don't checkImageFileOpen - - /// Same node type? - if ( ni->type() != E57_INTEGER ) - { - return ( false ); - } - - /// Downcast to shared_ptr - std::shared_ptr ii( std::static_pointer_cast( ni ) ); - - /// minimum must match - if ( minimum_ != ii->minimum_ ) - { - return ( false ); - } - - /// maximum must match - if ( maximum_ != ii->maximum_ ) - { - return ( false ); - } - - /// ignore value_, doesn't have to match - - /// Types match - return ( true ); - } - - bool IntegerNodeImpl::isDefined( const ustring &pathName ) - { - // don't checkImageFileOpen - - /// We have no sub-structure, so if path not empty return false - return pathName.empty(); - } - - int64_t IntegerNodeImpl::value() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( value_ ); - } - - int64_t IntegerNodeImpl::minimum() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( minimum_ ); - } - - int64_t IntegerNodeImpl::maximum() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( maximum_ ); - } - - void IntegerNodeImpl::checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) - { - // don't checkImageFileOpen - - /// We are a leaf node, so verify that we are listed in set. - if ( pathNames.find( relativePathName( origin ) ) == pathNames.end() ) - { - throw E57_EXCEPTION2( E57_ERROR_NO_BUFFER_FOR_ELEMENT, "this->pathName=" + this->pathName() ); - } - } - - void IntegerNodeImpl::writeXml( ImageFileImplSharedPtr /*imf???*/, CheckedFile &cf, int indent, - const char *forcedFieldName ) - { - // don't checkImageFileOpen - - ustring fieldName; - if ( forcedFieldName ) - { - fieldName = forcedFieldName; - } - else - { - fieldName = elementName_; - } - - cf << space( indent ) << "<" << fieldName << " type=\"Integer\""; - - /// Don't need to write if are default values - if ( minimum_ != E57_INT64_MIN ) - { - cf << " minimum=\"" << minimum_ << "\""; - } - if ( maximum_ != E57_INT64_MAX ) - { - cf << " maximum=\"" << maximum_ << "\""; - } - - /// Write value as child text, unless it is the default value - if ( value_ != 0 ) - { - cf << ">" << value_ << "\n"; - } - else - { - cf << "/>\n"; - } - } - -#ifdef E57_DEBUG - void IntegerNodeImpl::dump( int indent, std::ostream &os ) const - { - // don't checkImageFileOpen - os << space( indent ) << "type: Integer" - << " (" << type() << ")" << std::endl; - NodeImpl::dump( indent, os ); - os << space( indent ) << "value: " << value_ << std::endl; - os << space( indent ) << "minimum: " << minimum_ << std::endl; - os << space( indent ) << "maximum: " << maximum_ << std::endl; - } -#endif -} diff --git a/src/3rdParty/libE57Format/src/IntegerNodeImpl.h b/src/3rdParty/libE57Format/src/IntegerNodeImpl.h deleted file mode 100644 index d30e748a04..0000000000 --- a/src/3rdParty/libE57Format/src/IntegerNodeImpl.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "NodeImpl.h" - -namespace e57 -{ - class IntegerNodeImpl : public NodeImpl - { - public: - IntegerNodeImpl( ImageFileImplWeakPtr destImageFile, int64_t value = 0, int64_t minimum = 0, - int64_t maximum = 0 ); - ~IntegerNodeImpl() override = default; - - NodeType type() const override - { - return E57_INTEGER; - } - bool isTypeEquivalent( NodeImplSharedPtr ni ) override; - bool isDefined( const ustring &pathName ) override; - - int64_t value(); - int64_t minimum(); - int64_t maximum(); - - void checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) override; - - void writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, - const char *forcedFieldName = nullptr ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - - private: - int64_t value_; - int64_t minimum_; - int64_t maximum_; - }; -} diff --git a/src/3rdParty/libE57Format/src/NodeImpl.cpp b/src/3rdParty/libE57Format/src/NodeImpl.cpp deleted file mode 100644 index 8cb2a5032f..0000000000 --- a/src/3rdParty/libE57Format/src/NodeImpl.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "NodeImpl.h" -#include "ImageFileImpl.h" -#include "SourceDestBufferImpl.h" -#include "VectorNodeImpl.h" - -using namespace e57; - -NodeImpl::NodeImpl( ImageFileImplWeakPtr destImageFile ) : destImageFile_( destImageFile ), isAttached_( false ) -{ - checkImageFileOpen( __FILE__, __LINE__, - static_cast( __FUNCTION__ ) ); // does checking for all node type ctors -} - -void NodeImpl::checkImageFileOpen( const char *srcFileName, int srcLineNumber, const char *srcFunctionName ) const -{ - /// Throw an exception if destImageFile (destImageFile_) isn't open - ImageFileImplSharedPtr destImageFile( destImageFile_ ); - if ( !destImageFile->isOpen() ) - { - throw E57Exception( E57_ERROR_IMAGEFILE_NOT_OPEN, "fileName=" + destImageFile->fileName(), srcFileName, - srcLineNumber, srcFunctionName ); - } -} - -bool NodeImpl::isRoot() const -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - return parent_.expired(); -}; - -NodeImplSharedPtr NodeImpl::parent() -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - if ( isRoot() ) - { - /// If is root, then has self as parent (by convention) - return shared_from_this(); - } - - NodeImplSharedPtr myParent( parent_ ); - - return myParent; -} - -ustring NodeImpl::pathName() const -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - if ( isRoot() ) - { - return ( "/" ); - } - - NodeImplSharedPtr p( parent_ ); - - if ( p->isRoot() ) - { - return ( "/" + elementName_ ); - } - - return ( p->pathName() + "/" + elementName_ ); -} - -ustring NodeImpl::relativePathName( const NodeImplSharedPtr &origin, ustring childPathName ) const -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - if ( origin == shared_from_this() ) - { - return ( childPathName ); - } - - if ( isRoot() ) - { - /// Got to top and didn't find origin, must be error - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, - "this->elementName=" + this->elementName() + " childPathName=" + childPathName ); - } - - /// Assemble relativePathName from right to left, recursively - NodeImplSharedPtr p( parent_ ); - - if ( childPathName.empty() ) - { - return p->relativePathName( origin, elementName_ ); - } - - return p->relativePathName( origin, elementName_ + "/" + childPathName ); -} - -ustring NodeImpl::elementName() const -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - return elementName_; -} - -ImageFileImplSharedPtr NodeImpl::destImageFile() -{ - /// don't checkImageFileOpen - return ImageFileImplSharedPtr( destImageFile_ ); -} - -bool NodeImpl::isAttached() const -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - return isAttached_; -} - -void NodeImpl::setAttachedRecursive() -{ - /// Non-terminal node types (Structure, Vector, CompressedVector) will - /// override this virtual function, to mark their children, codecs, - /// prototypes - isAttached_ = true; -} - -ustring NodeImpl::imageFileName() const -{ - /// don't checkImageFileOpen - ImageFileImplSharedPtr imf( destImageFile_ ); - - return imf->fileName(); -} - -void NodeImpl::setParent( NodeImplSharedPtr parent, const ustring &elementName ) -{ - /// don't checkImageFileOpen - - /// First check if our parent_ is already set, throw - /// E57_ERROR_ALREADY_HAS_PARENT The isAttached_ condition is to catch two - /// errors: - /// 1) if user attempts to use the ImageFile root as a child (e.g. - /// root.set("x", root)) 2) if user attempts to reuse codecs or prototype - /// trees of a CompressedVectorNode - /// ??? what if CV not attached yet? - if ( !parent_.expired() || isAttached_ ) - { - /// ??? does caller do setParent first, so state is not messed up when - /// throw? - throw E57_EXCEPTION2( E57_ERROR_ALREADY_HAS_PARENT, - "this->pathName=" + this->pathName() + " newParent->pathName=" + parent->pathName() ); - } - - parent_ = parent; - elementName_ = elementName; - - /// If parent is attached then we are attached (and all of our children) - if ( parent->isAttached() ) - { - setAttachedRecursive(); - } -} - -NodeImplSharedPtr NodeImpl::getRoot() -{ - /// don't checkImageFileOpen - NodeImplSharedPtr p( shared_from_this() ); - while ( !p->isRoot() ) - { - p = NodeImplSharedPtr( p->parent_ ); //??? check if bad ptr? - } - - return p; -} - -//??? use visitor? -bool NodeImpl::isTypeConstrained() -{ - /// don't checkImageFileOpen - /// A node is type constrained if any of its parents is an homo VECTOR or - /// COMPRESSED_VECTOR with more than one child - NodeImplSharedPtr p( shared_from_this() ); - - while ( !p->isRoot() ) - { - /// We have a parent since we are not root - p = NodeImplSharedPtr( p->parent_ ); //??? check if bad ptr? - - switch ( p->type() ) - { - case E57_VECTOR: - { - /// Downcast to shared_ptr - std::shared_ptr ai( std::static_pointer_cast( p ) ); - - /// If homogeneous vector and have more than one child, then can't - /// change them - if ( !ai->allowHeteroChildren() && ai->childCount() > 1 ) - { - return ( true ); - } - } - break; - case E57_COMPRESSED_VECTOR: - /// Can't make any type changes to CompressedVector prototype. ??? - /// what if hasn't been written to yet - return ( true ); - default: - break; - } - } - /// Didn't find any constraining VECTORs or COMPRESSED_VECTORs in path above - /// us, so our type is not constrained. - return ( false ); -} - -NodeImplSharedPtr NodeImpl::get( const ustring &pathName ) -{ - /// This is common virtual function for terminal E57 element types: Integer, - /// ScaledInteger, Float, Blob. The non-terminal types override this virtual - /// function. Only absolute pathNames make any sense here, because the - /// terminal types can't have children, so relative pathNames are illegal. - -#ifdef E57_DEBUG - _verifyPathNameAbsolute( pathName ); -#endif - - NodeImplSharedPtr root = _verifyAndGetRoot(); - - /// Forward call to the non-terminal root node - return root->get( pathName ); -} - -void NodeImpl::set( const ustring &pathName, NodeImplSharedPtr ni, bool autoPathCreate ) -{ - /// This is common virtual function for terminal E57 element types: Integer, - /// ScaledInteger, Float, Blob. The non-terminal types override this virtual - /// function. Only absolute pathNames make any sense here, because the - /// terminal types can't have children, so relative pathNames are illegal. - -#ifdef E57_DEBUG - _verifyPathNameAbsolute( pathName ); -#endif - - NodeImplSharedPtr root = _verifyAndGetRoot(); - - /// Forward call to the non-terminal root node - root->set( pathName, ni, autoPathCreate ); -} - -void NodeImpl::set( const StringList & /*fields*/, unsigned /*level*/, NodeImplSharedPtr /*ni*/, - bool /*autoPathCreate*/ ) -{ - /// If get here, then tried to call set(fields...) on NodeImpl that wasn't a - /// StructureNodeImpl, so that's an error - throw E57_EXCEPTION1( E57_ERROR_BAD_PATH_NAME ); //??? -} - -void NodeImpl::checkBuffers( const std::vector &sdbufs, - bool allowMissing ) //??? convert sdbufs to vector of shared_ptr -{ - /// this node is prototype of CompressedVector - - /// don't checkImageFileOpen - - StringSet pathNames; - - for ( unsigned i = 0; i < sdbufs.size(); i++ ) - { - ustring pathName = sdbufs.at( i ).impl()->pathName(); - - /// Check that all buffers are same size - if ( sdbufs.at( i ).impl()->capacity() != sdbufs.at( 0 ).impl()->capacity() ) - { - throw E57_EXCEPTION2( E57_ERROR_BUFFER_SIZE_MISMATCH, - "this->pathName=" + this->pathName() + " sdbuf.pathName=" + pathName + - " firstCapacity=" + toString( sdbufs.at( 0 ).impl()->capacity() ) + - " secondCapacity=" + toString( sdbufs.at( i ).impl()->capacity() ) ); - } - - /// Add each pathName to set, error if already in set (a duplicate - /// pathName in sdbufs) - if ( !pathNames.insert( pathName ).second ) - { - throw E57_EXCEPTION2( E57_ERROR_BUFFER_DUPLICATE_PATHNAME, - "this->pathName=" + this->pathName() + " sdbuf.pathName=" + pathName ); - } - - /// Check no bad fields in sdbufs - if ( !isDefined( pathName ) ) - { - throw E57_EXCEPTION2( E57_ERROR_PATH_UNDEFINED, - "this->pathName=" + this->pathName() + " sdbuf.pathName=" + pathName ); - } - } - - if ( !allowMissing ) - { - /// Traverse tree recursively, checking that all nodes are listed in - /// sdbufs - checkLeavesInSet( pathNames, shared_from_this() ); - } -} - -bool NodeImpl::findTerminalPosition( const NodeImplSharedPtr &target, uint64_t &countFromLeft ) -{ - /// don't checkImageFileOpen - - if ( this == &*target ) //??? ok? - { - return true; - } - - switch ( type() ) - { - case E57_STRUCTURE: - { - auto sni = static_cast( this ); - - /// Recursively visit child nodes - int64_t childCount = sni->childCount(); - for ( int64_t i = 0; i < childCount; ++i ) - { - if ( sni->get( i )->findTerminalPosition( target, countFromLeft ) ) - { - return true; - } - } - } - break; - - case E57_VECTOR: - { - auto vni = static_cast( this ); - - /// Recursively visit child nodes - int64_t childCount = vni->childCount(); - for ( int64_t i = 0; i < childCount; ++i ) - { - if ( vni->get( i )->findTerminalPosition( target, countFromLeft ) ) - { - return true; - } - } - } - break; - - case E57_COMPRESSED_VECTOR: - break; //??? for now, don't search into contents of compressed vector - - case E57_INTEGER: - case E57_SCALED_INTEGER: - case E57_FLOAT: - case E57_STRING: - case E57_BLOB: - countFromLeft++; - break; - } - - return ( false ); -} - -#ifdef E57_DEBUG -void NodeImpl::dump( int indent, std::ostream &os ) const -{ - /// don't checkImageFileOpen - os << space( indent ) << "elementName: " << elementName_ << std::endl; - os << space( indent ) << "isAttached: " << isAttached_ << std::endl; - os << space( indent ) << "path: " << pathName() << std::endl; -} - -bool NodeImpl::_verifyPathNameAbsolute( const ustring &inPathName ) -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - /// Parse to determine if pathName is absolute - bool isRelative = false; - std::vector fields; - ImageFileImplSharedPtr imf( destImageFile_ ); - - imf->pathNameParse( inPathName, isRelative, - fields ); // throws if bad pathName - - /// If not an absolute path name, have error - if ( isRelative ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "this->pathName=" + this->pathName() + " pathName=" + inPathName ); - } - - return isRelative; -} -#endif - -NodeImplSharedPtr NodeImpl::_verifyAndGetRoot() -{ - /// Find root of the tree - NodeImplSharedPtr root( shared_from_this()->getRoot() ); - - /// Check to make sure root node is non-terminal type (otherwise have stack - /// overflow). - switch ( root->type() ) - { - case E57_STRUCTURE: - case E57_VECTOR: //??? COMPRESSED_VECTOR? - break; - default: - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "root invalid for this->pathName=" + this->pathName() ); - } - - return root; -} diff --git a/src/3rdParty/libE57Format/src/NodeImpl.h b/src/3rdParty/libE57Format/src/NodeImpl.h deleted file mode 100644 index 177b1ef209..0000000000 --- a/src/3rdParty/libE57Format/src/NodeImpl.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include "Common.h" - -namespace e57 -{ - - class CheckedFile; - - class NodeImpl : public std::enable_shared_from_this - { - public: - virtual NodeType type() const = 0; - void checkImageFileOpen( const char *srcFileName, int srcLineNumber, const char *srcFunctionName ) const; - virtual bool isTypeEquivalent( NodeImplSharedPtr ni ) = 0; - bool isRoot() const; - NodeImplSharedPtr parent(); - ustring pathName() const; - ustring relativePathName( const NodeImplSharedPtr &origin, ustring childPathName = ustring() ) const; - ustring elementName() const; - ImageFileImplSharedPtr destImageFile(); - - ustring imageFileName() const; - virtual bool isDefined( const ustring &pathName ) = 0; - bool isAttached() const; - virtual void setAttachedRecursive(); - - void setParent( NodeImplSharedPtr parent, const ustring &elementName ); - bool isTypeConstrained(); - - virtual NodeImplSharedPtr get( const ustring &pathName ); - virtual void set( const ustring &pathName, NodeImplSharedPtr ni, bool autoPathCreate = false ); - virtual void set( const StringList &fields, unsigned level, NodeImplSharedPtr ni, bool autoPathCreate = false ); - - virtual void checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) = 0; - void checkBuffers( const std::vector &sdbufs, bool allowMissing ); - bool findTerminalPosition( const NodeImplSharedPtr &target, uint64_t &countFromLeft ); - - virtual void writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, - const char *forcedFieldName = nullptr ) = 0; - - virtual ~NodeImpl() = default; - -#ifdef E57_DEBUG - virtual void dump( int indent = 0, std::ostream &os = std::cout ) const; -#endif - - private: -#ifdef E57_DEBUG - bool _verifyPathNameAbsolute( const ustring &inPathName ); -#endif - - NodeImplSharedPtr _verifyAndGetRoot(); - - protected: - friend class StructureNodeImpl; - friend class CompressedVectorWriterImpl; - friend class Decoder; - friend class Encoder; - - NodeImpl( ImageFileImplWeakPtr destImageFile ); - NodeImpl &operator=( NodeImpl &n ); - virtual NodeImplSharedPtr lookup( const ustring & /*pathName*/ ) - { - return NodeImplSharedPtr(); - } - NodeImplSharedPtr getRoot(); - - ImageFileImplWeakPtr destImageFile_; - NodeImplWeakPtr parent_; - ustring elementName_; - bool isAttached_; - }; -} diff --git a/src/3rdParty/libE57Format/src/Packet.cpp b/src/3rdParty/libE57Format/src/Packet.cpp deleted file mode 100644 index 2f3ae672d3..0000000000 --- a/src/3rdParty/libE57Format/src/Packet.cpp +++ /dev/null @@ -1,734 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include - -#include "CheckedFile.h" -#include "Packet.h" - -using namespace e57; - -struct IndexPacket -{ - static constexpr unsigned MAX_ENTRIES = 2048; - - const uint8_t packetType = INDEX_PACKET; - - uint8_t packetFlags = 0; // flag bitfields - uint16_t packetLogicalLengthMinus1 = 0; - uint16_t entryCount = 0; - uint8_t indexLevel = 0; - uint8_t reserved1[9] = {}; // must be zero - - struct IndexPacketEntry - { - uint64_t chunkRecordNumber = 0; - uint64_t chunkPhysicalOffset = 0; - } entries[MAX_ENTRIES]; - - void verify( unsigned bufferLength = 0, uint64_t totalRecordCount = 0, uint64_t fileSize = 0 ) const; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const; -#endif -}; - -struct EmptyPacketHeader -{ - const uint8_t packetType = EMPTY_PACKET; - - uint8_t reserved1 = 0; // must be zero - uint16_t packetLogicalLengthMinus1 = 0; - - void verify( unsigned bufferLength = 0 ) const; //???use - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const; -#endif -}; - -//============================================================================= -// PacketReadCache - -PacketReadCache::PacketReadCache( CheckedFile *cFile, unsigned packetCount ) : cFile_( cFile ), entries_( packetCount ) -{ - if ( packetCount == 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "packetCount=" + toString( packetCount ) ); - } -} - -std::unique_ptr PacketReadCache::lock( uint64_t packetLogicalOffset, char *&pkt ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "PacketReadCache::lock() called, packetLogicalOffset=" << packetLogicalOffset << std::endl; -#endif - - /// Only allow one locked packet at a time. - if ( lockCount_ > 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "lockCount=" + toString( lockCount_ ) ); - } - - /// Offset can't be 0 - if ( packetLogicalOffset == 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "packetLogicalOffset=" + toString( packetLogicalOffset ) ); - } - - /// Linear scan for matching packet offset in cache - for ( unsigned i = 0; i < entries_.size(); ++i ) - { - auto &entry = entries_[i]; - - if ( packetLogicalOffset == entry.logicalOffset_ ) - { - /// Found a match, so don't have to read anything -#ifdef E57_MAX_VERBOSE - std::cout << " Found matching cache entry, index=" << i << std::endl; -#endif - /// Mark entry with current useCount (keeps track of age of entry). - entry.lastUsed_ = ++useCount_; - - /// Publish buffer address to caller - pkt = entry.buffer_; - - /// Create lock so we are sure that we will be unlocked when use is - /// finished. - std::unique_ptr plock( new PacketLock( this, i ) ); - - /// Increment cache lock just before return - ++lockCount_; - - return plock; - } - } - /// Get here if didn't find a match already in cache. - - /// Find least recently used (LRU) packet buffer - unsigned oldestEntry = 0; - unsigned oldestUsed = entries_.at( 0 ).lastUsed_; - - for ( unsigned i = 0; i < entries_.size(); ++i ) - { - const auto &entry = entries_[i]; - - if ( entry.lastUsed_ < oldestUsed ) - { - oldestEntry = i; - oldestUsed = entry.lastUsed_; - } - } -#ifdef E57_MAX_VERBOSE - std::cout << " Oldest entry=" << oldestEntry << " lastUsed=" << oldestUsed << std::endl; -#endif - - readPacket( oldestEntry, packetLogicalOffset ); - - /// Publish buffer address to caller - pkt = entries_[oldestEntry].buffer_; - - /// Create lock so we are sure we will be unlocked when use is finished. - std::unique_ptr plock( new PacketLock( this, oldestEntry ) ); - - /// Increment cache lock just before return - ++lockCount_; - - return plock; -} - -void PacketReadCache::unlock( unsigned cacheIndex ) -{ - (void)cacheIndex; - //??? why lockedEntry not used? -#ifdef E57_MAX_VERBOSE - std::cout << "PacketReadCache::unlock() called, cacheIndex=" << cacheIndex << std::endl; -#endif - - if ( lockCount_ != 1 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "lockCount=" + toString( lockCount_ ) ); - } - - --lockCount_; -} - -void PacketReadCache::readPacket( unsigned oldestEntry, uint64_t packetLogicalOffset ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "PacketReadCache::readPacket() called, oldestEntry=" << oldestEntry - << " packetLogicalOffset=" << packetLogicalOffset << std::endl; -#endif - - /// Read header of packet first to get length. Use EmptyPacketHeader since - /// it has the fields common to all packets. - EmptyPacketHeader header; - - cFile_->seek( packetLogicalOffset, CheckedFile::Logical ); - cFile_->read( reinterpret_cast( &header ), sizeof( header ) ); - - /// Can't verify packet header here, because it is not really an - /// EmptyPacketHeader. - unsigned packetLength = header.packetLogicalLengthMinus1 + 1; - - /// Be paranoid about packetLength before read - if ( packetLength > DATA_PACKET_MAX ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) ); - } - - auto &entry = entries_.at( oldestEntry ); - - /// Now read in whole packet into preallocated buffer_. Note buffer is - cFile_->seek( packetLogicalOffset, CheckedFile::Logical ); - cFile_->read( entry.buffer_, packetLength ); - - /// Verify that packet is good. - switch ( header.packetType ) - { - case DATA_PACKET: - { - auto dpkt = reinterpret_cast( entry.buffer_ ); - - dpkt->verify( packetLength ); -#ifdef E57_MAX_VERBOSE - std::cout << " data packet:" << std::endl; - dpkt->dump( 4 ); //??? -#endif - } - break; - case INDEX_PACKET: - { - auto ipkt = reinterpret_cast( entry.buffer_ ); - - ipkt->verify( packetLength ); -#ifdef E57_MAX_VERBOSE - std::cout << " index packet:" << std::endl; - ipkt->dump( 4 ); //??? -#endif - } - break; - case EMPTY_PACKET: - { - auto hp = reinterpret_cast( entry.buffer_ ); - - hp->verify( packetLength ); -#ifdef E57_MAX_VERBOSE - std::cout << " empty packet:" << std::endl; - hp->dump( 4 ); //??? -#endif - } - break; - default: - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "packetType=" + toString( header.packetType ) ); - } - - entry.logicalOffset_ = packetLogicalOffset; - - /// Mark entry with current useCount (keeps track of age of entry). - /// This is a cache, so a small hiccup when useCount_ overflows won't hurt. - entry.lastUsed_ = ++useCount_; -} - -#ifdef E57_DEBUG -void PacketReadCache::dump( int indent, std::ostream &os ) -{ - os << space( indent ) << "lockCount: " << lockCount_ << std::endl; - os << space( indent ) << "useCount: " << useCount_ << std::endl; - os << space( indent ) << "entries:" << std::endl; - for ( unsigned i = 0; i < entries_.size(); i++ ) - { - os << space( indent ) << "entry[" << i << "]:" << std::endl; - os << space( indent + 4 ) << "logicalOffset: " << entries_[i].logicalOffset_ << std::endl; - os << space( indent + 4 ) << "lastUsed: " << entries_[i].lastUsed_ << std::endl; - if ( entries_[i].logicalOffset_ != 0 ) - { - os << space( indent + 4 ) << "packet:" << std::endl; - switch ( reinterpret_cast( entries_.at( i ).buffer_ )->packetType ) - { - case DATA_PACKET: - { - auto dpkt = reinterpret_cast( entries_.at( i ).buffer_ ); - dpkt->dump( indent + 6, os ); - } - break; - case INDEX_PACKET: - { - auto ipkt = reinterpret_cast( entries_.at( i ).buffer_ ); - ipkt->dump( indent + 6, os ); - } - break; - case EMPTY_PACKET: - { - auto hp = reinterpret_cast( entries_.at( i ).buffer_ ); - hp->dump( indent + 6, os ); - } - break; - default: - throw E57_EXCEPTION2( - E57_ERROR_INTERNAL, - "packetType=" + - toString( reinterpret_cast( entries_.at( i ).buffer_ )->packetType ) ); - } - } - } -} -#endif - -//============================================================================= -// PacketLock - -PacketLock::PacketLock( PacketReadCache *cache, unsigned cacheIndex ) : cache_( cache ), cacheIndex_( cacheIndex ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "PacketLock() called" << std::endl; -#endif -} - -PacketLock::~PacketLock() -{ -#ifdef E57_MAX_VERBOSE - std::cout << "~PacketLock() called" << std::endl; -#endif - try - { - /// Note cache must live longer than lock, this is reasonable assumption. - cache_->unlock( cacheIndex_ ); - } - catch ( ... ) - { - //??? report? - } -} - -//============================================================================= -// DataPacketHeader - -DataPacketHeader::DataPacketHeader() -{ - /// Double check that packet struct is correct length. Watch out for RTTI - /// increasing the size. - static_assert( sizeof( DataPacketHeader ) == 6, "Unexpected size of DataPacketHeader" ); -} - -void DataPacketHeader::reset() -{ - packetFlags = 0; - packetLogicalLengthMinus1 = 0; - bytestreamCount = 0; -} - -void DataPacketHeader::verify( unsigned bufferLength ) const -{ - /// Verify that packet is correct type - if ( packetType != DATA_PACKET ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetType=" + toString( packetType ) ); - } - - /// ??? check reserved flags zero? - - /// Check packetLength is at least large enough to hold header - unsigned packetLength = packetLogicalLengthMinus1 + 1; - if ( packetLength < sizeof( *this ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) ); - } - - /// Check packet length is multiple of 4 - if ( packetLength % 4 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) ); - } - - /// Check actual packet length is large enough. - if ( bufferLength > 0 && packetLength > bufferLength ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, - "packetLength=" + toString( packetLength ) + " bufferLength=" + toString( bufferLength ) ); - } - - /// Make sure there is at least one entry in packet ??? 0 record cvect - /// allowed? - if ( bytestreamCount == 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "bytestreamCount=" + toString( bytestreamCount ) ); - } - - /// Check packet is at least long enough to hold bytestreamBufferLength array - if ( sizeof( DataPacketHeader ) + 2 * bytestreamCount > packetLength ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) + - " bytestreamCount=" + toString( bytestreamCount ) ); - } -} - -#ifdef E57_DEBUG -void DataPacketHeader::dump( int indent, std::ostream &os ) const -{ - os << space( indent ) << "packetType: " << static_cast( packetType ) << std::endl; - os << space( indent ) << "packetFlags: " << static_cast( packetFlags ) << std::endl; - os << space( indent ) << "packetLogicalLengthMinus1: " << packetLogicalLengthMinus1 << std::endl; - os << space( indent ) << "bytestreamCount: " << bytestreamCount << std::endl; -} -#endif - -//============================================================================= -// DataPacket - -DataPacket::DataPacket() -{ - /// Double check that packet struct is correct length. Watch out for RTTI - /// increasing the size. - static_assert( sizeof( DataPacket ) == 64 * 1024, "Unexpected size of DataPacket" ); -} - -void DataPacket::verify( unsigned bufferLength ) const -{ - //??? do all packets need versions? how extend without breaking older - // checking? need to check - // file version#? - - /// Verify header is good - auto hp = reinterpret_cast( this ); - - hp->verify( bufferLength ); - - /// Calc sum of lengths of each bytestream buffer in this packet - auto bsbLength = reinterpret_cast( &payload[0] ); - unsigned totalStreamByteCount = 0; - - for ( unsigned i = 0; i < header.bytestreamCount; i++ ) - { - totalStreamByteCount += bsbLength[i]; - } - - /// Calc size of packet needed - const unsigned packetLength = header.packetLogicalLengthMinus1 + 1; - const unsigned needed = sizeof( DataPacketHeader ) + 2 * header.bytestreamCount + totalStreamByteCount; -#ifdef E57_MAX_VERBOSE - std::cout << "needed=" << needed << " actual=" << packetLength << std::endl; //??? -#endif - - /// If needed is not with 3 bytes of actual packet size, have an error - if ( needed > packetLength || needed + 3 < packetLength ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, - "needed=" + toString( needed ) + "packetLength=" + toString( packetLength ) ); - } - - /// Verify that padding at end of packet is zero - for ( unsigned i = needed; i < packetLength; i++ ) - { - if ( reinterpret_cast( this )[i] != 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "i=" + toString( i ) ); - } - } -} - -char *DataPacket::getBytestream( unsigned bytestreamNumber, unsigned &byteCount ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "getBytestream called, bytestreamNumber=" << bytestreamNumber << std::endl; -#endif - - /// Verify that packet is correct type - if ( header.packetType != DATA_PACKET ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetType=" + toString( header.packetType ) ); - } - - /// Check bytestreamNumber in bounds - if ( bytestreamNumber >= header.bytestreamCount ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "bytestreamNumber=" + toString( bytestreamNumber ) + - "bytestreamCount=" + toString( header.bytestreamCount ) ); - } - - /// Calc positions in packet - auto bsbLength = reinterpret_cast( &payload[0] ); - auto streamBase = reinterpret_cast( &bsbLength[header.bytestreamCount] ); - - /// Sum size of preceding stream buffers to get position - unsigned totalPreceeding = 0; - for ( unsigned i = 0; i < bytestreamNumber; i++ ) - { - totalPreceeding += bsbLength[i]; - } - - byteCount = bsbLength[bytestreamNumber]; - - /// Double check buffer is completely within packet - if ( sizeof( DataPacketHeader ) + 2 * header.bytestreamCount + totalPreceeding + byteCount > - header.packetLogicalLengthMinus1 + 1U ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, - "bytestreamCount=" + toString( header.bytestreamCount ) + " totalPreceeding=" + - toString( totalPreceeding ) + " byteCount=" + toString( byteCount ) + - " packetLogicalLengthMinus1=" + toString( header.packetLogicalLengthMinus1 ) ); - } - - /// Return start of buffer - return ( &streamBase[totalPreceeding] ); -} - -unsigned DataPacket::getBytestreamBufferLength( unsigned bytestreamNumber ) -{ - //??? for now: - unsigned byteCount; - (void)getBytestream( bytestreamNumber, byteCount ); - return ( byteCount ); -} - -#ifdef E57_DEBUG -void DataPacket::dump( int indent, std::ostream &os ) const -{ - if ( header.packetType != DATA_PACKET ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "packetType=" + toString( header.packetType ) ); - } - - reinterpret_cast( this )->dump( indent, os ); - - auto bsbLength = reinterpret_cast( &payload[0] ); - auto p = reinterpret_cast( &bsbLength[header.bytestreamCount] ); - - for ( unsigned i = 0; i < header.bytestreamCount; i++ ) - { - os << space( indent ) << "bytestream[" << i << "]:" << std::endl; - os << space( indent + 4 ) << "length: " << bsbLength[i] << std::endl; - /*==== - unsigned j; - for (j=0; j < bsbLength[i] && j < 10; j++) - os << space(indent+4) << "byte[" << j << "]=" << (unsigned)p[j] - << std::endl; if (j < bsbLength[i]) os << space(indent+4) << bsbLength[i]-j << " - more unprinted..." << std::endl; - ====*/ - p += bsbLength[i]; - if ( p - reinterpret_cast( this ) > DATA_PACKET_MAX ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, - "size=" + toString( p - reinterpret_cast( this ) ) ); - } - } -} -#endif - -//============================================================================= -// IndexPacket - -void IndexPacket::verify( unsigned bufferLength, uint64_t totalRecordCount, uint64_t fileSize ) const -{ - (void)totalRecordCount; (void)fileSize; - //??? do all packets need versions? how extend without breaking older - // checking? need to check - // file version#? - - /// Verify that packet is correct type - if ( packetType != INDEX_PACKET ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetType=" + toString( packetType ) ); - } - - /// Check packetLength is at least large enough to hold header - unsigned packetLength = packetLogicalLengthMinus1 + 1; - if ( packetLength < sizeof( *this ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) ); - } - - /// Check packet length is multiple of 4 - if ( packetLength % 4 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) ); - } - - /// Make sure there is at least one entry in packet ??? 0 record cvect - /// allowed? - if ( entryCount == 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "entryCount=" + toString( entryCount ) ); - } - - /// Have to have <= 2048 entries - if ( entryCount > MAX_ENTRIES ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "entryCount=" + toString( entryCount ) ); - } - - /// Index level should be <= 5. Because (5+1)* 11 bits = 66 bits, which will - /// cover largest number of chunks possible. - if ( indexLevel > 5 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "indexLevel=" + toString( indexLevel ) ); - } - - /// Index packets above level 0 must have at least two entries (otherwise no - /// point to existing). - ///??? check that this is in spec - if ( indexLevel > 0 && entryCount < 2 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, - "indexLevel=" + toString( indexLevel ) + " entryCount=" + toString( entryCount ) ); - } - - /// If not later version, verify reserved fields are zero. ??? test file - /// version if (version <= E57_FORMAT_MAJOR) { //??? - for ( unsigned i = 0; i < sizeof( reserved1 ); i++ ) - { - if ( reserved1[i] != 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "i=" + toString( i ) ); - } - } - - /// Check actual packet length is large enough. - if ( bufferLength > 0 && packetLength > bufferLength ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, - "packetLength=" + toString( packetLength ) + " bufferLength=" + toString( bufferLength ) ); - } - - /// Check if entries will fit in space provided - unsigned neededLength = 16 + 8 * entryCount; - if ( packetLength < neededLength ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, - "packetLength=" + toString( packetLength ) + " neededLength=" + toString( neededLength ) ); - } - -#ifdef E57_MAX_DEBUG - /// Verify padding at end is zero. - const char *p = reinterpret_cast( this ); - for ( unsigned i = neededLength; i < packetLength; i++ ) - { - if ( p[i] != 0 ) - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "i=" + toString( i ) ); - } - - /// Verify records and offsets are in sorted order - for ( unsigned i = 0; i < entryCount; i++ ) - { - /// Check chunkRecordNumber is in bounds - if ( totalRecordCount > 0 && entries[i].chunkRecordNumber >= totalRecordCount ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, - "i=" + toString( i ) + " chunkRecordNumber=" + toString( entries[i].chunkRecordNumber ) + - " totalRecordCount=" + toString( totalRecordCount ) ); - } - - /// Check record numbers are strictly increasing - if ( i > 0 && entries[i - 1].chunkRecordNumber >= entries[i].chunkRecordNumber ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, - "i=" + toString( i ) + - " prevChunkRecordNumber=" + toString( entries[i - 1].chunkRecordNumber ) + - " currentChunkRecordNumber=" + toString( entries[i].chunkRecordNumber ) ); - } - - /// Check chunkPhysicalOffset is in bounds - if ( fileSize > 0 && entries[i].chunkPhysicalOffset >= fileSize ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "i=" + toString( i ) + " chunkPhysicalOffset=" + - toString( entries[i].chunkPhysicalOffset ) + - " fileSize=" + toString( fileSize ) ); - } - - /// Check chunk offsets are strictly increasing - if ( i > 0 && entries[i - 1].chunkPhysicalOffset >= entries[i].chunkPhysicalOffset ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, - "i=" + toString( i ) + - " prevChunkPhysicalOffset=" + toString( entries[i - 1].chunkPhysicalOffset ) + - " currentChunkPhysicalOffset=" + toString( entries[i].chunkPhysicalOffset ) ); - } - } -#endif -} - -#ifdef E57_DEBUG -void IndexPacket::dump( int indent, std::ostream &os ) const -{ - os << space( indent ) << "packetType: " << static_cast( packetType ) << std::endl; - os << space( indent ) << "packetFlags: " << static_cast( packetFlags ) << std::endl; - os << space( indent ) << "packetLogicalLengthMinus1: " << packetLogicalLengthMinus1 << std::endl; - os << space( indent ) << "entryCount: " << entryCount << std::endl; - os << space( indent ) << "indexLevel: " << indexLevel << std::endl; - unsigned i; - for ( i = 0; i < entryCount && i < 10; i++ ) - { - os << space( indent ) << "entry[" << i << "]:" << std::endl; - os << space( indent + 4 ) << "chunkRecordNumber: " << entries[i].chunkRecordNumber << std::endl; - os << space( indent + 4 ) << "chunkPhysicalOffset: " << entries[i].chunkPhysicalOffset << std::endl; - } - if ( i < entryCount ) - { - os << space( indent ) << entryCount - i << "more entries unprinted..." << std::endl; - } -} -#endif - -//============================================================================= -// EmptyPacketHeader - -void EmptyPacketHeader::verify( unsigned bufferLength ) const -{ - /// Verify that packet is correct type - if ( packetType != EMPTY_PACKET ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetType=" + toString( packetType ) ); - } - - /// Check packetLength is at least large enough to hold header - unsigned packetLength = packetLogicalLengthMinus1 + 1; - if ( packetLength < sizeof( *this ) ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) ); - } - - /// Check packet length is multiple of 4 - if ( packetLength % 4 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) ); - } - - /// Check actual packet length is large enough. - if ( bufferLength > 0 && packetLength > bufferLength ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, - "packetLength=" + toString( packetLength ) + " bufferLength=" + toString( bufferLength ) ); - } -} - -#ifdef E57_DEBUG -void EmptyPacketHeader::dump( int indent, std::ostream &os ) const -{ - os << space( indent ) << "packetType: " << static_cast( packetType ) << std::endl; - os << space( indent ) << "packetLogicalLengthMinus1: " << packetLogicalLengthMinus1 << std::endl; -} -#endif diff --git a/src/3rdParty/libE57Format/src/Packet.h b/src/3rdParty/libE57Format/src/Packet.h deleted file mode 100644 index 7d202b2cf1..0000000000 --- a/src/3rdParty/libE57Format/src/Packet.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include -#include - -#include "Common.h" - -namespace e57 -{ - class CheckedFile; - class PacketLock; - - /// Packet types (in a compressed vector section) - enum - { - INDEX_PACKET = 0, - DATA_PACKET, - EMPTY_PACKET, - }; - - /// maximum size of CompressedVector binary data packet - constexpr int DATA_PACKET_MAX = ( 64 * 1024 ); - - class PacketReadCache - { - public: - PacketReadCache( CheckedFile *cFile, unsigned packetCount ); - - std::unique_ptr lock( uint64_t packetLogicalOffset, - char *&pkt ); //??? pkt could be const - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ); -#endif - - protected: - /// Only PacketLock can unlock the cache - friend class PacketLock; - void unlock( unsigned cacheIndex ); - - void readPacket( unsigned oldestEntry, uint64_t packetLogicalOffset ); - - struct CacheEntry - { - uint64_t logicalOffset_ = 0; - char buffer_[DATA_PACKET_MAX]; //! No need to init since it's a data buffer - unsigned lastUsed_ = 0; - }; - - unsigned lockCount_ = 0; - unsigned useCount_ = 0; - CheckedFile *cFile_ = nullptr; - - std::vector entries_; - }; - - class PacketLock - { - public: - ~PacketLock(); - - private: - /// Can't be copied or assigned - PacketLock( const PacketLock &plock ); - PacketLock &operator=( const PacketLock &plock ); - - protected: - friend class PacketReadCache; - /// Only PacketReadCache can construct - PacketLock( PacketReadCache *cache, unsigned cacheIndex ); - - PacketReadCache *cache_ = nullptr; - unsigned int cacheIndex_ = 0; - }; - - class DataPacketHeader - { - public: - DataPacketHeader(); - - void reset(); - - void verify( unsigned bufferLength = 0 ) const; //???use - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const; -#endif - const uint8_t packetType = DATA_PACKET; - - uint8_t packetFlags = 0; - uint16_t packetLogicalLengthMinus1 = 0; - uint16_t bytestreamCount = 0; - }; - - class DataPacket - { - public: - DataPacket(); - - void verify( unsigned bufferLength = 0 ) const; - char *getBytestream( unsigned bytestreamNumber, unsigned &byteCount ); - unsigned getBytestreamBufferLength( unsigned bytestreamNumber ); - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const; -#endif - - static constexpr int PayloadSize = DATA_PACKET_MAX - sizeof( DataPacketHeader ); - - DataPacketHeader header; - - uint8_t payload[PayloadSize]; //! No need to init since it's a data buffer - }; -} diff --git a/src/3rdParty/libE57Format/src/ReaderImpl.cpp b/src/3rdParty/libE57Format/src/ReaderImpl.cpp deleted file mode 100644 index 40814e8125..0000000000 --- a/src/3rdParty/libE57Format/src/ReaderImpl.cpp +++ /dev/null @@ -1,1434 +0,0 @@ -/* - * Copyright (c) 2010 Stan Coleby (scoleby@intelisum.com) - * Copyright (c) 2020 PTC Inc. - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "ReaderImpl.h" - -namespace e57 -{ - - ReaderImpl::ReaderImpl( const ustring &filePath ) : - imf_( filePath, "r" ), root_( imf_.root() ), data3D_( root_.get( "/data3D" ) ), - images2D_( root_.get( "/images2D" ) ) - { - } - - ReaderImpl::~ReaderImpl() - { - if ( IsOpen() ) - { - Close(); - } - } - - // This function returns true if the file is open - bool ReaderImpl::IsOpen() const - { - return imf_.isOpen(); - } - - // This function closes the file - bool ReaderImpl::Close() - { - if ( !IsOpen() ) - { - return false; - } - - imf_.close(); - return true; - } - - // This function returns the file header information - bool ReaderImpl::GetE57Root( E57Root &fileHeader ) const - { - if ( !IsOpen() ) - { - return false; - } - - fileHeader = {}; - - fileHeader.formatName = StringNode( root_.get( "formatName" ) ).value(); - fileHeader.versionMajor = (uint32_t)IntegerNode( root_.get( "versionMajor" ) ).value(); - fileHeader.versionMinor = (uint32_t)IntegerNode( root_.get( "versionMinor" ) ).value(); - fileHeader.guid = StringNode( root_.get( "guid" ) ).value(); - if ( root_.isDefined( "e57LibraryVersion" ) ) - { - fileHeader.e57LibraryVersion = StringNode( root_.get( "e57LibraryVersion" ) ).value(); - } - - if ( root_.isDefined( "coordinateMetadata" ) ) - { - fileHeader.coordinateMetadata = StringNode( root_.get( "coordinateMetadata" ) ).value(); - } - - if ( root_.isDefined( "creationDateTime" ) ) - { - StructureNode creationDateTime( root_.get( "creationDateTime" ) ); - fileHeader.creationDateTime.dateTimeValue = FloatNode( creationDateTime.get( "dateTimeValue" ) ).value(); - fileHeader.creationDateTime.isAtomicClockReferenced = - (int32_t)IntegerNode( creationDateTime.get( "isAtomicClockReferenced" ) ).value(); - } - - fileHeader.data3DSize = data3D_.childCount(); - fileHeader.images2DSize = images2D_.childCount(); - - return true; - } - - int64_t ReaderImpl::GetImage2DCount() const - { - return images2D_.childCount(); - } - - // This function returns the Image2Ds header and positions the cursor - bool ReaderImpl::ReadImage2D( int64_t imageIndex, Image2D &image2DHeader ) const - { - if ( !IsOpen() ) - { - return false; - } - if ( ( imageIndex < 0 ) || ( imageIndex >= images2D_.childCount() ) ) - { - return false; - } - - image2DHeader = {}; - - StructureNode image( images2D_.get( imageIndex ) ); - - image2DHeader.guid = StringNode( image.get( "guid" ) ).value(); - - if ( image.isDefined( "name" ) ) - { - image2DHeader.name = StringNode( image.get( "name" ) ).value(); - } - - if ( image.isDefined( "description" ) ) - { - image2DHeader.description = StringNode( image.get( "description" ) ).value(); - } - - if ( image.isDefined( "sensorVendor" ) ) - { - image2DHeader.sensorVendor = StringNode( image.get( "sensorVendor" ) ).value(); - } - if ( image.isDefined( "sensorModel" ) ) - { - image2DHeader.sensorModel = StringNode( image.get( "sensorModel" ) ).value(); - } - if ( image.isDefined( "sensorSerialNumber" ) ) - { - image2DHeader.sensorSerialNumber = StringNode( image.get( "sensorSerialNumber" ) ).value(); - } - - if ( image.isDefined( "associatedData3DGuid" ) ) - { - image2DHeader.associatedData3DGuid = StringNode( image.get( "associatedData3DGuid" ) ).value(); - } - - if ( image.isDefined( "acquisitionDateTime" ) ) - { - StructureNode acquisitionDateTime( image.get( "acquisitionDateTime" ) ); - image2DHeader.acquisitionDateTime.dateTimeValue = - FloatNode( acquisitionDateTime.get( "dateTimeValue" ) ).value(); - image2DHeader.acquisitionDateTime.isAtomicClockReferenced = - (int32_t)IntegerNode( acquisitionDateTime.get( "isAtomicClockReferenced" ) ).value(); - } - - // Get pose structure for scan. - if ( image.isDefined( "pose" ) ) - { - StructureNode pose( image.get( "pose" ) ); - if ( pose.isDefined( "rotation" ) ) - { - StructureNode rotation( pose.get( "rotation" ) ); - image2DHeader.pose.rotation.w = FloatNode( rotation.get( "w" ) ).value(); - image2DHeader.pose.rotation.x = FloatNode( rotation.get( "x" ) ).value(); - image2DHeader.pose.rotation.y = FloatNode( rotation.get( "y" ) ).value(); - image2DHeader.pose.rotation.z = FloatNode( rotation.get( "z" ) ).value(); - } - if ( pose.isDefined( "translation" ) ) - { - StructureNode translation( pose.get( "translation" ) ); - image2DHeader.pose.translation.x = FloatNode( translation.get( "x" ) ).value(); - image2DHeader.pose.translation.y = FloatNode( translation.get( "y" ) ).value(); - image2DHeader.pose.translation.z = FloatNode( translation.get( "z" ) ).value(); - } - } - - if ( image.isDefined( "visualReferenceRepresentation" ) ) - { - StructureNode visualReferenceRepresentation( image.get( "visualReferenceRepresentation" ) ); - - if ( visualReferenceRepresentation.isDefined( "jpegImage" ) ) - { - image2DHeader.visualReferenceRepresentation.jpegImageSize = - BlobNode( visualReferenceRepresentation.get( "jpegImage" ) ).byteCount(); - } - if ( visualReferenceRepresentation.isDefined( "pngImage" ) ) - { - image2DHeader.visualReferenceRepresentation.pngImageSize = - BlobNode( visualReferenceRepresentation.get( "pngImage" ) ).byteCount(); - } - if ( visualReferenceRepresentation.isDefined( "imageMask" ) ) - { - image2DHeader.visualReferenceRepresentation.imageMaskSize = - BlobNode( visualReferenceRepresentation.get( "imageMask" ) ).byteCount(); - } - - image2DHeader.visualReferenceRepresentation.imageHeight = - (int32_t)IntegerNode( visualReferenceRepresentation.get( "imageHeight" ) ).value(); - image2DHeader.visualReferenceRepresentation.imageWidth = - (int32_t)IntegerNode( visualReferenceRepresentation.get( "imageWidth" ) ).value(); - } - - if ( image.isDefined( "pinholeRepresentation" ) ) - { - StructureNode pinholeRepresentation( image.get( "pinholeRepresentation" ) ); - - if ( pinholeRepresentation.isDefined( "jpegImage" ) ) - { - image2DHeader.pinholeRepresentation.jpegImageSize = - BlobNode( pinholeRepresentation.get( "jpegImage" ) ).byteCount(); - } - if ( pinholeRepresentation.isDefined( "pngImage" ) ) - { - image2DHeader.pinholeRepresentation.pngImageSize = - BlobNode( pinholeRepresentation.get( "pngImage" ) ).byteCount(); - } - if ( pinholeRepresentation.isDefined( "imageMask" ) ) - { - image2DHeader.pinholeRepresentation.imageMaskSize = - BlobNode( pinholeRepresentation.get( "imageMask" ) ).byteCount(); - } - - image2DHeader.pinholeRepresentation.focalLength = - FloatNode( pinholeRepresentation.get( "focalLength" ) ).value(); - image2DHeader.pinholeRepresentation.imageHeight = - (int32_t)IntegerNode( pinholeRepresentation.get( "imageHeight" ) ).value(); - image2DHeader.pinholeRepresentation.imageWidth = - (int32_t)IntegerNode( pinholeRepresentation.get( "imageWidth" ) ).value(); - - image2DHeader.pinholeRepresentation.pixelHeight = - FloatNode( pinholeRepresentation.get( "pixelHeight" ) ).value(); - image2DHeader.pinholeRepresentation.pixelWidth = - FloatNode( pinholeRepresentation.get( "pixelWidth" ) ).value(); - image2DHeader.pinholeRepresentation.principalPointX = - FloatNode( pinholeRepresentation.get( "principalPointX" ) ).value(); - image2DHeader.pinholeRepresentation.principalPointY = - FloatNode( pinholeRepresentation.get( "principalPointY" ) ).value(); - } - else if ( image.isDefined( "sphericalRepresentation" ) ) - { - StructureNode sphericalRepresentation( image.get( "sphericalRepresentation" ) ); - - if ( sphericalRepresentation.isDefined( "jpegImage" ) ) - { - image2DHeader.sphericalRepresentation.jpegImageSize = - BlobNode( sphericalRepresentation.get( "jpegImage" ) ).byteCount(); - } - if ( sphericalRepresentation.isDefined( "pngImage" ) ) - { - image2DHeader.sphericalRepresentation.pngImageSize = - BlobNode( sphericalRepresentation.get( "pngImage" ) ).byteCount(); - } - if ( sphericalRepresentation.isDefined( "imageMask" ) ) - { - image2DHeader.sphericalRepresentation.imageMaskSize = - BlobNode( sphericalRepresentation.get( "imageMask" ) ).byteCount(); - } - - image2DHeader.sphericalRepresentation.imageHeight = - (int32_t)IntegerNode( sphericalRepresentation.get( "imageHeight" ) ).value(); - image2DHeader.sphericalRepresentation.imageWidth = - (int32_t)IntegerNode( sphericalRepresentation.get( "imageWidth" ) ).value(); - - image2DHeader.sphericalRepresentation.pixelHeight = - FloatNode( sphericalRepresentation.get( "pixelHeight" ) ).value(); - image2DHeader.sphericalRepresentation.pixelWidth = - FloatNode( sphericalRepresentation.get( "pixelWidth" ) ).value(); - } - else if ( image.isDefined( "cylindricalRepresentation" ) ) - { - StructureNode cylindricalRepresentation( image.get( "cylindricalRepresentation" ) ); - - if ( cylindricalRepresentation.isDefined( "jpegImage" ) ) - { - image2DHeader.cylindricalRepresentation.jpegImageSize = - BlobNode( cylindricalRepresentation.get( "jpegImage" ) ).byteCount(); - } - if ( cylindricalRepresentation.isDefined( "pngImage" ) ) - { - image2DHeader.cylindricalRepresentation.pngImageSize = - BlobNode( cylindricalRepresentation.get( "pngImage" ) ).byteCount(); - } - if ( cylindricalRepresentation.isDefined( "imageMask" ) ) - { - image2DHeader.cylindricalRepresentation.imageMaskSize = - BlobNode( cylindricalRepresentation.get( "imageMask" ) ).byteCount(); - } - - image2DHeader.cylindricalRepresentation.imageHeight = - (int32_t)IntegerNode( cylindricalRepresentation.get( "imageHeight" ) ).value(); - image2DHeader.cylindricalRepresentation.imageWidth = - (int32_t)IntegerNode( cylindricalRepresentation.get( "imageWidth" ) ).value(); - - image2DHeader.cylindricalRepresentation.pixelHeight = - FloatNode( cylindricalRepresentation.get( "pixelHeight" ) ).value(); - image2DHeader.cylindricalRepresentation.pixelWidth = - FloatNode( cylindricalRepresentation.get( "pixelWidth" ) ).value(); - image2DHeader.cylindricalRepresentation.principalPointY = - FloatNode( cylindricalRepresentation.get( "principalPointY" ) ).value(); - image2DHeader.cylindricalRepresentation.radius = - FloatNode( cylindricalRepresentation.get( "radius" ) ).value(); - } - - return true; - } - - // This function reads one of the image blobs - int64_t ReaderImpl::ReadImage2DNode( StructureNode image, Image2DType imageType, void *pBuffer, int64_t start, - int64_t count ) const - { - int64_t transferred = 0; - switch ( imageType ) - { - case E57_NO_IMAGE: - { - return 0; - } - case E57_JPEG_IMAGE: - { - if ( image.isDefined( "jpegImage" ) ) - { - BlobNode jpegImage( image.get( "jpegImage" ) ); - jpegImage.read( (uint8_t *)pBuffer, start, (size_t)count ); - transferred = count; - } - break; - } - case E57_PNG_IMAGE: - { - if ( image.isDefined( "pngImage" ) ) - { - BlobNode pngImage( image.get( "pngImage" ) ); - pngImage.read( (uint8_t *)pBuffer, start, (size_t)count ); - transferred = count; - } - break; - } - case E57_PNG_IMAGE_MASK: - { - if ( image.isDefined( "imageMask" ) ) - { - BlobNode imageMask( image.get( "imageMask" ) ); - imageMask.read( (uint8_t *)pBuffer, start, (size_t)count ); - transferred = count; - } - break; - } - } - return transferred; - } - - // This function reads one of the image blobs - bool ReaderImpl::GetImage2DNodeSizes( StructureNode image, Image2DType &imageType, int64_t &imageWidth, - int64_t &imageHeight, int64_t &imageSize, Image2DType &imageMaskType ) const - { - imageWidth = 0; - imageHeight = 0; - imageSize = 0; - imageType = E57_NO_IMAGE; - imageMaskType = E57_NO_IMAGE; - - if ( image.isDefined( "imageWidth" ) ) - { - imageWidth = IntegerNode( image.get( "imageWidth" ) ).value(); - } - else - { - return false; - } - - if ( image.isDefined( "imageHeight" ) ) - { - imageHeight = IntegerNode( image.get( "imageHeight" ) ).value(); - } - else - { - return false; - } - - if ( image.isDefined( "jpegImage" ) ) - { - imageSize = BlobNode( image.get( "jpegImage" ) ).byteCount(); - imageType = E57_JPEG_IMAGE; - } - else if ( image.isDefined( "pngImage" ) ) - { - imageSize = BlobNode( image.get( "pngImage" ) ).byteCount(); - imageType = E57_PNG_IMAGE; - } - - if ( image.isDefined( "imageMask" ) ) - { - if ( imageType == E57_NO_IMAGE ) - { - imageSize = BlobNode( image.get( "imageMask" ) ).byteCount(); - imageType = E57_PNG_IMAGE_MASK; - } - imageMaskType = E57_PNG_IMAGE_MASK; - } - return true; - } - - // This function returns the image sizes - bool ReaderImpl::GetImage2DSizes( int64_t imageIndex, Image2DProjection &imageProjection, Image2DType &imageType, - int64_t &imageWidth, int64_t &imageHeight, int64_t &imageSize, - Image2DType &imageMaskType, Image2DType &imageVisualType ) const - { - if ( ( imageIndex < 0 ) || ( imageIndex >= images2D_.childCount() ) ) - { - return false; - } - - imageProjection = E57_NO_PROJECTION; - imageType = E57_NO_IMAGE; - imageMaskType = E57_NO_IMAGE; - imageVisualType = E57_NO_IMAGE; - - bool ret = false; - StructureNode image( images2D_.get( imageIndex ) ); - - if ( image.isDefined( "visualReferenceRepresentation" ) ) - { - imageProjection = E57_VISUAL; - StructureNode visualReferenceRepresentation( image.get( "visualReferenceRepresentation" ) ); - ret = GetImage2DNodeSizes( visualReferenceRepresentation, imageType, imageWidth, imageHeight, imageSize, - imageMaskType ); - imageVisualType = imageType; - } - - if ( image.isDefined( "pinholeRepresentation" ) ) - { - imageProjection = E57_PINHOLE; - StructureNode pinholeRepresentation( image.get( "pinholeRepresentation" ) ); - ret = - GetImage2DNodeSizes( pinholeRepresentation, imageType, imageWidth, imageHeight, imageSize, imageMaskType ); - } - else if ( image.isDefined( "sphericalRepresentation" ) ) - { - imageProjection = E57_SPHERICAL; - StructureNode sphericalRepresentation( image.get( "sphericalRepresentation" ) ); - ret = GetImage2DNodeSizes( sphericalRepresentation, imageType, imageWidth, imageHeight, imageSize, - imageMaskType ); - } - else if ( image.isDefined( "cylindricalRepresentation" ) ) - { - imageProjection = E57_CYLINDRICAL; - StructureNode cylindricalRepresentation( image.get( "cylindricalRepresentation" ) ); - ret = GetImage2DNodeSizes( cylindricalRepresentation, imageType, imageWidth, imageHeight, imageSize, - imageMaskType ); - } - - return ret; - } - - // This function reads the block - int64_t ReaderImpl::ReadImage2DData( int64_t imageIndex, Image2DProjection imageProjection, Image2DType imageType, - void *pBuffer, int64_t start, int64_t count ) const - { - if ( ( imageIndex < 0 ) || ( imageIndex >= images2D_.childCount() ) ) - { - return 0; - } - - int64_t transferred = 0; - StructureNode image( images2D_.get( imageIndex ) ); - - switch ( imageProjection ) - { - case E57_NO_PROJECTION: - return 0; - case E57_VISUAL: - if ( image.isDefined( "visualReferenceRepresentation" ) ) - { - StructureNode visualReferenceRepresentation( image.get( "visualReferenceRepresentation" ) ); - transferred = ReadImage2DNode( visualReferenceRepresentation, imageType, pBuffer, start, count ); - } - break; - - case E57_PINHOLE: - if ( image.isDefined( "pinholeRepresentation" ) ) - { - StructureNode pinholeRepresentation( image.get( "pinholeRepresentation" ) ); - transferred = ReadImage2DNode( pinholeRepresentation, imageType, pBuffer, start, count ); - } - break; - - case E57_SPHERICAL: - if ( image.isDefined( "sphericalRepresentation" ) ) - { - StructureNode sphericalRepresentation( image.get( "sphericalRepresentation" ) ); - transferred = ReadImage2DNode( sphericalRepresentation, imageType, pBuffer, start, count ); - } - break; - - case E57_CYLINDRICAL: - if ( image.isDefined( "cylindricalRepresentation" ) ) - { - StructureNode cylindricalRepresentation( image.get( "cylindricalRepresentation" ) ); - transferred = ReadImage2DNode( cylindricalRepresentation, imageType, pBuffer, start, count ); - } - break; - } - - return transferred; - } - - int64_t ReaderImpl::GetData3DCount() const - { - return data3D_.childCount(); - } - - StructureNode ReaderImpl::GetRawE57Root() const - { - return root_; - } - - VectorNode ReaderImpl::GetRawData3D() const - { - return data3D_; - } - - VectorNode ReaderImpl::GetRawImages2D() const - { - return images2D_; - } - - ImageFile ReaderImpl::GetRawIMF() const - { - return imf_; - } - - bool ReaderImpl::ReadData3D( int64_t dataIndex, Data3D &data3DHeader ) const - { - if ( !IsOpen() ) - { - return false; - } - if ( ( dataIndex < 0 ) || ( dataIndex >= data3D_.childCount() ) ) - { - return false; - } - - data3DHeader = {}; - - StructureNode scan( data3D_.get( dataIndex ) ); - CompressedVectorNode points( scan.get( "points" ) ); - - data3DHeader.pointsSize = points.childCount(); - StructureNode proto( points.prototype() ); - - data3DHeader.guid = StringNode( scan.get( "guid" ) ).value(); - - if ( scan.isDefined( "name" ) ) - { - data3DHeader.name = StringNode( scan.get( "name" ) ).value(); - } - if ( scan.isDefined( "description" ) ) - { - data3DHeader.description = StringNode( scan.get( "description" ) ).value(); - } - - if ( scan.isDefined( "originalGuids" ) ) - { - VectorNode originalGuids( scan.get( "originalGuids" ) ); - if ( originalGuids.childCount() > 0 ) - { - data3DHeader.originalGuids.clear(); - int i; - for ( i = 0; i < originalGuids.childCount(); i++ ) - { - ustring str = StringNode( originalGuids.get( i ) ).value(); - data3DHeader.originalGuids.push_back( str ); - } - } - } - - // Get various sensor and version strings to scan. - if ( scan.isDefined( "sensorVendor" ) ) - { - data3DHeader.sensorVendor = StringNode( scan.get( "sensorVendor" ) ).value(); - } - if ( scan.isDefined( "sensorModel" ) ) - { - data3DHeader.sensorModel = StringNode( scan.get( "sensorModel" ) ).value(); - } - if ( scan.isDefined( "sensorSerialNumber" ) ) - { - data3DHeader.sensorSerialNumber = StringNode( scan.get( "sensorSerialNumber" ) ).value(); - } - if ( scan.isDefined( "sensorHardwareVersion" ) ) - { - data3DHeader.sensorHardwareVersion = StringNode( scan.get( "sensorHardwareVersion" ) ).value(); - } - if ( scan.isDefined( "sensorSoftwareVersion" ) ) - { - data3DHeader.sensorSoftwareVersion = StringNode( scan.get( "sensorSoftwareVersion" ) ).value(); - } - if ( scan.isDefined( "sensorFirmwareVersion" ) ) - { - data3DHeader.sensorFirmwareVersion = StringNode( scan.get( "sensorFirmwareVersion" ) ).value(); - } - - // Get temp/humidity to scan. - if ( scan.isDefined( "temperature" ) ) - { - data3DHeader.temperature = (float)FloatNode( scan.get( "temperature" ) ).value(); - } - if ( scan.isDefined( "relativeHumidity" ) ) - { - data3DHeader.relativeHumidity = (float)FloatNode( scan.get( "relativeHumidity" ) ).value(); - } - if ( scan.isDefined( "atmosphericPressure" ) ) - { - data3DHeader.atmosphericPressure = (float)FloatNode( scan.get( "atmosphericPressure" ) ).value(); - } - - if ( scan.isDefined( "indexBounds" ) ) - { - StructureNode ibox( scan.get( "indexBounds" ) ); - if ( ibox.isDefined( "rowMaximum" ) ) - { - data3DHeader.indexBounds.rowMinimum = IntegerNode( ibox.get( "rowMinimum" ) ).value(); - data3DHeader.indexBounds.rowMaximum = IntegerNode( ibox.get( "rowMaximum" ) ).value(); - } - if ( ibox.isDefined( "columnMaximum" ) ) - { - data3DHeader.indexBounds.columnMinimum = IntegerNode( ibox.get( "columnMinimum" ) ).value(); - data3DHeader.indexBounds.columnMaximum = IntegerNode( ibox.get( "columnMaximum" ) ).value(); - } - if ( ibox.isDefined( "returnMaximum" ) ) - { - data3DHeader.indexBounds.returnMinimum = IntegerNode( ibox.get( "returnMinimum" ) ).value(); - data3DHeader.indexBounds.returnMaximum = IntegerNode( ibox.get( "returnMaximum" ) ).value(); - } - } - - if ( scan.isDefined( "pointGroupingSchemes" ) ) - { - StructureNode pointGroupingSchemes( scan.get( "pointGroupingSchemes" ) ); - if ( pointGroupingSchemes.isDefined( "groupingByLine" ) ) - { - StructureNode groupingByLine( pointGroupingSchemes.get( "groupingByLine" ) ); - - data3DHeader.pointGroupingSchemes.groupingByLine.idElementName = - StringNode( groupingByLine.get( "idElementName" ) ).value(); - - CompressedVectorNode groups( groupingByLine.get( "groups" ) ); - data3DHeader.pointGroupingSchemes.groupingByLine.groupsSize = groups.childCount(); - - StructureNode lineGroupRecord( groups.prototype() ); - if ( lineGroupRecord.isDefined( "pointCount" ) ) - { - data3DHeader.pointGroupingSchemes.groupingByLine.pointCountSize = - IntegerNode( lineGroupRecord.get( "pointCount" ) ).maximum(); - } - } - } - - // Get Cartesian bounding box to scan. - if ( scan.isDefined( "cartesianBounds" ) ) - { - StructureNode bbox( scan.get( "cartesianBounds" ) ); - if ( bbox.get( "xMinimum" ).type() == E57_SCALED_INTEGER ) - { - data3DHeader.cartesianBounds.xMinimum = (double)ScaledIntegerNode( bbox.get( "xMinimum" ) ).scaledValue(); - data3DHeader.cartesianBounds.xMaximum = (double)ScaledIntegerNode( bbox.get( "xMaximum" ) ).scaledValue(); - data3DHeader.cartesianBounds.yMinimum = (double)ScaledIntegerNode( bbox.get( "yMinimum" ) ).scaledValue(); - data3DHeader.cartesianBounds.yMaximum = (double)ScaledIntegerNode( bbox.get( "yMaximum" ) ).scaledValue(); - data3DHeader.cartesianBounds.zMinimum = (double)ScaledIntegerNode( bbox.get( "zMinimum" ) ).scaledValue(); - data3DHeader.cartesianBounds.zMaximum = (double)ScaledIntegerNode( bbox.get( "zMaximum" ) ).scaledValue(); - } - else if ( bbox.get( "xMinimum" ).type() == E57_FLOAT ) - { - data3DHeader.cartesianBounds.xMinimum = FloatNode( bbox.get( "xMinimum" ) ).value(); - data3DHeader.cartesianBounds.xMaximum = FloatNode( bbox.get( "xMaximum" ) ).value(); - data3DHeader.cartesianBounds.yMinimum = FloatNode( bbox.get( "yMinimum" ) ).value(); - data3DHeader.cartesianBounds.yMaximum = FloatNode( bbox.get( "yMaximum" ) ).value(); - data3DHeader.cartesianBounds.zMinimum = FloatNode( bbox.get( "zMinimum" ) ).value(); - data3DHeader.cartesianBounds.zMaximum = FloatNode( bbox.get( "zMaximum" ) ).value(); - } - } - - if ( scan.isDefined( "sphericalBounds" ) ) - { - StructureNode sbox( scan.get( "sphericalBounds" ) ); - if ( sbox.get( "rangeMinimum" ).type() == E57_SCALED_INTEGER ) - { - data3DHeader.sphericalBounds.rangeMinimum = - (double)ScaledIntegerNode( sbox.get( "rangeMinimum" ) ).scaledValue(); - data3DHeader.sphericalBounds.rangeMaximum = - (double)ScaledIntegerNode( sbox.get( "rangeMaximum" ) ).scaledValue(); - } - else if ( sbox.get( "rangeMinimum" ).type() == E57_FLOAT ) - { - data3DHeader.sphericalBounds.rangeMinimum = FloatNode( sbox.get( "rangeMinimum" ) ).value(); - data3DHeader.sphericalBounds.rangeMaximum = FloatNode( sbox.get( "rangeMaximum" ) ).value(); - } - - if ( sbox.get( "elevationMinimum" ).type() == E57_SCALED_INTEGER ) - { - data3DHeader.sphericalBounds.elevationMinimum = - (double)ScaledIntegerNode( sbox.get( "elevationMinimum" ) ).scaledValue(); - data3DHeader.sphericalBounds.elevationMaximum = - (double)ScaledIntegerNode( sbox.get( "elevationMaximum" ) ).scaledValue(); - } - else if ( sbox.get( "elevationMinimum" ).type() == E57_FLOAT ) - { - data3DHeader.sphericalBounds.elevationMinimum = FloatNode( sbox.get( "elevationMinimum" ) ).value(); - data3DHeader.sphericalBounds.elevationMaximum = FloatNode( sbox.get( "elevationMaximum" ) ).value(); - } - - if ( sbox.get( "azimuthStart" ).type() == E57_SCALED_INTEGER ) - { - data3DHeader.sphericalBounds.azimuthStart = - (double)ScaledIntegerNode( sbox.get( "azimuthStart" ) ).scaledValue(); - data3DHeader.sphericalBounds.azimuthEnd = - (double)ScaledIntegerNode( sbox.get( "azimuthEnd" ) ).scaledValue(); - } - else if ( sbox.get( "azimuthStart" ).type() == E57_FLOAT ) - { - data3DHeader.sphericalBounds.azimuthStart = FloatNode( sbox.get( "azimuthStart" ) ).value(); - data3DHeader.sphericalBounds.azimuthEnd = FloatNode( sbox.get( "azimuthEnd" ) ).value(); - } - } - - // Get pose structure for scan. - if ( scan.isDefined( "pose" ) ) - { - StructureNode pose( scan.get( "pose" ) ); - if ( pose.isDefined( "rotation" ) ) - { - StructureNode rotation( pose.get( "rotation" ) ); - data3DHeader.pose.rotation.w = FloatNode( rotation.get( "w" ) ).value(); - data3DHeader.pose.rotation.x = FloatNode( rotation.get( "x" ) ).value(); - data3DHeader.pose.rotation.y = FloatNode( rotation.get( "y" ) ).value(); - data3DHeader.pose.rotation.z = FloatNode( rotation.get( "z" ) ).value(); - } - if ( pose.isDefined( "translation" ) ) - { - StructureNode translation( pose.get( "translation" ) ); - data3DHeader.pose.translation.x = FloatNode( translation.get( "x" ) ).value(); - data3DHeader.pose.translation.y = FloatNode( translation.get( "y" ) ).value(); - data3DHeader.pose.translation.z = FloatNode( translation.get( "z" ) ).value(); - } - } - - // Get start/stop acquisition times to scan. - if ( scan.isDefined( "acquisitionStart" ) ) - { - StructureNode acquisitionStart( scan.get( "acquisitionStart" ) ); - data3DHeader.acquisitionStart.dateTimeValue = FloatNode( acquisitionStart.get( "dateTimeValue" ) ).value(); - data3DHeader.acquisitionStart.isAtomicClockReferenced = - (int32_t)IntegerNode( acquisitionStart.get( "isAtomicClockReferenced" ) ).value(); - } - - if ( scan.isDefined( "acquisitionEnd" ) ) - { - StructureNode acquisitionEnd( scan.get( "acquisitionEnd" ) ); - data3DHeader.acquisitionEnd.dateTimeValue = FloatNode( acquisitionEnd.get( "dateTimeValue" ) ).value(); - data3DHeader.acquisitionEnd.isAtomicClockReferenced = - (int32_t)IntegerNode( acquisitionEnd.get( "isAtomicClockReferenced" ) ).value(); - } - - // Get a prototype of datatypes that will be stored in points record. - data3DHeader.pointFields.cartesianXField = proto.isDefined( "cartesianX" ); - data3DHeader.pointFields.cartesianYField = proto.isDefined( "cartesianY" ); - data3DHeader.pointFields.cartesianZField = proto.isDefined( "cartesianZ" ); - data3DHeader.pointFields.cartesianInvalidStateField = proto.isDefined( "cartesianInvalidState" ); - - data3DHeader.pointFields.pointRangeScaledInteger = E57_NOT_SCALED_USE_FLOAT; // FloatNode - data3DHeader.pointFields.pointRangeMinimum = 0.; - data3DHeader.pointFields.pointRangeMaximum = 0.; - - if ( proto.isDefined( "cartesianX" ) ) - { - if ( proto.get( "cartesianX" ).type() == E57_SCALED_INTEGER ) - { - double scale = ScaledIntegerNode( proto.get( "cartesianX" ) ).scale(); - double offset = ScaledIntegerNode( proto.get( "cartesianX" ) ).offset(); - int64_t minimum = ScaledIntegerNode( proto.get( "cartesianX" ) ).minimum(); - int64_t maximum = ScaledIntegerNode( proto.get( "cartesianX" ) ).maximum(); - data3DHeader.pointFields.pointRangeMinimum = (double)minimum * scale + offset; - data3DHeader.pointFields.pointRangeMaximum = (double)maximum * scale + offset; - data3DHeader.pointFields.pointRangeScaledInteger = scale; - } - else if ( proto.get( "cartesianX" ).type() == E57_FLOAT ) - { - data3DHeader.pointFields.pointRangeMinimum = FloatNode( proto.get( "cartesianX" ) ).minimum(); - data3DHeader.pointFields.pointRangeMaximum = FloatNode( proto.get( "cartesianX" ) ).maximum(); - data3DHeader.pointFields.pointRangeScaledInteger = E57_NOT_SCALED_USE_FLOAT; - } - } - else if ( proto.isDefined( "sphericalRange" ) ) - { - if ( proto.get( "sphericalRange" ).type() == E57_SCALED_INTEGER ) - { - double scale = ScaledIntegerNode( proto.get( "sphericalRange" ) ).scale(); - double offset = ScaledIntegerNode( proto.get( "sphericalRange" ) ).offset(); - int64_t minimum = ScaledIntegerNode( proto.get( "sphericalRange" ) ).minimum(); - int64_t maximum = ScaledIntegerNode( proto.get( "sphericalRange" ) ).maximum(); - data3DHeader.pointFields.pointRangeMinimum = (double)minimum * scale + offset; - data3DHeader.pointFields.pointRangeMaximum = (double)maximum * scale + offset; - data3DHeader.pointFields.pointRangeScaledInteger = scale; - } - else if ( proto.get( "sphericalRange" ).type() == E57_FLOAT ) - { - data3DHeader.pointFields.pointRangeMinimum = FloatNode( proto.get( "sphericalRange" ) ).minimum(); - data3DHeader.pointFields.pointRangeMaximum = FloatNode( proto.get( "sphericalRange" ) ).maximum(); - data3DHeader.pointFields.pointRangeScaledInteger = E57_NOT_SCALED_USE_FLOAT; - } - } - - data3DHeader.pointFields.sphericalRangeField = proto.isDefined( "sphericalRange" ); - data3DHeader.pointFields.sphericalAzimuthField = proto.isDefined( "sphericalAzimuth" ); - data3DHeader.pointFields.sphericalElevationField = proto.isDefined( "sphericalElevation" ); - data3DHeader.pointFields.sphericalInvalidStateField = proto.isDefined( "sphericalInvalidState" ); - - data3DHeader.pointFields.angleScaledInteger = E57_NOT_SCALED_USE_FLOAT; // FloatNode - data3DHeader.pointFields.angleMinimum = 0.; - data3DHeader.pointFields.angleMaximum = 0.; - - if ( proto.isDefined( "sphericalAzimuth" ) ) - { - if ( proto.get( "sphericalAzimuth" ).type() == E57_SCALED_INTEGER ) - { - double scale = ScaledIntegerNode( proto.get( "sphericalAzimuth" ) ).scale(); - double offset = ScaledIntegerNode( proto.get( "sphericalAzimuth" ) ).offset(); - int64_t minimum = ScaledIntegerNode( proto.get( "sphericalAzimuth" ) ).minimum(); - int64_t maximum = ScaledIntegerNode( proto.get( "sphericalAzimuth" ) ).maximum(); - data3DHeader.pointFields.angleMinimum = (double)minimum * scale + offset; - data3DHeader.pointFields.angleMaximum = (double)maximum * scale + offset; - data3DHeader.pointFields.angleScaledInteger = scale; - } - else if ( proto.get( "sphericalAzimuth" ).type() == E57_FLOAT ) - { - data3DHeader.pointFields.angleMinimum = FloatNode( proto.get( "sphericalAzimuth" ) ).minimum(); - data3DHeader.pointFields.angleMaximum = FloatNode( proto.get( "sphericalAzimuth" ) ).maximum(); - data3DHeader.pointFields.angleScaledInteger = E57_NOT_SCALED_USE_FLOAT; - } - } - - data3DHeader.pointFields.rowIndexField = proto.isDefined( "rowIndex" ); - data3DHeader.pointFields.columnIndexField = proto.isDefined( "columnIndex" ); - data3DHeader.pointFields.rowIndexMaximum = 0; - data3DHeader.pointFields.columnIndexMaximum = 0; - - if ( proto.isDefined( "rowIndex" ) ) - { - data3DHeader.pointFields.rowIndexMaximum = (uint32_t)IntegerNode( proto.get( "rowIndex" ) ).maximum(); - } - - if ( proto.isDefined( "columnIndex" ) ) - { - data3DHeader.pointFields.columnIndexMaximum = (uint32_t)IntegerNode( proto.get( "columnIndex" ) ).maximum(); - } - - data3DHeader.pointFields.returnIndexField = proto.isDefined( "returnIndex" ); - data3DHeader.pointFields.returnCountField = proto.isDefined( "returnCount" ); - data3DHeader.pointFields.returnMaximum = 0; - - if ( proto.isDefined( "returnIndex" ) ) - { - data3DHeader.pointFields.returnMaximum = (uint8_t)IntegerNode( proto.get( "returnIndex" ) ).maximum(); - } - - data3DHeader.pointFields.timeStampField = proto.isDefined( "timeStamp" ); - data3DHeader.pointFields.isTimeStampInvalidField = proto.isDefined( "isTimeStampInvalid" ); - data3DHeader.pointFields.timeMaximum = 0.; - data3DHeader.pointFields.timeMinimum = 0.; - data3DHeader.pointFields.timeScaledInteger = E57_NOT_SCALED_USE_FLOAT; - - if ( proto.isDefined( "timeStamp" ) ) - { - if ( proto.get( "timeStamp" ).type() == E57_INTEGER ) - { - data3DHeader.pointFields.timeMaximum = (double)IntegerNode( proto.get( "timeStamp" ) ).maximum(); - data3DHeader.pointFields.timeMinimum = (double)IntegerNode( proto.get( "timeStamp" ) ).minimum(); - data3DHeader.pointFields.timeScaledInteger = E57_NOT_SCALED_USE_FLOAT; - } - else if ( proto.get( "timeStamp" ).type() == E57_SCALED_INTEGER ) - { - double scale = ScaledIntegerNode( proto.get( "timeStamp" ) ).scale(); - double offset = ScaledIntegerNode( proto.get( "timeStamp" ) ).offset(); - int64_t minimum = ScaledIntegerNode( proto.get( "timeStamp" ) ).minimum(); - int64_t maximum = ScaledIntegerNode( proto.get( "timeStamp" ) ).maximum(); - data3DHeader.pointFields.timeMinimum = (double)minimum * scale + offset; - data3DHeader.pointFields.timeMaximum = (double)maximum * scale + offset; - data3DHeader.pointFields.timeScaledInteger = scale; - } - else if ( proto.get( "timeStamp" ).type() == E57_FLOAT ) - { - data3DHeader.pointFields.timeMinimum = FloatNode( proto.get( "timeStamp" ) ).minimum(); - data3DHeader.pointFields.timeMaximum = FloatNode( proto.get( "timeStamp" ) ).maximum(); - data3DHeader.pointFields.timeScaledInteger = E57_NOT_SCALED_USE_FLOAT; - } - } - - data3DHeader.pointFields.intensityField = proto.isDefined( "intensity" ); - data3DHeader.pointFields.isIntensityInvalidField = proto.isDefined( "isIntensityInvalid" ); - data3DHeader.intensityLimits.intensityMinimum = 0.; - data3DHeader.intensityLimits.intensityMaximum = 0.; - data3DHeader.pointFields.intensityScaledInteger = E57_NOT_SCALED_USE_FLOAT; - - if ( scan.isDefined( "intensityLimits" ) ) - { - StructureNode intbox( scan.get( "intensityLimits" ) ); - if ( intbox.get( "intensityMaximum" ).type() == E57_SCALED_INTEGER ) - { - data3DHeader.intensityLimits.intensityMaximum = - (double)ScaledIntegerNode( intbox.get( "intensityMaximum" ) ).scaledValue(); - data3DHeader.intensityLimits.intensityMinimum = - (double)ScaledIntegerNode( intbox.get( "intensityMinimum" ) ).scaledValue(); - } - else if ( intbox.get( "intensityMaximum" ).type() == E57_FLOAT ) - { - data3DHeader.intensityLimits.intensityMaximum = FloatNode( intbox.get( "intensityMaximum" ) ).value(); - data3DHeader.intensityLimits.intensityMinimum = FloatNode( intbox.get( "intensityMinimum" ) ).value(); - } - else if ( intbox.get( "intensityMaximum" ).type() == E57_INTEGER ) - { - data3DHeader.intensityLimits.intensityMaximum = - (double)IntegerNode( intbox.get( "intensityMaximum" ) ).value(); - data3DHeader.intensityLimits.intensityMinimum = - (double)IntegerNode( intbox.get( "intensityMinimum" ) ).value(); - } - } - if ( proto.isDefined( "intensity" ) ) - { - if ( proto.get( "intensity" ).type() == E57_INTEGER ) - { - if ( data3DHeader.intensityLimits.intensityMaximum == 0. ) - { - data3DHeader.intensityLimits.intensityMinimum = - (double)IntegerNode( proto.get( "intensity" ) ).minimum(); - data3DHeader.intensityLimits.intensityMaximum = - (double)IntegerNode( proto.get( "intensity" ) ).maximum(); - } - data3DHeader.pointFields.intensityScaledInteger = E57_NOT_SCALED_USE_INTEGER; - } - else if ( proto.get( "intensity" ).type() == E57_SCALED_INTEGER ) - { - double scale = ScaledIntegerNode( proto.get( "intensity" ) ).scale(); - double offset = ScaledIntegerNode( proto.get( "intensity" ) ).offset(); - - if ( data3DHeader.intensityLimits.intensityMaximum == 0. ) - { - int64_t minimum = ScaledIntegerNode( proto.get( "intensity" ) ).minimum(); - int64_t maximum = ScaledIntegerNode( proto.get( "intensity" ) ).maximum(); - data3DHeader.intensityLimits.intensityMinimum = (double)minimum * scale + offset; - data3DHeader.intensityLimits.intensityMaximum = (double)maximum * scale + offset; - } - data3DHeader.pointFields.intensityScaledInteger = scale; - } - else if ( proto.get( "intensity" ).type() == E57_FLOAT ) - { - if ( data3DHeader.intensityLimits.intensityMaximum == 0. ) - { - data3DHeader.intensityLimits.intensityMinimum = FloatNode( proto.get( "intensity" ) ).minimum(); - data3DHeader.intensityLimits.intensityMaximum = FloatNode( proto.get( "intensity" ) ).maximum(); - } - data3DHeader.pointFields.intensityScaledInteger = E57_NOT_SCALED_USE_FLOAT; - } - } - - data3DHeader.pointFields.colorRedField = proto.isDefined( "colorRed" ); - data3DHeader.pointFields.colorGreenField = proto.isDefined( "colorGreen" ); - data3DHeader.pointFields.colorBlueField = proto.isDefined( "colorBlue" ); - data3DHeader.pointFields.isColorInvalidField = proto.isDefined( "isColorInvalid" ); - - data3DHeader.colorLimits.colorRedMinimum = 0.; - data3DHeader.colorLimits.colorRedMaximum = 0.; - data3DHeader.colorLimits.colorGreenMinimum = 0.; - data3DHeader.colorLimits.colorGreenMaximum = 0.; - data3DHeader.colorLimits.colorBlueMinimum = 0.; - data3DHeader.colorLimits.colorBlueMaximum = 0.; - - if ( scan.isDefined( "colorLimits" ) ) - { - StructureNode colorbox( scan.get( "colorLimits" ) ); - if ( colorbox.get( "colorRedMaximum" ).type() == E57_SCALED_INTEGER ) - { - data3DHeader.colorLimits.colorRedMaximum = - (double)ScaledIntegerNode( colorbox.get( "colorRedMaximum" ) ).scaledValue(); - data3DHeader.colorLimits.colorRedMinimum = - (double)ScaledIntegerNode( colorbox.get( "colorRedMinimum" ) ).scaledValue(); - data3DHeader.colorLimits.colorGreenMaximum = - (double)ScaledIntegerNode( colorbox.get( "colorGreenMaximum" ) ).scaledValue(); - data3DHeader.colorLimits.colorGreenMinimum = - (double)ScaledIntegerNode( colorbox.get( "colorGreenMinimum" ) ).scaledValue(); - data3DHeader.colorLimits.colorBlueMaximum = - (double)ScaledIntegerNode( colorbox.get( "colorBlueMaximum" ) ).scaledValue(); - data3DHeader.colorLimits.colorBlueMinimum = - (double)ScaledIntegerNode( colorbox.get( "colorBlueMinimum" ) ).scaledValue(); - } - else if ( colorbox.get( "colorRedMaximum" ).type() == E57_FLOAT ) - { - data3DHeader.colorLimits.colorRedMaximum = FloatNode( colorbox.get( "colorRedMaximum" ) ).value(); - data3DHeader.colorLimits.colorRedMinimum = FloatNode( colorbox.get( "colorRedMinimum" ) ).value(); - data3DHeader.colorLimits.colorGreenMaximum = FloatNode( colorbox.get( "colorGreenMaximum" ) ).value(); - data3DHeader.colorLimits.colorGreenMinimum = FloatNode( colorbox.get( "colorGreenMinimum" ) ).value(); - data3DHeader.colorLimits.colorBlueMaximum = FloatNode( colorbox.get( "colorBlueMaximum" ) ).value(); - data3DHeader.colorLimits.colorBlueMinimum = FloatNode( colorbox.get( "colorBlueMinimum" ) ).value(); - } - else if ( colorbox.get( "colorRedMaximum" ).type() == E57_INTEGER ) - { - data3DHeader.colorLimits.colorRedMaximum = (double)IntegerNode( colorbox.get( "colorRedMaximum" ) ).value(); - data3DHeader.colorLimits.colorRedMinimum = (double)IntegerNode( colorbox.get( "colorRedMinimum" ) ).value(); - data3DHeader.colorLimits.colorGreenMaximum = - (double)IntegerNode( colorbox.get( "colorGreenMaximum" ) ).value(); - data3DHeader.colorLimits.colorGreenMinimum = - (double)IntegerNode( colorbox.get( "colorGreenMinimum" ) ).value(); - data3DHeader.colorLimits.colorBlueMaximum = - (double)IntegerNode( colorbox.get( "colorBlueMaximum" ) ).value(); - data3DHeader.colorLimits.colorBlueMinimum = - (double)IntegerNode( colorbox.get( "colorBlueMinimum" ) ).value(); - } - } - - if ( ( data3DHeader.colorLimits.colorRedMaximum == 0. ) && proto.isDefined( "colorRed" ) ) - { - if ( proto.get( "colorRed" ).type() == E57_INTEGER ) - { - data3DHeader.colorLimits.colorRedMinimum = (uint16_t)IntegerNode( proto.get( "colorRed" ) ).minimum(); - data3DHeader.colorLimits.colorRedMaximum = (uint16_t)IntegerNode( proto.get( "colorRed" ) ).maximum(); - } - else if ( proto.get( "colorRed" ).type() == E57_FLOAT ) - { - data3DHeader.colorLimits.colorRedMinimum = (uint16_t)FloatNode( proto.get( "colorRed" ) ).minimum(); - data3DHeader.colorLimits.colorRedMaximum = (uint16_t)FloatNode( proto.get( "colorRed" ) ).maximum(); - } - else if ( proto.get( "colorRed" ).type() == E57_SCALED_INTEGER ) - { - double scale = ScaledIntegerNode( proto.get( "colorRed" ) ).scale(); - double offset = ScaledIntegerNode( proto.get( "colorRed" ) ).offset(); - int64_t minimum = ScaledIntegerNode( proto.get( "colorRed" ) ).minimum(); - int64_t maximum = ScaledIntegerNode( proto.get( "colorRed" ) ).maximum(); - data3DHeader.colorLimits.colorRedMinimum = (uint16_t)minimum * scale + offset; - data3DHeader.colorLimits.colorRedMaximum = (uint16_t)maximum * scale + offset; - } - } - if ( ( data3DHeader.colorLimits.colorGreenMaximum == 0. ) && proto.isDefined( "colorGreen" ) ) - { - if ( proto.get( "colorGreen" ).type() == E57_INTEGER ) - { - data3DHeader.colorLimits.colorGreenMinimum = (uint16_t)IntegerNode( proto.get( "colorGreen" ) ).minimum(); - data3DHeader.colorLimits.colorGreenMaximum = (uint16_t)IntegerNode( proto.get( "colorGreen" ) ).maximum(); - } - else if ( proto.get( "colorGreen" ).type() == E57_FLOAT ) - { - data3DHeader.colorLimits.colorGreenMinimum = (uint16_t)FloatNode( proto.get( "colorGreen" ) ).minimum(); - data3DHeader.colorLimits.colorGreenMaximum = (uint16_t)FloatNode( proto.get( "colorGreen" ) ).maximum(); - } - else if ( proto.get( "colorGreen" ).type() == E57_SCALED_INTEGER ) - { - double scale = ScaledIntegerNode( proto.get( "colorGreen" ) ).scale(); - double offset = ScaledIntegerNode( proto.get( "colorGreen" ) ).offset(); - int64_t minimum = ScaledIntegerNode( proto.get( "colorGreen" ) ).minimum(); - int64_t maximum = ScaledIntegerNode( proto.get( "colorGreen" ) ).maximum(); - data3DHeader.colorLimits.colorGreenMinimum = (uint16_t)minimum * scale + offset; - data3DHeader.colorLimits.colorGreenMaximum = (uint16_t)maximum * scale + offset; - } - } - if ( ( data3DHeader.colorLimits.colorBlueMaximum == 0. ) && proto.isDefined( "colorBlue" ) ) - { - if ( proto.get( "colorBlue" ).type() == E57_INTEGER ) - { - data3DHeader.colorLimits.colorBlueMinimum = (uint16_t)IntegerNode( proto.get( "colorBlue" ) ).minimum(); - data3DHeader.colorLimits.colorBlueMaximum = (uint16_t)IntegerNode( proto.get( "colorBlue" ) ).maximum(); - } - else if ( proto.get( "colorBlue" ).type() == E57_FLOAT ) - { - data3DHeader.colorLimits.colorBlueMinimum = (uint16_t)FloatNode( proto.get( "colorBlue" ) ).minimum(); - data3DHeader.colorLimits.colorBlueMaximum = (uint16_t)FloatNode( proto.get( "colorBlue" ) ).maximum(); - } - else if ( proto.get( "colorBlue" ).type() == E57_SCALED_INTEGER ) - { - double scale = ScaledIntegerNode( proto.get( "colorBlue" ) ).scale(); - double offset = ScaledIntegerNode( proto.get( "colorBlue" ) ).offset(); - int64_t minimum = ScaledIntegerNode( proto.get( "colorBlue" ) ).minimum(); - int64_t maximum = ScaledIntegerNode( proto.get( "colorBlue" ) ).maximum(); - data3DHeader.colorLimits.colorRedMinimum = (uint16_t)minimum * scale + offset; - data3DHeader.colorLimits.colorRedMaximum = (uint16_t)maximum * scale + offset; - } - } - - // E57_EXT_surface_normals - ustring norExtUri; - if ( imf_.extensionsLookupPrefix( "nor", norExtUri ) ) - { - data3DHeader.pointFields.normalX = proto.isDefined( "nor:normalX" ); - data3DHeader.pointFields.normalY = proto.isDefined( "nor:normalY" ); - data3DHeader.pointFields.normalZ = proto.isDefined( "nor:normalZ" ); - } - - return true; - } - - // This function returns the size of the point data - bool ReaderImpl::GetData3DSizes( int64_t dataIndex, int64_t &row, int64_t &column, int64_t &pointsSize, - int64_t &groupsSize, int64_t &countSize, bool &bColumnIndex ) const - { - row = 0; - column = 0; - pointsSize = 0; - groupsSize = 0; - int64_t elementSize = 0; - countSize = 0; - bColumnIndex = false; - - if ( !IsOpen() ) - { - return false; - } - if ( ( dataIndex < 0 ) || ( dataIndex >= data3D_.childCount() ) ) - { - return false; - } - - StructureNode scan( data3D_.get( dataIndex ) ); - - CompressedVectorNode points( scan.get( "points" ) ); - pointsSize = points.childCount(); - - if ( scan.isDefined( "indexBounds" ) ) - { - StructureNode indexBounds( scan.get( "indexBounds" ) ); - if ( indexBounds.isDefined( "columnMaximum" ) ) - { - column = IntegerNode( indexBounds.get( "columnMaximum" ) ).value() - - IntegerNode( indexBounds.get( "columnMinimum" ) ).value() + 1; - } - - if ( indexBounds.isDefined( "rowMaximum" ) ) - { - row = IntegerNode( indexBounds.get( "rowMaximum" ) ).value() - - IntegerNode( indexBounds.get( "rowMinimum" ) ).value() + 1; - } - } - - if ( scan.isDefined( "pointGroupingSchemes" ) ) - { - StructureNode pointGroupingSchemes( scan.get( "pointGroupingSchemes" ) ); - if ( pointGroupingSchemes.isDefined( "groupingByLine" ) ) - { - StructureNode groupingByLine( pointGroupingSchemes.get( "groupingByLine" ) ); - - StringNode idElementName( groupingByLine.get( "idElementName" ) ); - if ( idElementName.value().compare( "columnIndex" ) == 0 ) - { - bColumnIndex = true; - } - - CompressedVectorNode groups( groupingByLine.get( "groups" ) ); - groupsSize = groups.childCount(); - - StructureNode lineGroupRecord( groups.prototype() ); - - if ( lineGroupRecord.isDefined( "idElementValue" ) ) - { - elementSize = IntegerNode( lineGroupRecord.get( "idElementValue" ) ).maximum() - - IntegerNode( lineGroupRecord.get( "idElementValue" ) ).minimum() + 1; - } - else if ( bColumnIndex ) - { - elementSize = column; - } - else - { - elementSize = row; - } - - if ( lineGroupRecord.isDefined( "pointCount" ) ) - { - countSize = IntegerNode( lineGroupRecord.get( "pointCount" ) ).maximum(); - } - else if ( bColumnIndex ) - { - countSize = row; - } - else - { - countSize = column; - } - } - } - - // if indexBounds is not given - if ( row == 0 ) - { - if ( bColumnIndex ) - { - row = countSize; - } - else - { - row = elementSize; - } - } - if ( column == 0 ) - { - if ( bColumnIndex ) - { - column = elementSize; - } - else - { - column = countSize; - } - } - - return true; - } - - // This function writes out the group data - bool ReaderImpl::ReadData3DGroupsData( int64_t dataIndex, int64_t groupCount, int64_t *idElementValue, - int64_t *startPointIndex, int64_t *pointCount ) const - { - if ( ( dataIndex < 0 ) || ( dataIndex >= data3D_.childCount() ) ) - { - return false; - } - - StructureNode scan( data3D_.get( dataIndex ) ); - if ( !scan.isDefined( "pointGroupingSchemes" ) ) - { - return false; - } - - StructureNode pointGroupingSchemes( scan.get( "pointGroupingSchemes" ) ); - if ( !pointGroupingSchemes.isDefined( "groupingByLine" ) ) - { - return false; - } - - StructureNode groupingByLine( pointGroupingSchemes.get( "groupingByLine" ) ); - - StringNode idElementName( groupingByLine.get( "idElementName" ) ); - CompressedVectorNode groups( groupingByLine.get( "groups" ) ); - StructureNode lineGroupRecord( groups.prototype() ); // not used here - - int64_t protoCount = lineGroupRecord.childCount(); - int64_t protoIndex; - std::vector groupSDBuffers; - - for ( protoIndex = 0; protoIndex < protoCount; protoIndex++ ) - { - ustring name = lineGroupRecord.get( protoIndex ).elementName(); - - if ( ( name.compare( "idElementValue" ) == 0 ) && lineGroupRecord.isDefined( "idElementValue" ) && - idElementValue ) - { - groupSDBuffers.emplace_back( imf_, "idElementValue", idElementValue, groupCount, true ); - } - - if ( ( name.compare( "startPointIndex" ) == 0 ) && lineGroupRecord.isDefined( "startPointIndex" ) && - startPointIndex ) - { - groupSDBuffers.emplace_back( imf_, "startPointIndex", startPointIndex, groupCount, true ); - } - - if ( ( name.compare( "pointCount" ) == 0 ) && lineGroupRecord.isDefined( "pointCount" ) && - pointCount ) - { - groupSDBuffers.emplace_back( imf_, "pointCount", pointCount, groupCount, true ); - } - } - - CompressedVectorReader reader = groups.reader( groupSDBuffers ); - - reader.read(); - reader.close(); - - return true; - } - - template - CompressedVectorReader ReaderImpl::SetUpData3DPointsData( int64_t dataIndex, size_t count, - const Data3DPointsData_t &buffers ) const - { - StructureNode scan( data3D_.get( dataIndex ) ); - CompressedVectorNode points( scan.get( "points" ) ); - StructureNode proto( points.prototype() ); - - int64_t protoCount = proto.childCount(); - int64_t protoIndex; - - std::vector destBuffers; - - for ( protoIndex = 0; protoIndex < protoCount; protoIndex++ ) - { - ustring name = proto.get( protoIndex ).elementName(); - NodeType type = proto.get( protoIndex ).type(); - bool scaled = (type == E57_SCALED_INTEGER); - // E57_EXT_surface_normals - ustring norExtUri; - bool haveNormalsExt = imf_.extensionsLookupPrefix( "nor", norExtUri ); - - if ( ( name.compare( "cartesianX" ) == 0 ) && proto.isDefined( "cartesianX" ) && - buffers.cartesianX ) - { - destBuffers.emplace_back( imf_, "cartesianX", buffers.cartesianX, count, true, scaled ); - } - else if ( ( name.compare( "cartesianY" ) == 0 ) && proto.isDefined( "cartesianY" ) && - buffers.cartesianY ) - { - destBuffers.emplace_back( imf_, "cartesianY", buffers.cartesianY, count, true, scaled ); - } - else if ( ( name.compare( "cartesianZ" ) == 0 ) && proto.isDefined( "cartesianZ" ) && - buffers.cartesianZ ) - { - destBuffers.emplace_back( imf_, "cartesianZ", buffers.cartesianZ, count, true, scaled ); - } - else if ( ( name.compare( "cartesianInvalidState" ) == 0 ) && proto.isDefined( "cartesianInvalidState" ) && - buffers.cartesianInvalidState ) - { - destBuffers.emplace_back( imf_, "cartesianInvalidState", buffers.cartesianInvalidState, count, true ); - } - else if ( ( name.compare( "sphericalRange" ) == 0 ) && proto.isDefined( "sphericalRange" ) && - buffers.sphericalRange ) - { - destBuffers.emplace_back( imf_, "sphericalRange", buffers.sphericalRange, count, true, scaled ); - } - else if ( ( name.compare( "sphericalAzimuth" ) == 0 ) && proto.isDefined( "sphericalAzimuth" ) && - buffers.sphericalAzimuth ) - { - destBuffers.emplace_back( imf_, "sphericalAzimuth", buffers.sphericalAzimuth, count, true, scaled ); - } - else if ( ( name.compare( "sphericalElevation" ) == 0 ) && proto.isDefined( "sphericalElevation" ) && - buffers.sphericalElevation ) - { - destBuffers.emplace_back( imf_, "sphericalElevation", buffers.sphericalElevation, count, true, scaled ); - } - else if ( ( name.compare( "sphericalInvalidState" ) == 0 ) && proto.isDefined( "sphericalInvalidState" ) && - buffers.sphericalInvalidState ) - { - destBuffers.emplace_back( imf_, "sphericalInvalidState", buffers.sphericalInvalidState, count, true ); - } - else if ( ( name.compare( "rowIndex" ) == 0 ) && proto.isDefined( "rowIndex" ) && - buffers.rowIndex ) - { - destBuffers.emplace_back( imf_, "rowIndex", buffers.rowIndex, count, true ); - } - else if ( ( name.compare( "columnIndex" ) == 0 ) && proto.isDefined( "columnIndex" ) && - buffers.columnIndex ) - { - destBuffers.emplace_back( imf_, "columnIndex", buffers.columnIndex, count, true ); - } - else if ( ( name.compare( "returnIndex" ) == 0 ) && proto.isDefined( "returnIndex" ) && - buffers.returnIndex ) - { - destBuffers.emplace_back( imf_, "returnIndex", buffers.returnIndex, count, true ); - } - else if ( ( name.compare( "returnCount" ) == 0 ) && proto.isDefined( "returnCount" ) && - buffers.returnCount ) - { - destBuffers.emplace_back( imf_, "returnCount", buffers.returnCount, count, true ); - } - else if ( ( name.compare( "timeStamp" ) == 0 ) && proto.isDefined( "timeStamp" ) && - buffers.timeStamp ) - { - destBuffers.emplace_back( imf_, "timeStamp", buffers.timeStamp, count, true, scaled ); - } - else if ( ( name.compare( "isTimeStampInvalid" ) == 0 ) && proto.isDefined( "isTimeStampInvalid" ) && - buffers.isTimeStampInvalid ) - { - destBuffers.emplace_back( imf_, "isTimeStampInvalid", buffers.isTimeStampInvalid, count, true ); - } - else if ( ( name.compare( "intensity" ) == 0 ) && proto.isDefined( "intensity" ) && - buffers.intensity ) - { - destBuffers.emplace_back( imf_, "intensity", buffers.intensity, count, true, scaled ); - } - else if ( ( name.compare( "isIntensityInvalid" ) == 0 ) && proto.isDefined( "isIntensityInvalid" ) && - buffers.isIntensityInvalid ) - { - destBuffers.emplace_back( imf_, "isIntensityInvalid", buffers.isIntensityInvalid, count, true ); - } - else if ( ( name.compare( "colorRed" ) == 0 ) && proto.isDefined( "colorRed" ) && - buffers.colorRed ) - { - destBuffers.emplace_back( imf_, "colorRed", buffers.colorRed, count, true, scaled ); - } - else if ( ( name.compare( "colorGreen" ) == 0 ) && proto.isDefined( "colorGreen" ) && - buffers.colorGreen ) - { - destBuffers.emplace_back( imf_, "colorGreen", buffers.colorGreen, count, true, scaled ); - } - else if ( ( name.compare( "colorBlue" ) == 0 ) && proto.isDefined( "colorBlue" ) && - buffers.colorBlue ) - { - destBuffers.emplace_back( imf_, "colorBlue", buffers.colorBlue, count, true, scaled ); - } - else if ( ( name.compare( "isColorInvalid" ) == 0 ) && proto.isDefined( "isColorInvalid" ) && - buffers.isColorInvalid ) - { - destBuffers.emplace_back( imf_, "isColorInvalid", buffers.isColorInvalid, count, true ); - } - else if ( haveNormalsExt && ( name.compare( "nor:normalX" ) == 0 ) && proto.isDefined( "nor:normalX" ) && - buffers.normalX ) - { - destBuffers.emplace_back( imf_, "nor:normalX", buffers.normalX, count, true, scaled ); - } - else if ( haveNormalsExt && ( name.compare( "nor:normalY" ) == 0 ) && proto.isDefined( "nor:normalY" ) && - buffers.normalY ) - { - destBuffers.emplace_back( imf_, "nor:normalY", buffers.normalY, count, true, scaled ); - } - else if ( haveNormalsExt && ( name.compare( "nor:normalZ" ) == 0 ) && proto.isDefined( "nor:normalZ" ) && - buffers.normalZ ) - { - destBuffers.emplace_back( imf_, "nor:normalZ", buffers.normalZ, count, true, scaled ); - } - } - - CompressedVectorReader reader = points.reader( destBuffers ); - - return reader; - } - - // Explicit template instantiation - template CompressedVectorReader ReaderImpl::SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData_t &buffers ) const; - - template CompressedVectorReader ReaderImpl::SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData_t &buffers ) const; - -} // end namespace e57 diff --git a/src/3rdParty/libE57Format/src/ReaderImpl.h b/src/3rdParty/libE57Format/src/ReaderImpl.h deleted file mode 100644 index 6570beb5fa..0000000000 --- a/src/3rdParty/libE57Format/src/ReaderImpl.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2010 Stan Coleby (scoleby@intelisum.com) - * Copyright (c) 2020 PTC Inc. - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include "E57SimpleData.h" - -namespace e57 -{ - - //! most of the functions follows Reader - class ReaderImpl - { - public: - ReaderImpl( const ustring &filePath ); - - ~ReaderImpl(); - - bool IsOpen() const; - - bool Close(); - - bool GetE57Root( E57Root &fileHeader ) const; - - int64_t GetImage2DCount() const; - - bool ReadImage2D( int64_t imageIndex, Image2D &Image2DHeader ) const; - - bool GetImage2DSizes( int64_t imageIndex, Image2DProjection &imageProjection, Image2DType &imageType, - int64_t &imageWidth, int64_t &imageHeight, int64_t &imageSize, Image2DType &imageMaskType, - Image2DType &imageVisualType ) const; - - int64_t ReadImage2DData( int64_t imageIndex, Image2DProjection imageProjection, Image2DType imageType, - void *pBuffer, int64_t start, int64_t count ) const; - - int64_t GetData3DCount() const; - - bool ReadData3D( int64_t dataIndex, Data3D &data3DHeader ) const; - - bool GetData3DSizes( int64_t dataIndex, int64_t &rowMax, int64_t &columnMax, int64_t &pointsSize, - int64_t &groupsSize, int64_t &countSize, bool &bColumnIndex ) const; - - bool ReadData3DGroupsData( int64_t dataIndex, int64_t groupCount, int64_t *idElementValue, - int64_t *startPointIndex, int64_t *pointCount ) const; - - template - CompressedVectorReader SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData_t &buffers ) const; - - StructureNode GetRawE57Root() const; - - VectorNode GetRawData3D() const; - - VectorNode GetRawImages2D() const; - - ImageFile GetRawIMF() const; - - private: - ImageFile imf_; - StructureNode root_; - - VectorNode data3D_; - - VectorNode images2D_; - - //! @brief This function reads one of the image blobs - //! @param [in] image 1 of 3 projects or the visual - //! @param [out] imageType identifies the image format desired. - //! @param [out] imageWidth The image width (in pixels). - //! @param [out] imageHeight The image height (in pixels). - //! @param [out] imageSize This is the total number of bytes for the image blob. - //! @param [out] imageMaskType This is E57_PNG_IMAGE_MASK if "imageMask" is defined in the projection - //! @return Returns true if successful - bool GetImage2DNodeSizes( StructureNode image, Image2DType &imageType, int64_t &imageWidth, int64_t &imageHeight, - int64_t &imageSize, Image2DType &imageMaskType ) const; - - //! @brief Reads the data out of a given image node - //! @param [in] image 1 of 3 projects or the visual - //! @param [in] imageType identifies the image format desired. - //! @param [out] pBuffer pointer the buffer - //! @param [out] start position in the block to start reading - //! @param [out] count size of desired chuck or buffer size - //! @return number of bytes read - int64_t ReadImage2DNode( StructureNode image, Image2DType imageType, void *pBuffer, int64_t start, - int64_t count ) const; - }; // end Reader class - -} // end namespace e57 diff --git a/src/3rdParty/libE57Format/src/ScaledIntegerNodeImpl.cpp b/src/3rdParty/libE57Format/src/ScaledIntegerNodeImpl.cpp deleted file mode 100644 index 90c40c6873..0000000000 --- a/src/3rdParty/libE57Format/src/ScaledIntegerNodeImpl.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include - -#include "CheckedFile.h" -#include "ScaledIntegerNodeImpl.h" - -namespace e57 -{ - ScaledIntegerNodeImpl::ScaledIntegerNodeImpl( ImageFileImplWeakPtr destImageFile, int64_t rawValue, int64_t minimum, - int64_t maximum, double scale, double offset ) : - NodeImpl( destImageFile ), - value_( rawValue ), minimum_( minimum ), maximum_( maximum ), scale_( scale ), offset_( offset ) - { - // don't checkImageFileOpen, NodeImpl() will do it - - /// Enforce the given bounds on raw value - if ( rawValue < minimum || maximum < rawValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_OUT_OF_BOUNDS, - "this->pathName=" + this->pathName() + " rawValue=" + toString( rawValue ) + - " minimum=" + toString( minimum ) + " maximum=" + toString( maximum ) ); - } - } - - ScaledIntegerNodeImpl::ScaledIntegerNodeImpl( ImageFileImplWeakPtr destImageFile, double scaledValue, - double scaledMinimum, double scaledMaximum, double scale, - double offset ) : - NodeImpl( destImageFile ), - value_( static_cast( std::floor( ( scaledValue - offset ) / scale + .5 ) ) ), - minimum_( static_cast( std::floor( ( scaledMinimum - offset ) / scale + .5 ) ) ), - maximum_( static_cast( std::floor( ( scaledMaximum - offset ) / scale + .5 ) ) ), scale_( scale ), - offset_( offset ) - { - // don't checkImageFileOpen, NodeImpl() will do it - - /// Enforce the given bounds on raw value - if ( scaledValue < scaledMinimum || scaledMaximum < scaledValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_OUT_OF_BOUNDS, "this->pathName=" + this->pathName() + - " scaledValue=" + toString( scaledValue ) + - " scaledMinimum=" + toString( scaledMinimum ) + - " scaledMaximum=" + toString( scaledMaximum ) ); - } - } - - bool ScaledIntegerNodeImpl::isTypeEquivalent( NodeImplSharedPtr ni ) - { - // don't checkImageFileOpen - - /// Same node type? - if ( ni->type() != E57_SCALED_INTEGER ) - { - return ( false ); - } - - /// Downcast to shared_ptr - std::shared_ptr ii( std::static_pointer_cast( ni ) ); - - /// minimum must match - if ( minimum_ != ii->minimum_ ) - { - return ( false ); - } - - /// maximum must match - if ( maximum_ != ii->maximum_ ) - { - return ( false ); - } - - /// scale must match - if ( scale_ != ii->scale_ ) - { - return ( false ); - } - - /// offset must match - if ( offset_ != ii->offset_ ) - { - return ( false ); - } - - /// ignore value_, doesn't have to match - - /// Types match - return ( true ); - } - - bool ScaledIntegerNodeImpl::isDefined( const ustring &pathName ) - { - // don't checkImageFileOpen - - /// We have no sub-structure, so if path not empty return false - return pathName.empty(); - } - - int64_t ScaledIntegerNodeImpl::rawValue() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( value_ ); - } - - double ScaledIntegerNodeImpl::scaledValue() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( value_ * scale_ + offset_ ); - } - - int64_t ScaledIntegerNodeImpl::minimum() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( minimum_ ); - } - double ScaledIntegerNodeImpl::scaledMinimum() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( minimum_ * scale_ + offset_ ); - } - - int64_t ScaledIntegerNodeImpl::maximum() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( maximum_ ); - } - double ScaledIntegerNodeImpl::scaledMaximum() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( maximum_ * scale_ + offset_ ); - } - - double ScaledIntegerNodeImpl::scale() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( scale_ ); - } - - double ScaledIntegerNodeImpl::offset() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( offset_ ); - } - - void ScaledIntegerNodeImpl::checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) - { - // don't checkImageFileOpen - - /// We are a leaf node, so verify that we are listed in set. - if ( pathNames.find( relativePathName( origin ) ) == pathNames.end() ) - { - throw E57_EXCEPTION2( E57_ERROR_NO_BUFFER_FOR_ELEMENT, "this->pathName=" + this->pathName() ); - } - } - - void ScaledIntegerNodeImpl::writeXml( ImageFileImplSharedPtr /*imf*/, CheckedFile &cf, int indent, - const char *forcedFieldName ) - { - // don't checkImageFileOpen - - ustring fieldName; - if ( forcedFieldName ) - { - fieldName = forcedFieldName; - } - else - { - fieldName = elementName_; - } - - cf << space( indent ) << "<" << fieldName << " type=\"ScaledInteger\""; - - /// Don't need to write if are default values - if ( minimum_ != E57_INT64_MIN ) - { - cf << " minimum=\"" << minimum_ << "\""; - } - if ( maximum_ != E57_INT64_MAX ) - { - cf << " maximum=\"" << maximum_ << "\""; - } - if ( scale_ != 1.0 ) - { - cf << " scale=\"" << scale_ << "\""; - } - if ( offset_ != 0.0 ) - { - cf << " offset=\"" << offset_ << "\""; - } - - /// Write value as child text, unless it is the default value - if ( value_ != 0 ) - { - cf << ">" << value_ << "\n"; - } - else - { - cf << "/>\n"; - } - } - -#ifdef E57_DEBUG - void ScaledIntegerNodeImpl::dump( int indent, std::ostream &os ) const - { - // don't checkImageFileOpen - os << space( indent ) << "type: ScaledInteger" - << " (" << type() << ")" << std::endl; - NodeImpl::dump( indent, os ); - os << space( indent ) << "rawValue: " << value_ << std::endl; - os << space( indent ) << "minimum: " << minimum_ << std::endl; - os << space( indent ) << "maximum: " << maximum_ << std::endl; - os << space( indent ) << "scale: " << scale_ << std::endl; - os << space( indent ) << "offset: " << offset_ << std::endl; - } -#endif -} diff --git a/src/3rdParty/libE57Format/src/ScaledIntegerNodeImpl.h b/src/3rdParty/libE57Format/src/ScaledIntegerNodeImpl.h deleted file mode 100644 index 427a023c88..0000000000 --- a/src/3rdParty/libE57Format/src/ScaledIntegerNodeImpl.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "NodeImpl.h" - -namespace e57 -{ - class ScaledIntegerNodeImpl : public NodeImpl - { - public: - ScaledIntegerNodeImpl( ImageFileImplWeakPtr destImageFile, int64_t value = 0, int64_t minimum = 0, - int64_t maximum = 0, double scale = 1.0, double offset = 0.0 ); - - ScaledIntegerNodeImpl( ImageFileImplWeakPtr destImageFile, double scaledValue = 0., double scaledMinimum = 0., - double scaledMaximum = 0., double scale = 1.0, double offset = 0.0 ); - - ~ScaledIntegerNodeImpl() override = default; - - NodeType type() const override - { - return E57_SCALED_INTEGER; - } - bool isTypeEquivalent( NodeImplSharedPtr ni ) override; - bool isDefined( const ustring &pathName ) override; - - int64_t rawValue(); - double scaledValue(); - int64_t minimum(); - double scaledMinimum(); - int64_t maximum(); - double scaledMaximum(); - double scale(); - double offset(); - - void checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) override; - - void writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, - const char *forcedFieldName = nullptr ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - - private: - int64_t value_; - int64_t minimum_; - int64_t maximum_; - double scale_; - double offset_; - }; -} diff --git a/src/3rdParty/libE57Format/src/SectionHeaders.cpp b/src/3rdParty/libE57Format/src/SectionHeaders.cpp deleted file mode 100644 index 6b4cd588a0..0000000000 --- a/src/3rdParty/libE57Format/src/SectionHeaders.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "SectionHeaders.h" - -namespace e57 -{ -#ifdef E57_DEBUG - void BlobSectionHeader::dump( int indent, std::ostream &os ) - { - os << space( indent ) << "sectionId: " << sectionId << std::endl; - os << space( indent ) << "sectionLogicalLength: " << sectionLogicalLength << std::endl; - } -#endif - - CompressedVectorSectionHeader::CompressedVectorSectionHeader() - { - /// Double check that header is correct length. Watch out for RTTI - /// increasing the size. - static_assert( sizeof( CompressedVectorSectionHeader ) == 32, - "Unexpected size of CompressedVectorSectionHeader" ); - } - - void CompressedVectorSectionHeader::verify( uint64_t filePhysicalSize ) - { - /// Verify reserved fields are zero. ??? if fileversion==1.0 ??? - for ( unsigned i = 0; i < sizeof( reserved1 ); i++ ) - { - if ( reserved1[i] != 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_HEADER, - "i=" + toString( i ) + " reserved=" + toString( reserved1[i] ) ); - } - } - - /// Check section length is multiple of 4 - if ( sectionLogicalLength % 4 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_HEADER, "sectionLogicalLength=" + toString( sectionLogicalLength ) ); - } - - /// Check sectionLogicalLength is in bounds - if ( filePhysicalSize > 0 && sectionLogicalLength >= filePhysicalSize ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_HEADER, "sectionLogicalLength=" + toString( sectionLogicalLength ) + - " filePhysicalSize=" + toString( filePhysicalSize ) ); - } - - /// Check dataPhysicalOffset is in bounds - if ( filePhysicalSize > 0 && dataPhysicalOffset >= filePhysicalSize ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_HEADER, "dataPhysicalOffset=" + toString( dataPhysicalOffset ) + - " filePhysicalSize=" + toString( filePhysicalSize ) ); - } - - /// Check indexPhysicalOffset is in bounds - if ( filePhysicalSize > 0 && indexPhysicalOffset >= filePhysicalSize ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_CV_HEADER, "indexPhysicalOffset=" + toString( indexPhysicalOffset ) + - " filePhysicalSize=" + toString( filePhysicalSize ) ); - } - } - -#ifdef E57_DEBUG - void CompressedVectorSectionHeader::dump( int indent, std::ostream &os ) const - { - os << space( indent ) << "sectionId: " << static_cast( sectionId ) << std::endl; - os << space( indent ) << "sectionLogicalLength: " << sectionLogicalLength << std::endl; - os << space( indent ) << "dataPhysicalOffset: " << dataPhysicalOffset << std::endl; - os << space( indent ) << "indexPhysicalOffset: " << indexPhysicalOffset << std::endl; - } -#endif -} diff --git a/src/3rdParty/libE57Format/src/SectionHeaders.h b/src/3rdParty/libE57Format/src/SectionHeaders.h deleted file mode 100644 index 2b248d0200..0000000000 --- a/src/3rdParty/libE57Format/src/SectionHeaders.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "Common.h" - -namespace e57 -{ - enum - { - BLOB_SECTION = 0, - COMPRESSED_VECTOR_SECTION, - }; - - struct BlobSectionHeader - { - const uint8_t sectionId = BLOB_SECTION; - - uint8_t reserved1[7] = {}; // must be zero - uint64_t sectionLogicalLength = 0; // byte length of whole section - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ); -#endif - }; - - struct CompressedVectorSectionHeader - { - const uint8_t sectionId = COMPRESSED_VECTOR_SECTION; - - uint8_t reserved1[7] = {}; // must be zero - uint64_t sectionLogicalLength = 0; // byte length of whole section - uint64_t dataPhysicalOffset = 0; // offset of first data packet - uint64_t indexPhysicalOffset = 0; // offset of first index packet - - CompressedVectorSectionHeader(); - void verify( uint64_t filePhysicalSize = 0 ); - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const; -#endif - }; -} diff --git a/src/3rdParty/libE57Format/src/SourceDestBufferImpl.cpp b/src/3rdParty/libE57Format/src/SourceDestBufferImpl.cpp deleted file mode 100644 index 010a27296c..0000000000 --- a/src/3rdParty/libE57Format/src/SourceDestBufferImpl.cpp +++ /dev/null @@ -1,1045 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include - -#include "ImageFileImpl.h" -#include "SourceDestBufferImpl.h" - -using namespace e57; - -SourceDestBufferImpl::SourceDestBufferImpl( ImageFileImplWeakPtr destImageFile, const ustring &pathName, - const size_t capacity, bool doConversion, bool doScaling ) : - destImageFile_( destImageFile ), - pathName_( pathName ), capacity_( capacity ), doConversion_( doConversion ), doScaling_( doScaling ) -{ -} - -template void SourceDestBufferImpl::setTypeInfo( T *base, size_t stride ) -{ - static_assert( std::is_integral::value || std::is_floating_point::value, - "Integral or floating point required." ); - - base_ = reinterpret_cast( base ); - stride_ = stride; - - // this is a little ugly, but it saves us having to pass around the memory - // representation - if ( std::is_same::value ) - { - memoryRepresentation_ = E57_INT8; - } - else if ( std::is_same::value ) - { - memoryRepresentation_ = E57_UINT8; - } - else if ( std::is_same::value ) - { - memoryRepresentation_ = E57_INT16; - } - else if ( std::is_same::value ) - { - memoryRepresentation_ = E57_UINT16; - } - else if ( std::is_same::value ) - { - memoryRepresentation_ = E57_INT32; - } - else if ( std::is_same::value ) - { - memoryRepresentation_ = E57_UINT32; - } - else if ( std::is_same::value ) - { - memoryRepresentation_ = E57_INT64; - } - else if ( std::is_same::value ) - { - memoryRepresentation_ = E57_BOOL; - } - else if ( std::is_same::value ) - { - memoryRepresentation_ = E57_REAL32; - } - else if ( std::is_same::value ) - { - memoryRepresentation_ = E57_REAL64; - } - - checkState_(); -} - -template void SourceDestBufferImpl::setTypeInfo( int8_t *base, size_t stride ); -template void SourceDestBufferImpl::setTypeInfo( uint8_t *base, size_t stride ); -template void SourceDestBufferImpl::setTypeInfo( int16_t *base, size_t stride ); -template void SourceDestBufferImpl::setTypeInfo( uint16_t *base, size_t stride ); -template void SourceDestBufferImpl::setTypeInfo( int32_t *base, size_t stride ); -template void SourceDestBufferImpl::setTypeInfo( uint32_t *base, size_t stride ); -template void SourceDestBufferImpl::setTypeInfo( int64_t *base, size_t stride ); -template void SourceDestBufferImpl::setTypeInfo( bool *base, size_t stride ); -template void SourceDestBufferImpl::setTypeInfo( float *base, size_t stride ); -template void SourceDestBufferImpl::setTypeInfo( double *base, size_t stride ); - -SourceDestBufferImpl::SourceDestBufferImpl( ImageFileImplWeakPtr destImageFile, const ustring &pathName, - std::vector *b ) : - destImageFile_( destImageFile ), - pathName_( pathName ), memoryRepresentation_( E57_USTRING ), ustrings_( b ) -{ - /// don't checkImageFileOpen, checkState_ will do it - - /// Set capacity_ after testing that b is OK - if ( !b ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_BUFFER, "sdbuf.pathName=" + pathName ); - } - - capacity_ = b->size(); - - checkState_(); - - /// Note that capacity_ is set to the size() of the vector<>, not its - /// capacity(). The size() of *ustrings_ will not be changed as strings are - /// stored in it. -} - -template void SourceDestBufferImpl::_setNextReal( T inValue ) -{ - static_assert( std::is_same::value || std::is_same::value, - "_setNextReal() requires float or double type" ); - - /// don't checkImageFileOpen - - /// Verify have room - if ( nextIndex_ >= capacity_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - - /// Calc start of memory location, index into buffer using stride_ (the - /// distance between elements). - char *p = &base_[nextIndex_ * stride_]; - - switch ( memoryRepresentation_ ) - { - case E57_INT8: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - //??? fault if get special value: NaN, NegInf... (all other ints below - // too) - if ( inValue < E57_INT8_MIN || E57_INT8_MAX < inValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( inValue ) ); - } - *reinterpret_cast( p ) = static_cast( inValue ); - break; - case E57_UINT8: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - if ( inValue < E57_UINT8_MIN || E57_UINT8_MAX < inValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( inValue ) ); - } - *reinterpret_cast( p ) = static_cast( inValue ); - break; - case E57_INT16: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - if ( inValue < E57_INT16_MIN || E57_INT16_MAX < inValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( inValue ) ); - } - *reinterpret_cast( p ) = static_cast( inValue ); - break; - case E57_UINT16: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - if ( inValue < E57_UINT16_MIN || E57_UINT16_MAX < inValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( inValue ) ); - } - *reinterpret_cast( p ) = static_cast( inValue ); - break; - case E57_INT32: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - if ( inValue < E57_INT32_MIN || E57_INT32_MAX < inValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( inValue ) ); - } - *reinterpret_cast( p ) = static_cast( inValue ); - break; - case E57_UINT32: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - if ( inValue < E57_UINT32_MIN || E57_UINT32_MAX < inValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( inValue ) ); - } - *reinterpret_cast( p ) = static_cast( inValue ); - break; - case E57_INT64: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - if ( inValue < E57_INT64_MIN || E57_INT64_MAX < inValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( inValue ) ); - } - *reinterpret_cast( p ) = static_cast( inValue ); - break; - case E57_BOOL: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - *reinterpret_cast( p ) = ( inValue ? false : true ); - break; - case E57_REAL32: - if ( std::is_same::value ) - { - /// Does this count as conversion? It loses information. - /// Check for really large exponents that can't fit in a single - /// precision - if ( inValue < E57_DOUBLE_MIN || E57_DOUBLE_MAX < inValue ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( inValue ) ); - } - *reinterpret_cast( p ) = static_cast( inValue ); - } - else - { -#ifdef _MSC_VER - // MSVC is not smart enough to realize 'inValue' cannot be a double here, so disable warning -#pragma warning( disable : 4244 ) - *reinterpret_cast( p ) = inValue; -#pragma warning( default : 4244 ) -#else - *reinterpret_cast( p ) = inValue; -#endif - } - break; - case E57_REAL64: - //??? does this count as a conversion? - *reinterpret_cast( p ) = static_cast( inValue ); - break; - case E57_USTRING: - throw E57_EXCEPTION2( E57_ERROR_EXPECTING_NUMERIC, "pathName=" + pathName_ ); - } - - nextIndex_++; -} - -void SourceDestBufferImpl::checkState_() const -{ - /// Implement checkImageFileOpen functionality for SourceDestBufferImpl ctors - /// Throw an exception if destImageFile (destImageFile_) isn't open - ImageFileImplSharedPtr destImageFile( destImageFile_ ); - if ( !destImageFile->isOpen() ) - { - throw E57_EXCEPTION2( E57_ERROR_IMAGEFILE_NOT_OPEN, "fileName=" + destImageFile->fileName() ); - } - - /// Check pathName is well formed (can't verify path is defined until - /// associate sdbuffer with CompressedVector later) - ImageFileImplSharedPtr imf( destImageFile_ ); - imf->pathNameCheckWellFormed( pathName_ ); - - if ( memoryRepresentation_ != E57_USTRING ) - { - if ( !base_ ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_BUFFER, "pathName=" + pathName_ ); - } - if ( stride_ == 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_BUFFER, "pathName=" + pathName_ ); - } - //??? check base alignment, depending on CPU type - //??? check if stride too small, positive or negative - } - else - { - if ( !ustrings_ ) - { - throw E57_EXCEPTION2( E57_ERROR_BAD_BUFFER, "pathName=" + pathName_ ); - } - } -} - -int64_t SourceDestBufferImpl::getNextInt64() -{ - /// don't checkImageFileOpen - - /// Verify index is within bounds - if ( nextIndex_ >= capacity_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - - /// Fetch value from source buffer. - /// Convert from non-integer formats if requested. - char *p = &base_[nextIndex_ * stride_]; - int64_t value; - switch ( memoryRepresentation_ ) - { - case E57_INT8: - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_UINT8: - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_INT16: - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_UINT16: - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_INT32: - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_UINT32: - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_INT64: - value = *reinterpret_cast( p ); - break; - case E57_BOOL: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - /// Convert bool to 0/1, all non-zero values map to 1.0 - value = ( *reinterpret_cast( p ) ) ? 1 : 0; - break; - case E57_REAL32: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - //??? fault if get special value: NaN, NegInf... - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_REAL64: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - //??? fault if get special value: NaN, NegInf... - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_USTRING: - throw E57_EXCEPTION2( E57_ERROR_EXPECTING_NUMERIC, "pathName=" + pathName_ ); - default: - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - nextIndex_++; - return ( value ); -} - -int64_t SourceDestBufferImpl::getNextInt64( double scale, double offset ) -{ - /// don't checkImageFileOpen - - /// Reverse scale (undo scaling) of a user's number to get raw value to put - /// in file. - - /// Incorporating the scale is optional (requested by user when constructing - /// the sdbuf). If the user did not request scaling, then we get raw values - /// from user's buffer. - if ( !doScaling_ ) - { - /// Just return raw value. - return ( getNextInt64() ); - } - - /// Double check non-zero scale. Going to divide by it below. - if ( scale == 0 ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - - /// Verify index is within bounds - if ( nextIndex_ >= capacity_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - - /// Fetch value from source buffer. - /// Convert from non-integer formats if requested - char *p = &base_[nextIndex_ * stride_]; - double doubleRawValue; - switch ( memoryRepresentation_ ) - { - case E57_INT8: - /// Calc (x-offset)/scale rounded to nearest integer, but keep in - /// floating point until sure is in bounds - doubleRawValue = floor( ( *reinterpret_cast( p ) - offset ) / scale + 0.5 ); - break; - case E57_UINT8: - /// Calc (x-offset)/scale rounded to nearest integer, but keep in - /// floating point until sure is in bounds - doubleRawValue = floor( ( *reinterpret_cast( p ) - offset ) / scale + 0.5 ); - break; - case E57_INT16: - /// Calc (x-offset)/scale rounded to nearest integer, but keep in - /// floating point until sure is in bounds - doubleRawValue = floor( ( *reinterpret_cast( p ) - offset ) / scale + 0.5 ); - break; - case E57_UINT16: - /// Calc (x-offset)/scale rounded to nearest integer, but keep in - /// floating point until sure is in bounds - doubleRawValue = floor( ( *reinterpret_cast( p ) - offset ) / scale + 0.5 ); - break; - case E57_INT32: - /// Calc (x-offset)/scale rounded to nearest integer, but keep in - /// floating point until sure is in bounds - doubleRawValue = floor( ( *reinterpret_cast( p ) - offset ) / scale + 0.5 ); - break; - case E57_UINT32: - /// Calc (x-offset)/scale rounded to nearest integer, but keep in - /// floating point until sure is in bounds - doubleRawValue = floor( ( *reinterpret_cast( p ) - offset ) / scale + 0.5 ); - break; - case E57_INT64: - /// Calc (x-offset)/scale rounded to nearest integer, but keep in - /// floating point until sure is in bounds - doubleRawValue = floor( ( *reinterpret_cast( p ) - offset ) / scale + 0.5 ); - break; - case E57_BOOL: - if ( *reinterpret_cast( p ) ) - { - doubleRawValue = floor( ( 1 - offset ) / scale + 0.5 ); - } - else - { - doubleRawValue = floor( ( 0 - offset ) / scale + 0.5 ); - } - break; - case E57_REAL32: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - //??? fault if get special value: NaN, NegInf... - - /// Calc (x-offset)/scale rounded to nearest integer, but keep in - /// floating point until sure is in bounds - doubleRawValue = floor( ( *reinterpret_cast( p ) - offset ) / scale + 0.5 ); - break; - case E57_REAL64: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - //??? fault if get special value: NaN, NegInf... - - /// Calc (x-offset)/scale rounded to nearest integer, but keep in - /// floating point until sure is in bounds - doubleRawValue = floor( ( *reinterpret_cast( p ) - offset ) / scale + 0.5 ); - break; - case E57_USTRING: - throw E57_EXCEPTION2( E57_ERROR_EXPECTING_NUMERIC, "pathName=" + pathName_ ); - default: - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - /// Make sure that value is representable in an int64_t - if ( doubleRawValue < E57_INT64_MIN || E57_INT64_MAX < doubleRawValue ) - { - throw E57_EXCEPTION2( E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( doubleRawValue ) ); - } - - auto rawValue = static_cast( doubleRawValue ); - - nextIndex_++; - return ( rawValue ); -} - -float SourceDestBufferImpl::getNextFloat() -{ - /// don't checkImageFileOpen - - /// Verify index is within bounds - if ( nextIndex_ >= capacity_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - - /// Fetch value from source buffer. - /// Convert from other formats to floating point if requested - char *p = &base_[nextIndex_ * stride_]; - float value; - switch ( memoryRepresentation_ ) - { - case E57_INT8: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_UINT8: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_INT16: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_UINT16: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_INT32: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_UINT32: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_INT64: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_BOOL: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - - /// Convert bool to 0/1, all non-zero values map to 1.0 - value = ( *reinterpret_cast( p ) ) ? 1.0F : 0.0F; - break; - case E57_REAL32: - value = *reinterpret_cast( p ); - break; - case E57_REAL64: - { - /// Check that exponent of user's value is not too large for single - /// precision number in file. - double d = *reinterpret_cast( p ); - - ///??? silently limit here? - if ( d < E57_DOUBLE_MIN || E57_DOUBLE_MAX < d ) - { - throw E57_EXCEPTION2( E57_ERROR_REAL64_TOO_LARGE, "pathName=" + pathName_ + " value=" + toString( d ) ); - } - value = static_cast( d ); - break; - } - case E57_USTRING: - throw E57_EXCEPTION2( E57_ERROR_EXPECTING_NUMERIC, "pathName=" + pathName_ ); - default: - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - nextIndex_++; - return ( value ); -} - -double SourceDestBufferImpl::getNextDouble() -{ - /// don't checkImageFileOpen - - /// Verify index is within bounds - if ( nextIndex_ >= capacity_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - - /// Fetch value from source buffer. - /// Convert from other formats to floating point if requested - char *p = &base_[nextIndex_ * stride_]; - double value; - switch ( memoryRepresentation_ ) - { - case E57_INT8: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_UINT8: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_INT16: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_UINT16: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_INT32: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_UINT32: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_INT64: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_BOOL: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - /// Convert bool to 0/1, all non-zero values map to 1.0 - value = ( *reinterpret_cast( p ) ) ? 1.0 : 0.0; - break; - case E57_REAL32: - value = static_cast( *reinterpret_cast( p ) ); - break; - case E57_REAL64: - value = *reinterpret_cast( p ); - break; - case E57_USTRING: - throw E57_EXCEPTION2( E57_ERROR_EXPECTING_NUMERIC, "pathName=" + pathName_ ); - default: - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - nextIndex_++; - return ( value ); -} - -ustring SourceDestBufferImpl::getNextString() -{ - /// don't checkImageFileOpen - - /// Check have correct type buffer - if ( memoryRepresentation_ != E57_USTRING ) - { - throw E57_EXCEPTION2( E57_ERROR_EXPECTING_USTRING, "pathName=" + pathName_ ); - } - - /// Verify index is within bounds - if ( nextIndex_ >= capacity_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - - /// Get ustring from vector - return ( ( *ustrings_ )[nextIndex_++] ); -} - -void SourceDestBufferImpl::setNextInt64( int64_t value ) -{ - /// don't checkImageFileOpen - - /// Verify have room - if ( nextIndex_ >= capacity_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - - /// Calc start of memory location, index into buffer using stride_ (the - /// distance between elements). - char *p = &base_[nextIndex_ * stride_]; - - switch ( memoryRepresentation_ ) - { - case E57_INT8: - if ( value < E57_INT8_MIN || E57_INT8_MAX < value ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( value ) ); - } - *reinterpret_cast( p ) = static_cast( value ); - break; - case E57_UINT8: - if ( value < E57_UINT8_MIN || E57_UINT8_MAX < value ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( value ) ); - } - *reinterpret_cast( p ) = static_cast( value ); - break; - case E57_INT16: - if ( value < E57_INT16_MIN || E57_INT16_MAX < value ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( value ) ); - } - *reinterpret_cast( p ) = static_cast( value ); - break; - case E57_UINT16: - if ( value < E57_UINT16_MIN || E57_UINT16_MAX < value ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( value ) ); - } - *reinterpret_cast( p ) = static_cast( value ); - break; - case E57_INT32: - if ( value < E57_INT32_MIN || E57_INT32_MAX < value ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( value ) ); - } - *reinterpret_cast( p ) = static_cast( value ); - break; - case E57_UINT32: - if ( value < E57_UINT32_MIN || E57_UINT32_MAX < value ) - { - throw E57_EXCEPTION2( E57_ERROR_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " value=" + toString( value ) ); - } - *reinterpret_cast( p ) = static_cast( value ); - break; - case E57_INT64: - *reinterpret_cast( p ) = static_cast( value ); - break; - case E57_BOOL: - *reinterpret_cast( p ) = ( value ? false : true ); - break; - case E57_REAL32: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - //??? very large integers may lose some lowest bits here. error? - *reinterpret_cast( p ) = static_cast( value ); - break; - case E57_REAL64: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - *reinterpret_cast( p ) = static_cast( value ); - break; - case E57_USTRING: - throw E57_EXCEPTION2( E57_ERROR_EXPECTING_NUMERIC, "pathName=" + pathName_ ); - } - - nextIndex_++; -} - -void SourceDestBufferImpl::setNextInt64( int64_t value, double scale, double offset ) -{ - /// don't checkImageFileOpen - - /// Apply a scale and offset to numbers from file before putting in user's - /// buffer. - - /// Incorporating the scale is optional (requested by user when constructing - /// the sdbuf). If the user did not request scaling, then we send raw values - /// to user's buffer. - if ( !doScaling_ ) - { - /// Use raw value routine, then bail out. - setNextInt64( value ); - return; - } - - /// Verify have room - if ( nextIndex_ >= capacity_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - - /// Calc start of memory location, index into buffer using stride_ (the - /// distance between elements). - char *p = &base_[nextIndex_ * stride_]; - - /// Calc x*scale+offset - double scaledValue; - if ( memoryRepresentation_ == E57_REAL32 || memoryRepresentation_ == E57_REAL64 ) - { - /// Value will be stored in some floating point rep in user's buffer, so - /// keep full resolution here. - scaledValue = value * scale + offset; - } - else - { - /// Value will represented as some integer in user's buffer, so round to - /// nearest integer here. But keep in floating point rep until we know - /// that the value is representable in the user's buffer. - scaledValue = floor( value * scale + offset + 0.5 ); - } - - switch ( memoryRepresentation_ ) - { - case E57_INT8: - if ( scaledValue < E57_INT8_MIN || E57_INT8_MAX < scaledValue ) - { - throw E57_EXCEPTION2( E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " scaledValue=" + toString( scaledValue ) ); - } - *reinterpret_cast( p ) = static_cast( scaledValue ); - break; - case E57_UINT8: - if ( scaledValue < E57_UINT8_MIN || E57_UINT8_MAX < scaledValue ) - { - throw E57_EXCEPTION2( E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " scaledValue=" + toString( scaledValue ) ); - } - *reinterpret_cast( p ) = static_cast( scaledValue ); - break; - case E57_INT16: - if ( scaledValue < E57_INT16_MIN || E57_INT16_MAX < scaledValue ) - { - throw E57_EXCEPTION2( E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " scaledValue=" + toString( scaledValue ) ); - } - *reinterpret_cast( p ) = static_cast( scaledValue ); - break; - case E57_UINT16: - if ( scaledValue < E57_UINT16_MIN || E57_UINT16_MAX < scaledValue ) - { - throw E57_EXCEPTION2( E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " scaledValue=" + toString( scaledValue ) ); - } - *reinterpret_cast( p ) = static_cast( scaledValue ); - break; - case E57_INT32: - if ( scaledValue < E57_INT32_MIN || E57_INT32_MAX < scaledValue ) - { - throw E57_EXCEPTION2( E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " scaledValue=" + toString( scaledValue ) ); - } - *reinterpret_cast( p ) = static_cast( scaledValue ); - break; - case E57_UINT32: - if ( scaledValue < E57_UINT32_MIN || E57_UINT32_MAX < scaledValue ) - { - throw E57_EXCEPTION2( E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " scaledValue=" + toString( scaledValue ) ); - } - *reinterpret_cast( p ) = static_cast( scaledValue ); - break; - case E57_INT64: - *reinterpret_cast( p ) = static_cast( scaledValue ); - break; - case E57_BOOL: - *reinterpret_cast( p ) = ( scaledValue ? false : true ); - break; - case E57_REAL32: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - /// Check that exponent of result is not too big for single precision - /// float - if ( scaledValue < E57_DOUBLE_MIN || E57_DOUBLE_MAX < scaledValue ) - { - throw E57_EXCEPTION2( E57_ERROR_SCALED_VALUE_NOT_REPRESENTABLE, - "pathName=" + pathName_ + " scaledValue=" + toString( scaledValue ) ); - } - *reinterpret_cast( p ) = static_cast( scaledValue ); - break; - case E57_REAL64: - if ( !doConversion_ ) - { - throw E57_EXCEPTION2( E57_ERROR_CONVERSION_REQUIRED, "pathName=" + pathName_ ); - } - *reinterpret_cast( p ) = scaledValue; - break; - case E57_USTRING: - throw E57_EXCEPTION2( E57_ERROR_EXPECTING_NUMERIC, "pathName=" + pathName_ ); - } - - nextIndex_++; -} - -void SourceDestBufferImpl::setNextFloat( float value ) -{ - _setNextReal( value ); -} - -void SourceDestBufferImpl::setNextDouble( double value ) -{ - _setNextReal( value ); -} - -void SourceDestBufferImpl::setNextString( const ustring &value ) -{ - /// don't checkImageFileOpen - - if ( memoryRepresentation_ != E57_USTRING ) - { - throw E57_EXCEPTION2( E57_ERROR_EXPECTING_USTRING, "pathName=" + pathName_ ); - } - - /// Verify have room. - if ( nextIndex_ >= capacity_ ) - { - throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "pathName=" + pathName_ ); - } - - /// Assign to already initialized element in vector - ( *ustrings_ )[nextIndex_] = value; - nextIndex_++; -} - -void SourceDestBufferImpl::checkCompatible( const std::shared_ptr &newBuf ) const -{ - if ( pathName_ != newBuf->pathName() ) - { - throw E57_EXCEPTION2( E57_ERROR_BUFFERS_NOT_COMPATIBLE, - "pathName=" + pathName_ + " newPathName=" + newBuf->pathName() ); - } - if ( memoryRepresentation_ != newBuf->memoryRepresentation() ) - { - throw E57_EXCEPTION2( E57_ERROR_BUFFERS_NOT_COMPATIBLE, - "memoryRepresentation=" + toString( memoryRepresentation_ ) + - " newMemoryType=" + toString( newBuf->memoryRepresentation() ) ); - } - if ( capacity_ != newBuf->capacity() ) - { - throw E57_EXCEPTION2( E57_ERROR_BUFFERS_NOT_COMPATIBLE, - "capacity=" + toString( capacity_ ) + " newCapacity=" + toString( newBuf->capacity() ) ); - } - if ( doConversion_ != newBuf->doConversion() ) - { - throw E57_EXCEPTION2( E57_ERROR_BUFFERS_NOT_COMPATIBLE, - "doConversion=" + toString( doConversion_ ) + - "newDoConversion=" + toString( newBuf->doConversion() ) ); - } - if ( stride_ != newBuf->stride() ) - { - throw E57_EXCEPTION2( E57_ERROR_BUFFERS_NOT_COMPATIBLE, - "stride=" + toString( stride_ ) + " newStride=" + toString( newBuf->stride() ) ); - } -} - -#ifdef E57_DEBUG -void SourceDestBufferImpl::dump( int indent, std::ostream &os ) -{ - /// don't checkImageFileOpen - - os << space( indent ) << "pathName: " << pathName_ << std::endl; - os << space( indent ) << "memoryRepresentation: "; - switch ( memoryRepresentation_ ) - { - case E57_INT8: - os << "int8_t" << std::endl; - break; - case E57_UINT8: - os << "uint8_t" << std::endl; - break; - case E57_INT16: - os << "int16_t" << std::endl; - break; - case E57_UINT16: - os << "uint16_t" << std::endl; - break; - case E57_INT32: - os << "int32_t" << std::endl; - break; - case E57_UINT32: - os << "uint32_t" << std::endl; - break; - case E57_INT64: - os << "int64_t" << std::endl; - break; - case E57_BOOL: - os << "bool" << std::endl; - break; - case E57_REAL32: - os << "float" << std::endl; - break; - case E57_REAL64: - os << "double" << std::endl; - break; - case E57_USTRING: - os << "ustring" << std::endl; - break; - default: - os << "" << std::endl; - break; - } - os << space( indent ) << "base: " << static_cast( base_ ) << std::endl; - os << space( indent ) << "ustrings: " << static_cast( ustrings_ ) << std::endl; - os << space( indent ) << "capacity: " << capacity_ << std::endl; - os << space( indent ) << "doConversion: " << doConversion_ << std::endl; - os << space( indent ) << "doScaling: " << doScaling_ << std::endl; - os << space( indent ) << "stride: " << stride_ << std::endl; - os << space( indent ) << "nextIndex: " << nextIndex_ << std::endl; -} -#endif diff --git a/src/3rdParty/libE57Format/src/SourceDestBufferImpl.h b/src/3rdParty/libE57Format/src/SourceDestBufferImpl.h deleted file mode 100644 index 896b45dda2..0000000000 --- a/src/3rdParty/libE57Format/src/SourceDestBufferImpl.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include "Common.h" - -namespace e57 -{ - class ImageFileImpl; - - class SourceDestBufferImpl : public std::enable_shared_from_this - { - public: - SourceDestBufferImpl( ImageFileImplWeakPtr destImageFile, const ustring &pathName, const size_t capacity, - bool doConversion = false, bool doScaling = false ); - - template void setTypeInfo( T *base, size_t stride = sizeof( T ) ); - - SourceDestBufferImpl( ImageFileImplWeakPtr destImageFile, const ustring &pathName, StringList *b ); - - ImageFileImplWeakPtr destImageFile() const - { - return destImageFile_; - } - - ustring pathName() const - { - return pathName_; - } - MemoryRepresentation memoryRepresentation() const - { - return memoryRepresentation_; - } - void *base() const - { - return base_; - } - StringList *ustrings() const - { - return ustrings_; - } - bool doConversion() const - { - return doConversion_; - } - bool doScaling() const - { - return doScaling_; - } - size_t stride() const - { - return stride_; - } - size_t capacity() const - { - return capacity_; - } - unsigned nextIndex() const - { - return nextIndex_; - } - void rewind() - { - nextIndex_ = 0; - } - - int64_t getNextInt64(); - int64_t getNextInt64( double scale, double offset ); - float getNextFloat(); - double getNextDouble(); - ustring getNextString(); - void setNextInt64( int64_t value ); - void setNextInt64( int64_t value, double scale, double offset ); - void setNextFloat( float value ); - void setNextDouble( double value ); - void setNextString( const ustring &value ); - - void checkCompatible( const std::shared_ptr &newBuf ) const; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ); -#endif - - private: - template void _setNextReal( T inValue ); - - void checkState_() const; /// Common routine to check that constructor - /// arguments were ok, throws if not - - //??? verify alignment - ImageFileImplWeakPtr destImageFile_; - ustring pathName_; /// Pathname from CompressedVectorNode to source/dest - /// object, e.g. "Indices/0" - MemoryRepresentation memoryRepresentation_; /// Type of element (e.g. E57_INT8, E57_UINT64, - /// DOUBLE...) - char *base_ = nullptr; /// Address of first element, for non-ustring buffers - size_t capacity_ = 0; /// Total number of elements in array - bool doConversion_ = false; /// Convert memory representation to/from disk representation - bool doScaling_ = false; /// Apply scale factor for integer type - size_t stride_ = 0; /// Distance between each element (different than size_ - /// if elements not contiguous) - unsigned nextIndex_ = 0; /// Number of elements that have been set (dest - /// buffer) or read (source buffer) since rewind(). - StringList *ustrings_ = nullptr; /// Optional array of ustrings (used if - /// memoryRepresentation_==E57_USTRING) ???ownership - }; -} diff --git a/src/3rdParty/libE57Format/src/StringNodeImpl.cpp b/src/3rdParty/libE57Format/src/StringNodeImpl.cpp deleted file mode 100644 index 8d03d58138..0000000000 --- a/src/3rdParty/libE57Format/src/StringNodeImpl.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "StringNodeImpl.h" -#include "CheckedFile.h" - -namespace e57 -{ - StringNodeImpl::StringNodeImpl( ImageFileImplWeakPtr destImageFile, const ustring &value ) : - NodeImpl( destImageFile ), value_( value ) - { - // don't checkImageFileOpen, NodeImpl() will do it - } - - bool StringNodeImpl::isTypeEquivalent( NodeImplSharedPtr ni ) - { - // don't checkImageFileOpen - - /// Same node type? - if ( ni->type() != E57_STRING ) - { - return ( false ); - } - - /// ignore value_, doesn't have to match - - /// Types match - return ( true ); - } - - bool StringNodeImpl::isDefined( const ustring &pathName ) - { - // don't checkImageFileOpen - - /// We have no sub-structure, so if path not empty return false - return pathName.empty(); - } - - ustring StringNodeImpl::value() - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return ( value_ ); - } - - void StringNodeImpl::checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) - { - // don't checkImageFileOpen - - /// We are a leaf node, so verify that we are listed in set. - if ( pathNames.find( relativePathName( origin ) ) == pathNames.end() ) - { - throw E57_EXCEPTION2( E57_ERROR_NO_BUFFER_FOR_ELEMENT, "this->pathName=" + this->pathName() ); - } - } - - void StringNodeImpl::writeXml( ImageFileImplSharedPtr /*imf*/, CheckedFile &cf, int indent, - const char *forcedFieldName ) - { - // don't checkImageFileOpen - - ustring fieldName; - if ( forcedFieldName ) - { - fieldName = forcedFieldName; - } - else - { - fieldName = elementName_; - } - - cf << space( indent ) << "<" << fieldName << " type=\"String\""; - - /// Write value as child text, unless it is the default value - if ( value_.empty() ) - { - cf << "/>\n"; - } - else - { - cf << ">", which will be split across - /// two CDATA directives - while ( currentPosition < len ) - { - size_t found = value_.find( "]]>", currentPosition ); - - if ( found == std::string::npos ) - { - /// Didn't find any more "]]>", so can send the rest. - cf << value_.substr( currentPosition ); - break; - } - - /// Must output in two pieces, first send up to end of "]]" (don't send - /// the following ">"). - cf << value_.substr( currentPosition, found - currentPosition + 2 ); - - /// Then start a new CDATA - cf << "]]>" plus the remaining part of the string - currentPosition = found + 2; - } - cf << "]]>\n"; - } - } - -#ifdef E57_DEBUG - void StringNodeImpl::dump( int indent, std::ostream &os ) const - { - os << space( indent ) << "type: String" - << " (" << type() << ")" << std::endl; - NodeImpl::dump( indent, os ); - os << space( indent ) << "value: '" << value_ << "'" << std::endl; - } -#endif -} diff --git a/src/3rdParty/libE57Format/src/StringNodeImpl.h b/src/3rdParty/libE57Format/src/StringNodeImpl.h deleted file mode 100644 index 73dc4fa294..0000000000 --- a/src/3rdParty/libE57Format/src/StringNodeImpl.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "NodeImpl.h" - -namespace e57 -{ - class StringNodeImpl : public NodeImpl - { - public: - explicit StringNodeImpl( ImageFileImplWeakPtr destImageFile, const ustring &value = "" ); - ~StringNodeImpl() override = default; - - NodeType type() const override - { - return E57_STRING; - } - bool isTypeEquivalent( NodeImplSharedPtr ni ) override; - bool isDefined( const ustring &pathName ) override; - - ustring value(); - - void checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) override; - - void writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, - const char *forcedFieldName = nullptr ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - - private: - ustring value_; - }; - -} diff --git a/src/3rdParty/libE57Format/src/StructureNodeImpl.cpp b/src/3rdParty/libE57Format/src/StructureNodeImpl.cpp deleted file mode 100644 index e4aacb6ca0..0000000000 --- a/src/3rdParty/libE57Format/src/StructureNodeImpl.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include - -#include "CheckedFile.h" -#include "ImageFileImpl.h" -#include "StructureNodeImpl.h" - -using namespace e57; - -StructureNodeImpl::StructureNodeImpl( ImageFileImplWeakPtr destImageFile ) : NodeImpl( destImageFile ) -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); -} - -NodeType StructureNodeImpl::type() const -{ - /// don't checkImageFileOpen - return E57_STRUCTURE; -} - -//??? use visitor? -bool StructureNodeImpl::isTypeEquivalent( NodeImplSharedPtr ni ) -{ - /// don't checkImageFileOpen - - /// Same node type? - if ( ni->type() != E57_STRUCTURE ) - { - return ( false ); - } - - /// Downcast to shared_ptr - std::shared_ptr si( std::static_pointer_cast( ni ) ); - - /// Same number of children? - if ( childCount() != si->childCount() ) - { - return ( false ); - } - - /// Check each child is equivalent - for ( unsigned i = 0; i < childCount(); i++ ) - { //??? vector iterator? - ustring myChildsFieldName = children_.at( i )->elementName(); - /// Check if matching field name is in same position (to speed things up) - if ( myChildsFieldName == si->children_.at( i )->elementName() ) - { - if ( !children_.at( i )->isTypeEquivalent( si->children_.at( i ) ) ) - { - return ( false ); - } - } - else - { - /// Children in different order, so lookup by name and check if equal - /// to our child - if ( !si->isDefined( myChildsFieldName ) ) - { - return ( false ); - } - if ( !children_.at( i )->isTypeEquivalent( si->lookup( myChildsFieldName ) ) ) - { - return ( false ); - } - } - } - - /// Types match - return ( true ); -} - -bool StructureNodeImpl::isDefined( const ustring &pathName ) -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - NodeImplSharedPtr ni( lookup( pathName ) ); - return ( ni != nullptr ); -} - -void StructureNodeImpl::setAttachedRecursive() -{ - /// Mark this node as attached to an ImageFile - isAttached_ = true; - - /// Not a leaf node, so mark all our children - for ( auto &child : children_ ) - { - child->setAttachedRecursive(); - } -} - -int64_t StructureNodeImpl::childCount() const -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - return children_.size(); -} -NodeImplSharedPtr StructureNodeImpl::get( int64_t index ) -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - if ( index < 0 || index >= static_cast( children_.size() ) ) - { // %%% Possible truncation on platforms where size_t = uint64 - throw E57_EXCEPTION2( E57_ERROR_CHILD_INDEX_OUT_OF_BOUNDS, "this->pathName=" + this->pathName() + - " index=" + toString( index ) + - " size=" + toString( children_.size() ) ); - } - return ( children_.at( static_cast( index ) ) ); -} - -NodeImplSharedPtr StructureNodeImpl::get( const ustring &pathName ) -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - NodeImplSharedPtr ni( lookup( pathName ) ); - - if ( !ni ) - { - throw E57_EXCEPTION2( E57_ERROR_PATH_UNDEFINED, "this->pathName=" + this->pathName() + " pathName=" + pathName ); - } - return ( ni ); -} - -NodeImplSharedPtr StructureNodeImpl::lookup( const ustring &pathName ) -{ - /// don't checkImageFileOpen - //??? use lookup(fields, level) instead, for speed. - bool isRelative; - std::vector fields; - ImageFileImplSharedPtr imf( destImageFile_ ); - imf->pathNameParse( pathName, isRelative, fields ); // throws if bad pathName - - if ( isRelative || isRoot() ) - { - if ( fields.empty() ) - { - if ( isRelative ) - { - return NodeImplSharedPtr(); /// empty pointer - } - else - { - NodeImplSharedPtr root( getRoot() ); - return ( root ); - } - } - else - { - /// Find child with elementName that matches first field in path - unsigned i; - for ( i = 0; i < children_.size(); i++ ) - { - if ( fields.at( 0 ) == children_.at( i )->elementName() ) - { - break; - } - } - if ( i == children_.size() ) - { - return NodeImplSharedPtr(); /// empty pointer - } - - if ( fields.size() == 1 ) - { - return ( children_.at( i ) ); - } - - //??? use level here rather than unparse - /// Remove first field in path - fields.erase( fields.begin() ); - - /// Call lookup on child object with remaining fields in path name - return children_.at( i )->lookup( imf->pathNameUnparse( true, fields ) ); - } - } - else - { /// Absolute pathname and we aren't at the root - /// Find root of the tree - NodeImplSharedPtr root( getRoot() ); - - /// Call lookup on root - return ( root->lookup( pathName ) ); - } -} - -void StructureNodeImpl::set( int64_t index64, NodeImplSharedPtr ni ) -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - - auto index = static_cast( index64 ); - - /// Allow index == current number of elements, interpret as append - if ( index64 < 0 || index64 > UINT_MAX || index > children_.size() ) - { - throw E57_EXCEPTION2( E57_ERROR_CHILD_INDEX_OUT_OF_BOUNDS, "this->pathName=" + this->pathName() + - " index=" + toString( index64 ) + - " size=" + toString( children_.size() ) ); - } - - /// Enforce "set once" policy, only allow append - if ( index != children_.size() ) - { - throw E57_EXCEPTION2( E57_ERROR_SET_TWICE, - "this->pathName=" + this->pathName() + " index=" + toString( index64 ) ); - } - - /// Verify that child is destined for same ImageFile as this is - ImageFileImplSharedPtr thisDest( destImageFile() ); - ImageFileImplSharedPtr niDest( ni->destImageFile() ); - if ( thisDest != niDest ) - { - throw E57_EXCEPTION2( E57_ERROR_DIFFERENT_DEST_IMAGEFILE, - "this->destImageFile" + thisDest->fileName() + " ni->destImageFile" + niDest->fileName() ); - } - - /// Field name is string version of index value, e.g. "14" - std::stringstream elementName; - elementName << index; - - /// If this struct is type constrained, can't add new child - if ( isTypeConstrained() ) - { - throw E57_EXCEPTION2( E57_ERROR_HOMOGENEOUS_VIOLATION, "this->pathName=" + this->pathName() ); - } - - ni->setParent( shared_from_this(), elementName.str() ); - children_.push_back( ni ); -} - -void StructureNodeImpl::set( const ustring &pathName, NodeImplSharedPtr ni, bool autoPathCreate ) -{ - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - //??? parse pathName! throw if impossible, absolute and multi-level paths... - //??? enforce type constraints on path (non-zero index types match zero index - // types for VECTOR, - // COMPRESSED_VECTOR - -#ifdef E57_MAX_VERBOSE - std::cout << "StructureNodeImpl::set(pathName=" << pathName << ", ni, autoPathCreate=" << autoPathCreate - << std::endl; -#endif - - bool isRelative; - std::vector fields; - - /// Path may be absolute or relative with several levels. Break string into - /// individual levels. - ImageFileImplSharedPtr imf( destImageFile_ ); - imf->pathNameParse( pathName, isRelative, fields ); // throws if bad pathName - if ( isRelative ) - { - /// Relative path, starting from current object, e.g. "foo/17/bar" - set( fields, 0, ni, autoPathCreate ); - } - else - { - /// Absolute path (starting from root), e.g. "/foo/17/bar" - getRoot()->set( fields, 0, ni, autoPathCreate ); - } -} - -void StructureNodeImpl::set( const std::vector &fields, unsigned level, NodeImplSharedPtr ni, - bool autoPathCreate ) -{ -#ifdef E57_MAX_VERBOSE - std::cout << "StructureNodeImpl::set: level=" << level << std::endl; - for ( unsigned i = 0; i < fields.size(); i++ ) - { - std::cout << " field[" << i << "]: " << fields.at( i ) << std::endl; - } -#endif - - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - //??? check if field is numeric string (e.g. "17"), verify number is same as - // index, else throw - // bad_path - - /// Check if trying to set the root node "/", which is illegal - if ( level == 0 && fields.empty() ) - { - throw E57_EXCEPTION2( E57_ERROR_SET_TWICE, "this->pathName=" + this->pathName() + " element=/" ); - } - - /// Serial search for matching field name, if find match, have error since - /// can't set twice - for ( auto &child : children_ ) - { - if ( fields.at( level ) == child->elementName() ) - { - if ( level == fields.size() - 1 ) - { - /// Enforce "set once" policy, don't allow reset - throw E57_EXCEPTION2( E57_ERROR_SET_TWICE, - "this->pathName=" + this->pathName() + " element=" + fields[level] ); - } - - /// Recurse on child - child->set( fields, level + 1, ni ); - - return; - } - } - /// Didn't find matching field name, so have a new child. - - /// If this struct is type constrained, can't add new child - if ( isTypeConstrained() ) - { - throw E57_EXCEPTION2( E57_ERROR_HOMOGENEOUS_VIOLATION, "this->pathName=" + this->pathName() ); - } - - /// Check if we are at bottom level - if ( level == fields.size() - 1 ) - { - /// At bottom, so append node at end of children - ni->setParent( shared_from_this(), fields.at( level ) ); - children_.push_back( ni ); - } - else - { - /// Not at bottom level, if not autoPathCreate have an error - if ( !autoPathCreate ) - { - throw E57_EXCEPTION2( E57_ERROR_PATH_UNDEFINED, - "this->pathName=" + this->pathName() + " field=" + fields.at( level ) ); - } - //??? what if extra fields are numbers? - - /// Do autoPathCreate: Create nested Struct objects for extra field names - /// in path - NodeImplSharedPtr parent( shared_from_this() ); - for ( ; level != fields.size() - 1; level++ ) - { - std::shared_ptr child( new StructureNodeImpl( destImageFile_ ) ); - parent->set( fields.at( level ), child ); - parent = child; - } - parent->set( fields.at( level ), ni ); - } -} - -void StructureNodeImpl::append( NodeImplSharedPtr ni ) -{ - /// don't checkImageFileOpen, set() will do it - - /// Create new node at end of list with integer field name - set( childCount(), ni ); -} - -//??? use visitor? -void StructureNodeImpl::checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) -{ - /// don't checkImageFileOpen - - /// Not a leaf node, so check all our children - for ( auto &child : children_ ) - { - child->checkLeavesInSet( pathNames, origin ); - } -} - -//??? use visitor? -void StructureNodeImpl::writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, const char *forcedFieldName ) -{ - /// don't checkImageFileOpen - - ustring fieldName; - if ( forcedFieldName ) - { - fieldName = forcedFieldName; - } - else - { - fieldName = elementName_; - } - - cf << space( indent ) << "<" << fieldName << " type=\"Structure\""; - - const int numSpaces = indent + static_cast( fieldName.length() ) + 2; - - /// If this struct is the root for the E57 file, add name space declarations - /// Note the prototype of a CompressedVector is a separate tree, so don't - /// want to write out namespaces if not the ImageFile root - if ( isRoot() && shared_from_this() == imf->root() ) - { - bool gotDefaultNamespace = false; - for ( size_t i = 0; i < imf->extensionsCount(); i++ ) - { - const char *xmlnsExtension; - if ( imf->extensionsPrefix( i ).empty() ) - { - gotDefaultNamespace = true; - xmlnsExtension = "xmlns"; - } - else - { - xmlnsExtension = "xmlns:"; - } - - const int index = static_cast( i ); - - cf << "\n" - << space( numSpaces ) << xmlnsExtension << imf->extensionsPrefix( index ) << "=\"" - << imf->extensionsUri( index ) << "\""; - } - - /// If user didn't explicitly declare a default namespace, use the current - /// E57 standard one. - if ( !gotDefaultNamespace ) - { - cf << "\n" << space( numSpaces ) << "xmlns=\"" << E57_V1_0_URI << "\""; - } - } - if ( !children_.empty() ) - { - cf << ">\n"; - - /// Write all children nested inside Structure element - for ( auto &child : children_ ) - { - child->writeXml( imf, cf, indent + 2 ); - } - - /// Write closing tag - cf << space( indent ) << "\n"; - } - else - { - /// XML element has no child elements - cf << "/>\n"; - } -} - -//??? use visitor? -#ifdef E57_DEBUG -void StructureNodeImpl::dump( int indent, std::ostream &os ) const -{ - /// don't checkImageFileOpen - os << space( indent ) << "type: Structure" - << " (" << type() << ")" << std::endl; - NodeImpl::dump( indent, os ); - for ( unsigned i = 0; i < children_.size(); i++ ) - { - os << space( indent ) << "child[" << i << "]:" << std::endl; - children_.at( i )->dump( indent + 2, os ); - } -} -#endif diff --git a/src/3rdParty/libE57Format/src/StructureNodeImpl.h b/src/3rdParty/libE57Format/src/StructureNodeImpl.h deleted file mode 100644 index 53546d92d3..0000000000 --- a/src/3rdParty/libE57Format/src/StructureNodeImpl.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include "NodeImpl.h" - -namespace e57 -{ - - class StructureNodeImpl : public NodeImpl - { - public: - StructureNodeImpl( ImageFileImplWeakPtr destImageFile ); - ~StructureNodeImpl() override = default; - - NodeType type() const override; - bool isTypeEquivalent( NodeImplSharedPtr ni ) override; - bool isDefined( const ustring &pathName ) override; - void setAttachedRecursive() override; - - virtual int64_t childCount() const; - - virtual NodeImplSharedPtr get( int64_t index ); - NodeImplSharedPtr get( const ustring &pathName ) override; - - virtual void set( int64_t index, NodeImplSharedPtr ni ); - void set( const ustring &pathName, NodeImplSharedPtr ni, bool autoPathCreate = false ) override; - void set( const StringList &fields, unsigned level, NodeImplSharedPtr ni, bool autoPathCreate = false ) override; - virtual void append( NodeImplSharedPtr ni ); - - void checkLeavesInSet( const StringSet &pathNames, NodeImplSharedPtr origin ) override; - - void writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, - const char *forcedFieldName = nullptr ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - - protected: - friend class CompressedVectorReaderImpl; - NodeImplSharedPtr lookup( const ustring &pathName ) override; - - std::vector children_; - }; -} diff --git a/src/3rdParty/libE57Format/src/VectorNodeImpl.cpp b/src/3rdParty/libE57Format/src/VectorNodeImpl.cpp deleted file mode 100644 index 9534375a23..0000000000 --- a/src/3rdParty/libE57Format/src/VectorNodeImpl.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "VectorNodeImpl.h" -#include "CheckedFile.h" - -namespace e57 -{ - VectorNodeImpl::VectorNodeImpl( ImageFileImplWeakPtr destImageFile, bool allowHeteroChildren ) : - StructureNodeImpl( destImageFile ), allowHeteroChildren_( allowHeteroChildren ) - { - /// don't checkImageFileOpen, StructNodeImpl() will do it - } - - bool VectorNodeImpl::isTypeEquivalent( NodeImplSharedPtr ni ) - { - /// don't checkImageFileOpen - - /// Same node type? - if ( ni->type() != E57_VECTOR ) - { - return ( false ); - } - - std::shared_ptr ai( std::static_pointer_cast( ni ) ); - - /// allowHeteroChildren must match - if ( allowHeteroChildren_ != ai->allowHeteroChildren_ ) - { - return ( false ); - } - - /// Same number of children? - if ( childCount() != ai->childCount() ) - { - return ( false ); - } - - /// Check each child, must be in same order - for ( unsigned i = 0; i < childCount(); i++ ) - { - if ( !children_.at( i )->isTypeEquivalent( ai->children_.at( i ) ) ) - { - return ( false ); - } - } - - /// Types match - return ( true ); - } - - bool VectorNodeImpl::allowHeteroChildren() const - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - return allowHeteroChildren_; - } - - void VectorNodeImpl::set( int64_t index64, NodeImplSharedPtr ni ) - { - checkImageFileOpen( __FILE__, __LINE__, static_cast( __FUNCTION__ ) ); - if ( !allowHeteroChildren_ ) - { - /// New node type must match all existing children - for ( auto &child : children_ ) - { - if ( !child->isTypeEquivalent( ni ) ) - { - throw E57_EXCEPTION2( E57_ERROR_HOMOGENEOUS_VIOLATION, "this->pathName=" + this->pathName() ); - } - } - } - - ///??? for now, use base implementation - StructureNodeImpl::set( index64, ni ); - } - - void VectorNodeImpl::writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, const char *forcedFieldName ) - { - /// don't checkImageFileOpen - - ustring fieldName; - if ( forcedFieldName ) - { - fieldName = forcedFieldName; - } - else - { - fieldName = elementName_; - } - - cf << space( indent ) << "<" << fieldName << " type=\"Vector\" allowHeterogeneousChildren=\"" - << static_cast( allowHeteroChildren_ ) << "\">\n"; - for ( auto &child : children_ ) - { - child->writeXml( imf, cf, indent + 2, "vectorChild" ); - } - cf << space( indent ) << "\n"; - } - -#ifdef E57_DEBUG - void VectorNodeImpl::dump( int indent, std::ostream &os ) const - { - /// don't checkImageFileOpen - os << space( indent ) << "type: Vector" - << " (" << type() << ")" << std::endl; - NodeImpl::dump( indent, os ); - os << space( indent ) << "allowHeteroChildren: " << allowHeteroChildren() << std::endl; - for ( unsigned i = 0; i < children_.size(); i++ ) - { - os << space( indent ) << "child[" << i << "]:" << std::endl; - children_.at( i )->dump( indent + 2, os ); - } - } -#endif -} diff --git a/src/3rdParty/libE57Format/src/VectorNodeImpl.h b/src/3rdParty/libE57Format/src/VectorNodeImpl.h deleted file mode 100644 index fc4adc825d..0000000000 --- a/src/3rdParty/libE57Format/src/VectorNodeImpl.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once -/* - * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net) - * Modified work Copyright 2018 - 2020 Andy Maloney - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "StructureNodeImpl.h" - -namespace e57 -{ - class VectorNodeImpl : public StructureNodeImpl - { - public: - explicit VectorNodeImpl( ImageFileImplWeakPtr destImageFile, bool allowHeteroChildren ); - ~VectorNodeImpl() override = default; - - NodeType type() const override - { - return E57_VECTOR; - } - - bool isTypeEquivalent( NodeImplSharedPtr ni ) override; - bool allowHeteroChildren() const; - - void set( int64_t index, NodeImplSharedPtr ni ) override; - - void writeXml( ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, - const char *forcedFieldName = nullptr ) override; - -#ifdef E57_DEBUG - void dump( int indent = 0, std::ostream &os = std::cout ) const override; -#endif - - private: - bool allowHeteroChildren_; - }; -} diff --git a/src/3rdParty/libE57Format/src/WriterImpl.cpp b/src/3rdParty/libE57Format/src/WriterImpl.cpp deleted file mode 100644 index f8942038b3..0000000000 --- a/src/3rdParty/libE57Format/src/WriterImpl.cpp +++ /dev/null @@ -1,1113 +0,0 @@ -/* - * Copyright (c) 2010 Stan Coleby (scoleby@intelisum.com) - * Copyright (c) 2020 PTC Inc. - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "WriterImpl.h" - -#include "Common.h" -#include - -namespace e57 -{ - - WriterImpl::WriterImpl( const ustring &filePath, const ustring &coordinateMetadata ) : - imf_( filePath, "w" ), root_( imf_.root() ), data3D_( imf_, true ), images2D_( imf_, true ) - { - // We are using the E57 v1.0 data format standard fieldnames. - // The standard fieldnames are used without an extension prefix (in the default namespace). - // We explicitly register it for completeness (the reference implementation would do it for us, if we didn't). - imf_.extensionsAdd( "", E57_V1_0_URI ); - - // Set per-file properties. - // Path names: "/formatName", "/majorVersion", "/minorVersion", "/coordinateMetadata" - root_.set( "formatName", StringNode( imf_, "ASTM E57 3D Imaging Data File" ) ); - root_.set( "guid", StringNode( imf_, generateRandomGUID() ) ); - - // Get ASTM version number supported by library, so can write it into file - int astmMajor; - int astmMinor; - ustring libraryId; - Utilities::getVersions( astmMajor, astmMinor, libraryId ); - - root_.set( "versionMajor", IntegerNode( imf_, astmMajor ) ); - root_.set( "versionMinor", IntegerNode( imf_, astmMinor ) ); - root_.set( "e57LibraryVersion", StringNode( imf_, libraryId ) ); - - // Save a dummy string for coordinate system. - // Really should be a valid WKT string identifying the coordinate reference system (CRS). - if ( !coordinateMetadata.empty() ) - { - root_.set( "coordinateMetadata", StringNode( imf_, coordinateMetadata ) ); - } - -// Create creationDateTime structure -// Path name: "/creationDateTime -// TODO currently no support for handling UTC <-> GPS time conversions -// note that "creationDateTime" is optional in the standard -#if 0 - StructureNode creationDateTime = StructureNode(imf_); - creationDateTime.set("dateTimeValue", FloatNode(imf_, GetGPSTime())); - creationDateTime.set("isAtomicClockReferenced", IntegerNode(imf_,0)); - root_.set("creationDateTime", creationDateTime); -#endif - - root_.set( "data3D", data3D_ ); - root_.set( "images2D", images2D_ ); - } - - WriterImpl::~WriterImpl() - { - if ( IsOpen() ) - { - Close(); - } - } - - bool WriterImpl::IsOpen() const - { - return imf_.isOpen(); - } - - bool WriterImpl::Close() - { - if ( !IsOpen() ) - { - return false; - } - - imf_.close(); - return true; - } - - StructureNode WriterImpl::GetRawE57Root() - { - return root_; - } - - VectorNode WriterImpl::GetRawData3D() - { - return data3D_; - } - - VectorNode WriterImpl::GetRawImages2D() - { - return images2D_; - } - - ImageFile WriterImpl::GetRawIMF() - { - return imf_; - } - - int64_t WriterImpl::NewImage2D( Image2D &image2DHeader ) - { - int64_t pos = -1; - - StructureNode image = StructureNode( imf_ ); - images2D_.append( image ); - pos = images2D_.childCount() - 1; - - if ( image2DHeader.guid.empty() ) - { - image2DHeader.guid = generateRandomGUID(); - } - - image.set( "guid", StringNode( imf_, image2DHeader.guid ) ); // required - - if ( !image2DHeader.name.empty() ) - { - image.set( "name", StringNode( imf_, image2DHeader.name ) ); - } - if ( !image2DHeader.description.empty() ) - { - image.set( "description", StringNode( imf_, image2DHeader.description ) ); - } - - // Add various sensor and version strings to image. - if ( !image2DHeader.sensorVendor.empty() ) - { - image.set( "sensorVendor", StringNode( imf_, image2DHeader.sensorVendor ) ); - } - if ( !image2DHeader.sensorModel.empty() ) - { - image.set( "sensorModel", StringNode( imf_, image2DHeader.sensorModel ) ); - } - if ( !image2DHeader.sensorSerialNumber.empty() ) - { - image.set( "sensorSerialNumber", StringNode( imf_, image2DHeader.sensorSerialNumber ) ); - } - - if ( !image2DHeader.associatedData3DGuid.empty() ) - { - image.set( "associatedData3DGuid", StringNode( imf_, image2DHeader.associatedData3DGuid ) ); - } - - if ( image2DHeader.acquisitionDateTime.dateTimeValue > 0. ) - { - StructureNode acquisitionDateTime = StructureNode( imf_ ); - image.set( "acquisitionDateTime", acquisitionDateTime ); - acquisitionDateTime.set( "dateTimeValue", FloatNode( imf_, image2DHeader.acquisitionDateTime.dateTimeValue ) ); - acquisitionDateTime.set( "isAtomicClockReferenced", - IntegerNode( imf_, image2DHeader.acquisitionDateTime.isAtomicClockReferenced ) ); - } - - // Create pose structure for image. - if ( image2DHeader.pose != RigidBodyTransform{} ) - { - StructureNode pose = StructureNode( imf_ ); - image.set( "pose", pose ); - - StructureNode rotation = StructureNode( imf_ ); - pose.set( "rotation", rotation ); - rotation.set( "w", FloatNode( imf_, image2DHeader.pose.rotation.w ) ); - rotation.set( "x", FloatNode( imf_, image2DHeader.pose.rotation.x ) ); - rotation.set( "y", FloatNode( imf_, image2DHeader.pose.rotation.y ) ); - rotation.set( "z", FloatNode( imf_, image2DHeader.pose.rotation.z ) ); - - StructureNode translation = StructureNode( imf_ ); - pose.set( "translation", translation ); - translation.set( "x", FloatNode( imf_, image2DHeader.pose.translation.x ) ); - translation.set( "y", FloatNode( imf_, image2DHeader.pose.translation.y ) ); - translation.set( "z", FloatNode( imf_, image2DHeader.pose.translation.z ) ); - } - - if ( image2DHeader.visualReferenceRepresentation.jpegImageSize > 0 || - image2DHeader.visualReferenceRepresentation.pngImageSize > 0 ) - { - StructureNode visualReferenceRepresentation = StructureNode( imf_ ); - image.set( "visualReferenceRepresentation", visualReferenceRepresentation ); - - if ( image2DHeader.visualReferenceRepresentation.jpegImageSize > 0 ) - { - visualReferenceRepresentation.set( - "jpegImage", BlobNode( imf_, image2DHeader.visualReferenceRepresentation.jpegImageSize ) ); - } - else if ( image2DHeader.visualReferenceRepresentation.pngImageSize > 0 ) - { - visualReferenceRepresentation.set( - "pngImage", BlobNode( imf_, image2DHeader.visualReferenceRepresentation.pngImageSize ) ); - } - if ( image2DHeader.visualReferenceRepresentation.imageMaskSize > 0 ) - { - visualReferenceRepresentation.set( - "imageMask", BlobNode( imf_, image2DHeader.visualReferenceRepresentation.imageMaskSize ) ); - } - - visualReferenceRepresentation.set( - "imageHeight", IntegerNode( imf_, image2DHeader.visualReferenceRepresentation.imageHeight ) ); - visualReferenceRepresentation.set( - "imageWidth", IntegerNode( imf_, image2DHeader.visualReferenceRepresentation.imageWidth ) ); - } - else if ( image2DHeader.pinholeRepresentation.jpegImageSize > 0 || - image2DHeader.pinholeRepresentation.pngImageSize > 0 ) - { - StructureNode pinholeRepresentation = StructureNode( imf_ ); - image.set( "pinholeRepresentation", pinholeRepresentation ); - - if ( image2DHeader.pinholeRepresentation.jpegImageSize > 0 ) - { - pinholeRepresentation.set( "jpegImage", - BlobNode( imf_, image2DHeader.pinholeRepresentation.jpegImageSize ) ); - } - else if ( image2DHeader.pinholeRepresentation.pngImageSize > 0 ) - { - pinholeRepresentation.set( "pngImage", BlobNode( imf_, image2DHeader.pinholeRepresentation.pngImageSize ) ); - } - if ( image2DHeader.pinholeRepresentation.imageMaskSize > 0 ) - { - pinholeRepresentation.set( "imageMask", - BlobNode( imf_, image2DHeader.pinholeRepresentation.imageMaskSize ) ); - } - - pinholeRepresentation.set( "focalLength", FloatNode( imf_, image2DHeader.pinholeRepresentation.focalLength ) ); - pinholeRepresentation.set( "imageHeight", - IntegerNode( imf_, image2DHeader.pinholeRepresentation.imageHeight ) ); - pinholeRepresentation.set( "imageWidth", IntegerNode( imf_, image2DHeader.pinholeRepresentation.imageWidth ) ); - pinholeRepresentation.set( "pixelHeight", FloatNode( imf_, image2DHeader.pinholeRepresentation.pixelHeight ) ); - pinholeRepresentation.set( "pixelWidth", FloatNode( imf_, image2DHeader.pinholeRepresentation.pixelWidth ) ); - pinholeRepresentation.set( "principalPointX", - FloatNode( imf_, image2DHeader.pinholeRepresentation.principalPointX ) ); - pinholeRepresentation.set( "principalPointY", - FloatNode( imf_, image2DHeader.pinholeRepresentation.principalPointY ) ); - } - else if ( image2DHeader.sphericalRepresentation.jpegImageSize > 0 || - image2DHeader.sphericalRepresentation.pngImageSize > 0 ) - { - StructureNode sphericalRepresentation = StructureNode( imf_ ); - image.set( "sphericalRepresentation", sphericalRepresentation ); - - if ( image2DHeader.sphericalRepresentation.jpegImageSize > 0 ) - { - sphericalRepresentation.set( "jpegImage", - BlobNode( imf_, image2DHeader.sphericalRepresentation.jpegImageSize ) ); - } - else if ( image2DHeader.sphericalRepresentation.pngImageSize > 0 ) - { - sphericalRepresentation.set( "pngImage", - BlobNode( imf_, image2DHeader.sphericalRepresentation.pngImageSize ) ); - } - if ( image2DHeader.sphericalRepresentation.imageMaskSize > 0 ) - { - sphericalRepresentation.set( "imageMask", - BlobNode( imf_, image2DHeader.sphericalRepresentation.imageMaskSize ) ); - } - - sphericalRepresentation.set( "imageHeight", - IntegerNode( imf_, image2DHeader.sphericalRepresentation.imageHeight ) ); - sphericalRepresentation.set( "imageWidth", - IntegerNode( imf_, image2DHeader.sphericalRepresentation.imageWidth ) ); - sphericalRepresentation.set( "pixelHeight", - FloatNode( imf_, image2DHeader.sphericalRepresentation.pixelHeight ) ); - sphericalRepresentation.set( "pixelWidth", - FloatNode( imf_, image2DHeader.sphericalRepresentation.pixelWidth ) ); - } - else if ( image2DHeader.cylindricalRepresentation.jpegImageSize > 0 || - image2DHeader.cylindricalRepresentation.pngImageSize > 0 ) - { - StructureNode cylindricalRepresentation = StructureNode( imf_ ); - image.set( "cylindricalRepresentation", cylindricalRepresentation ); - - if ( image2DHeader.cylindricalRepresentation.jpegImageSize > 0 ) - { - cylindricalRepresentation.set( "jpegImage", - BlobNode( imf_, image2DHeader.cylindricalRepresentation.jpegImageSize ) ); - } - else if ( image2DHeader.cylindricalRepresentation.pngImageSize > 0 ) - { - cylindricalRepresentation.set( "pngImage", - BlobNode( imf_, image2DHeader.cylindricalRepresentation.pngImageSize ) ); - } - if ( image2DHeader.cylindricalRepresentation.imageMaskSize > 0 ) - { - cylindricalRepresentation.set( "imageMask", - BlobNode( imf_, image2DHeader.cylindricalRepresentation.imageMaskSize ) ); - } - - cylindricalRepresentation.set( "imageHeight", - IntegerNode( imf_, image2DHeader.cylindricalRepresentation.imageHeight ) ); - cylindricalRepresentation.set( "imageWidth", - IntegerNode( imf_, image2DHeader.cylindricalRepresentation.imageWidth ) ); - cylindricalRepresentation.set( "pixelHeight", - FloatNode( imf_, image2DHeader.cylindricalRepresentation.pixelHeight ) ); - cylindricalRepresentation.set( "pixelWidth", - FloatNode( imf_, image2DHeader.cylindricalRepresentation.pixelWidth ) ); - cylindricalRepresentation.set( "principalPointY", - FloatNode( imf_, image2DHeader.cylindricalRepresentation.principalPointY ) ); - cylindricalRepresentation.set( "radius", FloatNode( imf_, image2DHeader.cylindricalRepresentation.radius ) ); - } - return pos; - } - - // This function reads one of the image blobs - int64_t WriterImpl::WriteImage2DNode( StructureNode image, Image2DType imageType, void *pBuffer, int64_t start, - int64_t count ) - { - int64_t transferred = 0; - switch ( imageType ) - { - case E57_NO_IMAGE: - { - return 0; - } - case E57_JPEG_IMAGE: - { - if ( image.isDefined( "jpegImage" ) ) - { - BlobNode jpegImage( image.get( "jpegImage" ) ); - jpegImage.write( (uint8_t *)pBuffer, start, (size_t)count ); - transferred = count; - } - break; - } - case E57_PNG_IMAGE: - { - if ( image.isDefined( "pngImage" ) ) - { - BlobNode pngImage( image.get( "pngImage" ) ); - pngImage.write( (uint8_t *)pBuffer, start, (size_t)count ); - transferred = count; - } - break; - } - case E57_PNG_IMAGE_MASK: - { - if ( image.isDefined( "imageMask" ) ) - { - BlobNode imageMask( image.get( "imageMask" ) ); - imageMask.write( (uint8_t *)pBuffer, start, (size_t)count ); - transferred = count; - } - break; - } - } - return transferred; - } - - int64_t WriterImpl::WriteImage2DData( int64_t imageIndex, Image2DType imageType, Image2DProjection imageProjection, - void *pBuffer, int64_t start, int64_t count ) - { - if ( ( imageIndex < 0 ) || ( imageIndex >= images2D_.childCount() ) ) - { - return 0; - } - - int64_t transferred = 0; - StructureNode image( images2D_.get( imageIndex ) ); - - switch ( imageProjection ) - { - case E57_NO_PROJECTION: - return 0; - case E57_VISUAL: - if ( image.isDefined( "visualReferenceRepresentation" ) ) - { - StructureNode visualReferenceRepresentation( image.get( "visualReferenceRepresentation" ) ); - transferred = WriteImage2DNode( visualReferenceRepresentation, imageType, pBuffer, start, count ); - } - break; - case E57_PINHOLE: - if ( image.isDefined( "pinholeRepresentation" ) ) - { - StructureNode pinholeRepresentation( image.get( "pinholeRepresentation" ) ); - transferred = WriteImage2DNode( pinholeRepresentation, imageType, pBuffer, start, count ); - } - break; - case E57_SPHERICAL: - if ( image.isDefined( "sphericalRepresentation" ) ) - { - StructureNode sphericalRepresentation( image.get( "sphericalRepresentation" ) ); - transferred = WriteImage2DNode( sphericalRepresentation, imageType, pBuffer, start, count ); - } - break; - case E57_CYLINDRICAL: - if ( image.isDefined( "cylindricalRepresentation" ) ) - { - StructureNode cylindricalRepresentation( image.get( "cylindricalRepresentation" ) ); - transferred = WriteImage2DNode( cylindricalRepresentation, imageType, pBuffer, start, count ); - } - break; - } - return transferred; - } - - int64_t WriterImpl::NewData3D( Data3D &data3DHeader ) - { - int64_t pos = -1; - - if ( data3DHeader.guid.empty() ) - { - data3DHeader.guid = generateRandomGUID(); - } - - StructureNode scan = StructureNode( imf_ ); - data3D_.append( scan ); - pos = data3D_.childCount() - 1; - - scan.set( "guid", StringNode( imf_, data3DHeader.guid ) ); // required - - if ( !data3DHeader.name.empty() ) - { - scan.set( "name", StringNode( imf_, data3DHeader.name ) ); - } - - if ( !data3DHeader.description.empty() ) - { - scan.set( "description", StringNode( imf_, data3DHeader.description ) ); - } - - if ( data3DHeader.originalGuids.size() > 0 ) - { - scan.set( "originalGuids", VectorNode( imf_ ) ); - VectorNode originalGuids( scan.get( "originalGuids" ) ); - int i; - for ( i = 0; i < (int)data3DHeader.originalGuids.size(); i++ ) - { - originalGuids.append( StringNode( imf_, data3DHeader.originalGuids[i] ) ); - } - } - - // Add various sensor and version strings to scan. - // Path names: "/data3D/0/sensorVendor", etc... - if ( !data3DHeader.sensorVendor.empty() ) - { - scan.set( "sensorVendor", StringNode( imf_, data3DHeader.sensorVendor ) ); - } - if ( !data3DHeader.sensorModel.empty() ) - { - scan.set( "sensorModel", StringNode( imf_, data3DHeader.sensorModel ) ); - } - if ( !data3DHeader.sensorSerialNumber.empty() ) - { - scan.set( "sensorSerialNumber", StringNode( imf_, data3DHeader.sensorSerialNumber ) ); - } - if ( !data3DHeader.sensorHardwareVersion.empty() ) - { - scan.set( "sensorHardwareVersion", StringNode( imf_, data3DHeader.sensorHardwareVersion ) ); - } - if ( !data3DHeader.sensorSoftwareVersion.empty() ) - { - scan.set( "sensorSoftwareVersion", StringNode( imf_, data3DHeader.sensorSoftwareVersion ) ); - } - if ( !data3DHeader.sensorFirmwareVersion.empty() ) - { - scan.set( "sensorFirmwareVersion", StringNode( imf_, data3DHeader.sensorFirmwareVersion ) ); - } - - // Add temp/humidity to scan. - // Path names: "/data3D/0/temperature", etc... - if ( data3DHeader.temperature != E57_FLOAT_MAX ) - { - scan.set( "temperature", FloatNode( imf_, data3DHeader.temperature ) ); - } - - if ( data3DHeader.relativeHumidity != E57_FLOAT_MAX ) - { - scan.set( "relativeHumidity", FloatNode( imf_, data3DHeader.relativeHumidity ) ); - } - - if ( data3DHeader.atmosphericPressure != E57_FLOAT_MAX ) - { - scan.set( "atmosphericPressure", FloatNode( imf_, data3DHeader.atmosphericPressure ) ); - } - - if ( data3DHeader.indexBounds != IndexBounds{} ) - { - StructureNode ibox = StructureNode( imf_ ); - - if ( ( data3DHeader.indexBounds.rowMinimum != 0 ) || ( data3DHeader.indexBounds.rowMaximum != 0 ) ) - { - ibox.set( "rowMinimum", IntegerNode( imf_, data3DHeader.indexBounds.rowMinimum ) ); - ibox.set( "rowMaximum", IntegerNode( imf_, data3DHeader.indexBounds.rowMaximum ) ); - } - if ( ( data3DHeader.indexBounds.columnMinimum != 0 ) || ( data3DHeader.indexBounds.columnMaximum != 0 ) ) - { - ibox.set( "columnMinimum", IntegerNode( imf_, data3DHeader.indexBounds.columnMinimum ) ); - ibox.set( "columnMaximum", IntegerNode( imf_, data3DHeader.indexBounds.columnMaximum ) ); - } - if ( ( data3DHeader.indexBounds.returnMinimum != 0 ) || ( data3DHeader.indexBounds.returnMaximum != 0 ) ) - { - ibox.set( "returnMinimum", IntegerNode( imf_, data3DHeader.indexBounds.returnMinimum ) ); - ibox.set( "returnMaximum", IntegerNode( imf_, data3DHeader.indexBounds.returnMaximum ) ); - } - scan.set( "indexBounds", ibox ); - } - - if ( ( data3DHeader.intensityLimits.intensityMaximum != 0. ) || - ( data3DHeader.intensityLimits.intensityMinimum != 0. ) ) - { - StructureNode intbox = StructureNode( imf_ ); - if ( data3DHeader.pointFields.intensityScaledInteger > 0. ) - { - double offset = 0.; - double scale = data3DHeader.pointFields.intensityScaledInteger; - - int64_t rawIntegerMinimum = - (int64_t)floor( ( data3DHeader.intensityLimits.intensityMinimum - offset ) / scale + .5 ); - int64_t rawIntegerMaximum = - (int64_t)floor( ( data3DHeader.intensityLimits.intensityMaximum - offset ) / scale + .5 ); - - intbox.set( "intensityMaximum", ScaledIntegerNode( imf_, rawIntegerMaximum, rawIntegerMinimum, - rawIntegerMaximum, scale, offset ) ); - - intbox.set( "intensityMinimum", ScaledIntegerNode( imf_, rawIntegerMinimum, rawIntegerMinimum, - rawIntegerMaximum, scale, offset ) ); - } - else if ( data3DHeader.pointFields.intensityScaledInteger == 0. ) - { - intbox.set( "intensityMaximum", FloatNode( imf_, data3DHeader.intensityLimits.intensityMaximum ) ); - intbox.set( "intensityMinimum", FloatNode( imf_, data3DHeader.intensityLimits.intensityMinimum ) ); - } - else - { - intbox.set( "intensityMaximum", - IntegerNode( imf_, (int64_t)data3DHeader.intensityLimits.intensityMaximum ) ); - intbox.set( "intensityMinimum", - IntegerNode( imf_, (int64_t)data3DHeader.intensityLimits.intensityMinimum ) ); - } - scan.set( "intensityLimits", intbox ); - } - - if ( ( data3DHeader.colorLimits.colorRedMaximum != 0. ) || ( data3DHeader.colorLimits.colorRedMinimum != 0. ) ) - { - StructureNode colorbox = StructureNode( imf_ ); - colorbox.set( "colorRedMaximum", IntegerNode( imf_, (int64_t)data3DHeader.colorLimits.colorRedMaximum ) ); - colorbox.set( "colorRedMinimum", IntegerNode( imf_, (int64_t)data3DHeader.colorLimits.colorRedMinimum ) ); - colorbox.set( "colorGreenMaximum", IntegerNode( imf_, (int64_t)data3DHeader.colorLimits.colorGreenMaximum ) ); - colorbox.set( "colorGreenMinimum", IntegerNode( imf_, (int64_t)data3DHeader.colorLimits.colorGreenMinimum ) ); - colorbox.set( "colorBlueMaximum", IntegerNode( imf_, (int64_t)data3DHeader.colorLimits.colorBlueMaximum ) ); - colorbox.set( "colorBlueMinimum", IntegerNode( imf_, (int64_t)data3DHeader.colorLimits.colorBlueMinimum ) ); - scan.set( "colorLimits", colorbox ); - } - - // Add Cartesian bounding box to scan. - // Path names: "/data3D/0/cartesianBounds/xMinimum", etc... - if ( ( data3DHeader.cartesianBounds.xMinimum != -E57_DOUBLE_MAX ) || - ( data3DHeader.cartesianBounds.xMaximum != E57_DOUBLE_MAX ) ) - { - StructureNode bbox = StructureNode( imf_ ); - bbox.set( "xMinimum", FloatNode( imf_, data3DHeader.cartesianBounds.xMinimum ) ); - bbox.set( "xMaximum", FloatNode( imf_, data3DHeader.cartesianBounds.xMaximum ) ); - bbox.set( "yMinimum", FloatNode( imf_, data3DHeader.cartesianBounds.yMinimum ) ); - bbox.set( "yMaximum", FloatNode( imf_, data3DHeader.cartesianBounds.yMaximum ) ); - bbox.set( "zMinimum", FloatNode( imf_, data3DHeader.cartesianBounds.zMinimum ) ); - bbox.set( "zMaximum", FloatNode( imf_, data3DHeader.cartesianBounds.zMaximum ) ); - scan.set( "cartesianBounds", bbox ); - } - - if ( ( data3DHeader.sphericalBounds.rangeMinimum != 0. ) || - ( data3DHeader.sphericalBounds.rangeMaximum != E57_DOUBLE_MAX ) ) - { - StructureNode sbox = StructureNode( imf_ ); - sbox.set( "rangeMinimum", FloatNode( imf_, data3DHeader.sphericalBounds.rangeMinimum ) ); - sbox.set( "rangeMaximum", FloatNode( imf_, data3DHeader.sphericalBounds.rangeMaximum ) ); - sbox.set( "elevationMinimum", FloatNode( imf_, data3DHeader.sphericalBounds.elevationMinimum ) ); - sbox.set( "elevationMaximum", FloatNode( imf_, data3DHeader.sphericalBounds.elevationMaximum ) ); - sbox.set( "azimuthStart", FloatNode( imf_, data3DHeader.sphericalBounds.azimuthStart ) ); - sbox.set( "azimuthEnd", FloatNode( imf_, data3DHeader.sphericalBounds.azimuthEnd ) ); - scan.set( "sphericalBounds", sbox ); - } - - // Create pose structure for scan. - // Path names: "/data3D/0/pose/rotation/w", etc... - // "/data3D/0/pose/translation/x", etc... - if ( data3DHeader.pose != RigidBodyTransform{} ) - { - StructureNode pose = StructureNode( imf_ ); - scan.set( "pose", pose ); - - StructureNode rotation = StructureNode( imf_ ); - rotation.set( "w", FloatNode( imf_, data3DHeader.pose.rotation.w ) ); - rotation.set( "x", FloatNode( imf_, data3DHeader.pose.rotation.x ) ); - rotation.set( "y", FloatNode( imf_, data3DHeader.pose.rotation.y ) ); - rotation.set( "z", FloatNode( imf_, data3DHeader.pose.rotation.z ) ); - pose.set( "rotation", rotation ); - - StructureNode translation = StructureNode( imf_ ); - translation.set( "x", FloatNode( imf_, data3DHeader.pose.translation.x ) ); - translation.set( "y", FloatNode( imf_, data3DHeader.pose.translation.y ) ); - translation.set( "z", FloatNode( imf_, data3DHeader.pose.translation.z ) ); - pose.set( "translation", translation ); - } - - // Add start/stop acquisition times to scan. - // Path names: "/data3D/0/acquisitionStart/dateTimeValue", - // "/data3D/0/acquisitionEnd/dateTimeValue" - if ( data3DHeader.acquisitionStart.dateTimeValue > 0. ) - { - StructureNode acquisitionStart = StructureNode( imf_ ); - scan.set( "acquisitionStart", acquisitionStart ); - acquisitionStart.set( "dateTimeValue", FloatNode( imf_, data3DHeader.acquisitionStart.dateTimeValue ) ); - acquisitionStart.set( "isAtomicClockReferenced", - IntegerNode( imf_, data3DHeader.acquisitionStart.isAtomicClockReferenced ) ); - } - if ( data3DHeader.acquisitionEnd.dateTimeValue > 0. ) - { - StructureNode acquisitionEnd = StructureNode( imf_ ); - scan.set( "acquisitionEnd", acquisitionEnd ); - acquisitionEnd.set( "dateTimeValue", FloatNode( imf_, data3DHeader.acquisitionEnd.dateTimeValue ) ); - acquisitionEnd.set( "isAtomicClockReferenced", - IntegerNode( imf_, data3DHeader.acquisitionEnd.isAtomicClockReferenced ) ); - } - - // Add grouping scheme area - // Path name: "/data3D/0/pointGroupingSchemes" - if ( !data3DHeader.pointGroupingSchemes.groupingByLine.idElementName.empty() ) - { - StructureNode pointGroupingSchemes = StructureNode( imf_ ); - scan.set( "pointGroupingSchemes", pointGroupingSchemes ); - - // Add a line grouping scheme - // Path name: "/data3D/0/pointGroupingSchemes/groupingByLine" - StructureNode groupingByLine = StructureNode( imf_ ); - pointGroupingSchemes.set( "groupingByLine", groupingByLine ); - - // data3DHeader.pointGroupingSchemes.groupingByLine.idElementName)); - bool byColumn = true; // default should be "columnIndex" - if ( data3DHeader.pointGroupingSchemes.groupingByLine.idElementName.compare( "rowIndex" ) == 0 ) - { - byColumn = false; - } - - // Add idElementName to groupingByLine, specify a line is column or row oriented - // Path name: "/data3D/0/pointGroupingSchemes/groupingByLine/idElementName" - if ( byColumn ) - { - groupingByLine.set( "idElementName", StringNode( imf_, "columnIndex" ) ); - } - else - { - groupingByLine.set( "idElementName", StringNode( imf_, "rowIndex" ) ); - } - - // Make a prototype of datatypes that will be stored in LineGroupRecord. - // This prototype will be used in creating the groups CompressedVector. - // Will define path names like: - // "/data3D/0/pointGroupingSchemes/groupingByLine/groups/0/idElementValue" - int64_t groupsSize = data3DHeader.pointGroupingSchemes.groupingByLine.groupsSize; - int64_t countSize = data3DHeader.pointGroupingSchemes.groupingByLine.pointCountSize; - int64_t pointsSize = data3DHeader.pointsSize; - - StructureNode lineGroupProto = StructureNode( imf_ ); - lineGroupProto.set( "startPointIndex", IntegerNode( imf_, 0, 0, pointsSize - 1 ) ); - lineGroupProto.set( "idElementValue", IntegerNode( imf_, 0, 0, groupsSize - 1 ) ); - lineGroupProto.set( "pointCount", IntegerNode( imf_, 0, 0, countSize ) ); - - // Not supported in this Simple API for now - /* - StructureNode bbox = StructureNode(imf_); - bbox.set("xMinimum", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.pointRangeMinimum, data3DHeader.pointFields.pointRangeMaximum)); - bbox.set("xMaximum", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.pointRangeMinimum, data3DHeader.pointFields.pointRangeMaximum)); - bbox.set("yMinimum", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.pointRangeMinimum, data3DHeader.pointFields.pointRangeMaximum)); - bbox.set("yMaximum", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.pointRangeMinimum, data3DHeader.pointFields.pointRangeMaximum)); - bbox.set("zMinimum", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.pointRangeMinimum, data3DHeader.pointFields.pointRangeMaximum)); - bbox.set("zMaximum", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.pointRangeMinimum, data3DHeader.pointFields.pointRangeMaximum)); - lineGroupProto.set("cartesianBounds", bbox); - - StructureNode sbox = StructureNode(imf_); - sbox.set("rangeMinimum", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.pointRangeMinimum, data3DHeader.pointFields.pointRangeMaximum)); - sbox.set("rangeMaximum", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.pointRangeMinimum, data3DHeader.pointFields.pointRangeMaximum)); - sbox.set("elevationMinimum", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.angleMinimum, data3DHeader.pointFields.angleMaximum)); - sbox.set("elevationMaximum", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.angleMinimum, data3DHeader.pointFields.angleMaximum)); - sbox.set("azimuthStart", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.angleMinimum, data3DHeader.pointFields.angleMaximum)); - sbox.set("azimuthEnd", FloatNode(imf_, 0., E57_SINGLE, - data3DHeader.pointFields.angleMinimum, data3DHeader.pointFields.angleMaximum)); - lineGroupProto.set("sphericalBounds", sbox); - */ - // Make empty codecs vector for use in creating groups CompressedVector. - // If this vector is empty, it is assumed that all fields will use the BitPack codec. - VectorNode lineGroupCodecs = VectorNode( imf_, true ); - - // Create CompressedVector for storing groups. - // Path Name: "/data3D/0/pointGroupingSchemes/groupingByLine/groups". - // We use the prototype and empty codecs tree from above. - // The CompressedVector will be filled by code below. - CompressedVectorNode groups = CompressedVectorNode( imf_, lineGroupProto, lineGroupCodecs ); - groupingByLine.set( "groups", groups ); - } - - // Make a prototype of datatypes that will be stored in points record. - // This prototype will be used in creating the points CompressedVector. - // Using this proto in a CompressedVector will define path names like: - // "/data3D/0/points/0/cartesianX" - StructureNode proto = StructureNode( imf_ ); - - // Because ScaledInteger min/max are the raw integer min/max, we must calculate them from the data min/max - const double pointRangeScale = data3DHeader.pointFields.pointRangeScaledInteger; - const double pointRangeOffset = 0.; - int64_t pointRangeMinimum = - (int64_t)floor( ( data3DHeader.pointFields.pointRangeMinimum - pointRangeOffset ) / pointRangeScale + .5 ); - int64_t pointRangeMaximum = - (int64_t)floor( ( data3DHeader.pointFields.pointRangeMaximum - pointRangeOffset ) / pointRangeScale + .5 ); - - const auto getPointProto = [=]() -> Node { - if ( pointRangeScale > E57_NOT_SCALED_USE_FLOAT ) - { - return ScaledIntegerNode( imf_, 0, pointRangeMinimum, pointRangeMaximum, pointRangeScale, - pointRangeOffset ); - } - else - { - return FloatNode( imf_, 0., ( pointRangeScale < E57_NOT_SCALED_USE_FLOAT ) ? E57_DOUBLE : E57_SINGLE, - data3DHeader.pointFields.pointRangeMinimum, data3DHeader.pointFields.pointRangeMaximum ); - } - }; - - if ( data3DHeader.pointFields.cartesianXField ) - { - proto.set( "cartesianX", getPointProto() ); - } - if ( data3DHeader.pointFields.cartesianYField ) - { - proto.set( "cartesianY", getPointProto() ); - } - - if ( data3DHeader.pointFields.cartesianZField ) - { - proto.set( "cartesianZ", getPointProto() ); - } - - if ( data3DHeader.pointFields.sphericalRangeField ) - { - proto.set( "sphericalRange", getPointProto() ); - } - - const double angleScale = data3DHeader.pointFields.angleScaledInteger; - const double angleOffset = 0.; - int64_t angleMinimum = - (int64_t)std::floor( ( data3DHeader.pointFields.angleMinimum - angleOffset ) / angleScale + .5 ); - int64_t angleMaximum = - (int64_t)std::floor( ( data3DHeader.pointFields.angleMaximum - angleOffset ) / angleScale + .5 ); - - const auto getAngleProto = [=]() -> Node { - if ( angleScale > E57_NOT_SCALED_USE_FLOAT ) - { - return ScaledIntegerNode( imf_, 0, angleMinimum, angleMaximum, angleScale, angleOffset ); - } - else - { - return FloatNode( imf_, 0., ( angleScale < E57_NOT_SCALED_USE_FLOAT ) ? E57_DOUBLE : E57_SINGLE, - data3DHeader.pointFields.angleMinimum, data3DHeader.pointFields.angleMaximum ); - } - }; - - if ( data3DHeader.pointFields.sphericalAzimuthField ) - { - proto.set( "sphericalAzimuth", getAngleProto() ); - } - - if ( data3DHeader.pointFields.sphericalElevationField ) - { - proto.set( "sphericalElevation", getAngleProto() ); - } - - if ( data3DHeader.pointFields.intensityField ) - { - if ( data3DHeader.pointFields.intensityScaledInteger > 0. ) - { - double offset = 0; // could be data3DHeader.intensityLimits.intensityMinimum; - double scale = data3DHeader.pointFields.intensityScaledInteger; - int64_t rawIntegerMinimum = - (int64_t)floor( ( data3DHeader.intensityLimits.intensityMinimum - offset ) / scale + .5 ); - int64_t rawIntegerMaximum = - (int64_t)floor( ( data3DHeader.intensityLimits.intensityMaximum - offset ) / scale + .5 ); - proto.set( "intensity", ScaledIntegerNode( imf_, 0, rawIntegerMinimum, rawIntegerMaximum, scale, offset ) ); - } - else if ( data3DHeader.pointFields.intensityScaledInteger == E57_NOT_SCALED_USE_FLOAT ) - { - proto.set( "intensity", FloatNode( imf_, 0., E57_SINGLE, data3DHeader.intensityLimits.intensityMinimum, - data3DHeader.intensityLimits.intensityMaximum ) ); - } - else - { - proto.set( "intensity", IntegerNode( imf_, 0, (int64_t)data3DHeader.intensityLimits.intensityMinimum, - (int64_t)data3DHeader.intensityLimits.intensityMaximum ) ); - } - } - - if ( data3DHeader.pointFields.colorRedField ) - { - proto.set( "colorRed", IntegerNode( imf_, 0, (int64_t)data3DHeader.colorLimits.colorRedMinimum, - (int64_t)data3DHeader.colorLimits.colorRedMaximum ) ); - } - if ( data3DHeader.pointFields.colorGreenField ) - { - proto.set( "colorGreen", IntegerNode( imf_, 0, (int64_t)data3DHeader.colorLimits.colorGreenMinimum, - (int64_t)data3DHeader.colorLimits.colorGreenMaximum ) ); - } - if ( data3DHeader.pointFields.colorBlueField ) - { - proto.set( "colorBlue", IntegerNode( imf_, 0, (int64_t)data3DHeader.colorLimits.colorBlueMinimum, - (int64_t)data3DHeader.colorLimits.colorBlueMaximum ) ); - } - - if ( data3DHeader.pointFields.returnIndexField ) - { - proto.set( "returnIndex", IntegerNode( imf_, 0, E57_UINT8_MIN, data3DHeader.pointFields.returnMaximum ) ); - } - if ( data3DHeader.pointFields.returnCountField ) - { - proto.set( "returnCount", IntegerNode( imf_, 0, E57_UINT8_MIN, data3DHeader.pointFields.returnMaximum ) ); - } - - if ( data3DHeader.pointFields.rowIndexField ) - { - proto.set( "rowIndex", IntegerNode( imf_, 0, E57_UINT32_MIN, data3DHeader.pointFields.rowIndexMaximum ) ); - } - if ( data3DHeader.pointFields.columnIndexField ) - { - proto.set( "columnIndex", - IntegerNode( imf_, 0, E57_UINT32_MIN, data3DHeader.pointFields.columnIndexMaximum ) ); - } - - if ( data3DHeader.pointFields.timeStampField ) - { - if ( data3DHeader.pointFields.timeScaledInteger > 0. ) - { - double offset = 0; - double scale = data3DHeader.pointFields.timeScaledInteger; - int64_t rawIntegerMinimum = - (int64_t)floor( ( data3DHeader.pointFields.timeMinimum - offset ) / scale + .5 ); - int64_t rawIntegerMaximum = - (int64_t)floor( ( data3DHeader.pointFields.timeMaximum - offset ) / scale + .5 ); - proto.set( "timeStamp", ScaledIntegerNode( imf_, 0, rawIntegerMinimum, rawIntegerMaximum, scale, offset ) ); - } - else if ( data3DHeader.pointFields.timeScaledInteger == E57_NOT_SCALED_USE_FLOAT ) - { - if ( data3DHeader.pointFields.timeMaximum == E57_FLOAT_MAX ) - { - proto.set( "timeStamp", FloatNode( imf_, 0., E57_SINGLE, E57_FLOAT_MIN, E57_FLOAT_MAX ) ); - } - else if ( data3DHeader.pointFields.timeMaximum == E57_DOUBLE_MAX ) - { - proto.set( "timeStamp", FloatNode( imf_, 0., E57_DOUBLE, E57_DOUBLE_MIN, E57_DOUBLE_MAX ) ); - } - } - else - { - proto.set( "timeStamp", IntegerNode( imf_, 0, (int64_t)data3DHeader.pointFields.timeMinimum, - (int64_t)data3DHeader.pointFields.timeMaximum ) ); - } - } - - if ( data3DHeader.pointFields.cartesianInvalidStateField ) - { - proto.set( "cartesianInvalidState", IntegerNode( imf_, 0, 0, 2 ) ); - } - if ( data3DHeader.pointFields.sphericalInvalidStateField ) - { - proto.set( "sphericalInvalidState", IntegerNode( imf_, 0, 0, 2 ) ); - } - if ( data3DHeader.pointFields.isIntensityInvalidField ) - { - proto.set( "isIntensityInvalid", IntegerNode( imf_, 0, 0, 1 ) ); - } - if ( data3DHeader.pointFields.isColorInvalidField ) - { - proto.set( "isColorInvalid", IntegerNode( imf_, 0, 0, 1 ) ); - } - if ( data3DHeader.pointFields.isTimeStampInvalidField ) - { - proto.set( "isTimeStampInvalid", IntegerNode( imf_, 0, 0, 1 ) ); - } - - // E57_EXT_surface_normals - if ( data3DHeader.pointFields.normalX || data3DHeader.pointFields.normalY || data3DHeader.pointFields.normalZ ) - { - // make sure we declare the extension before using the fields with prefix - ustring norExtUri; - if ( !imf_.extensionsLookupPrefix( "nor", norExtUri ) ) - { - imf_.extensionsAdd( "nor", "http://www.libe57.org/E57_NOR_surface_normals.txt" ); - } - } - - // currently we support writing normals only as float32 - if ( data3DHeader.pointFields.normalX ) - { - proto.set( "nor:normalX", FloatNode( imf_, 0., E57_SINGLE, -1., 1. ) ); - } - if ( data3DHeader.pointFields.normalY ) - { - proto.set( "nor:normalY", FloatNode( imf_, 0., E57_SINGLE, -1., 1. ) ); - } - if ( data3DHeader.pointFields.normalZ ) - { - proto.set( "nor:normalZ", FloatNode( imf_, 0., E57_SINGLE, -1., 1. ) ); - } - - // Make empty codecs vector for use in creating points CompressedVector. - // If this vector is empty, it is assumed that all fields will use the BitPack codec. - VectorNode codecs = VectorNode( imf_, true ); - - // Create CompressedVector for storing points. Path Name: "/data3D/0/points". - // We use the prototype and empty codecs tree from above. - // The CompressedVector will be filled by code below. - CompressedVectorNode points = CompressedVectorNode( imf_, proto, codecs ); - scan.set( "points", points ); - return pos; - } - - template - CompressedVectorWriter WriterImpl::SetUpData3DPointsData( int64_t dataIndex, size_t count, - const Data3DPointsData_t &buffers ) - { - StructureNode scan( data3D_.get( dataIndex ) ); - CompressedVectorNode points( scan.get( "points" ) ); - StructureNode proto( points.prototype() ); - - std::vector sourceBuffers; - if ( proto.isDefined( "cartesianX" ) && buffers.cartesianX ) - { - sourceBuffers.emplace_back( imf_, "cartesianX", buffers.cartesianX, count, true, true ); - } - if ( proto.isDefined( "cartesianY" ) && buffers.cartesianY ) - { - sourceBuffers.emplace_back( imf_, "cartesianY", buffers.cartesianY, count, true, true ); - } - if ( proto.isDefined( "cartesianZ" ) && buffers.cartesianZ ) - { - sourceBuffers.emplace_back( imf_, "cartesianZ", buffers.cartesianZ, count, true, true ); - } - - if ( proto.isDefined( "sphericalRange" ) && buffers.sphericalRange ) - { - sourceBuffers.emplace_back( imf_, "sphericalRange", buffers.sphericalRange, count, true, true ); - } - if ( proto.isDefined( "sphericalAzimuth" ) && buffers.sphericalAzimuth ) - { - sourceBuffers.emplace_back( imf_, "sphericalAzimuth", buffers.sphericalAzimuth, count, true, true ); - } - if ( proto.isDefined( "sphericalElevation" ) && buffers.sphericalElevation ) - { - sourceBuffers.emplace_back( imf_, "sphericalElevation", buffers.sphericalElevation, count, true, true ); - } - - if ( proto.isDefined( "intensity" ) && buffers.intensity ) - { - sourceBuffers.emplace_back( imf_, "intensity", buffers.intensity, count, true, true ); - } - - if ( proto.isDefined( "colorRed" ) && buffers.colorRed ) - { - sourceBuffers.emplace_back( imf_, "colorRed", buffers.colorRed, count, true ); - } - if ( proto.isDefined( "colorGreen" ) && buffers.colorGreen ) - { - sourceBuffers.emplace_back( imf_, "colorGreen", buffers.colorGreen, count, true ); - } - if ( proto.isDefined( "colorBlue" ) && buffers.colorBlue ) - { - sourceBuffers.emplace_back( imf_, "colorBlue", buffers.colorBlue, count, true ); - } - - if ( proto.isDefined( "returnIndex" ) && buffers.returnIndex ) - { - sourceBuffers.emplace_back( imf_, "returnIndex", buffers.returnIndex, count, true ); - } - if ( proto.isDefined( "returnCount" ) && buffers.returnCount ) - { - sourceBuffers.emplace_back( imf_, "returnCount", buffers.returnCount, count, true ); - } - - if ( proto.isDefined( "rowIndex" ) && buffers.rowIndex ) - { - sourceBuffers.emplace_back( imf_, "rowIndex", buffers.rowIndex, count, true ); - } - if ( proto.isDefined( "columnIndex" ) && buffers.columnIndex ) - { - sourceBuffers.emplace_back( imf_, "columnIndex", buffers.columnIndex, count, true ); - } - - if ( proto.isDefined( "timeStamp" ) && buffers.timeStamp ) - { - sourceBuffers.emplace_back( imf_, "timeStamp", buffers.timeStamp, count, true, true ); - } - - if ( proto.isDefined( "cartesianInvalidState" ) && buffers.cartesianInvalidState ) - { - sourceBuffers.emplace_back( imf_, "cartesianInvalidState", buffers.cartesianInvalidState, count, true ); - } - if ( proto.isDefined( "sphericalInvalidState" ) && buffers.sphericalInvalidState ) - { - sourceBuffers.emplace_back( imf_, "sphericalInvalidState", buffers.sphericalInvalidState, count, true ); - } - if ( proto.isDefined( "isIntensityInvalid" ) && buffers.isIntensityInvalid ) - { - sourceBuffers.emplace_back( imf_, "isIntensityInvalid", buffers.isIntensityInvalid, count, true ); - } - if ( proto.isDefined( "isColorInvalid" ) && buffers.isColorInvalid ) - { - sourceBuffers.emplace_back( imf_, "isColorInvalid", buffers.isColorInvalid, count, true ); - } - if ( proto.isDefined( "isTimeStampInvalid" ) && buffers.isTimeStampInvalid ) - { - sourceBuffers.emplace_back( imf_, "isTimeStampInvalid", buffers.isTimeStampInvalid, count, true ); - } - - // E57_EXT_surface_normals - ustring norExtUri; - if ( imf_.extensionsLookupPrefix( "nor", norExtUri ) ) - { - if ( proto.isDefined( "nor:normalX" ) && buffers.normalX ) - { - sourceBuffers.emplace_back( imf_, "nor:normalX", buffers.normalX, count, true, true ); - } - if ( proto.isDefined( "nor:normalY" ) && buffers.normalY ) - { - sourceBuffers.emplace_back( imf_, "nor:normalY", buffers.normalY, count, true, true ); - } - if ( proto.isDefined( "nor:normalZ" ) && buffers.normalZ ) - { - sourceBuffers.emplace_back( imf_, "nor:normalZ", buffers.normalZ, count, true, true ); - } - } - - // create the writer, all buffers must be setup before this call - CompressedVectorWriter writer = points.writer( sourceBuffers ); - - return writer; - } - - // Explicit template instantiation - template CompressedVectorWriter WriterImpl::SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData_t &buffers ); - - template CompressedVectorWriter WriterImpl::SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData_t &buffers ); - - // This function writes out the group data - bool WriterImpl::WriteData3DGroupsData( int64_t dataIndex, int64_t groupCount, int64_t *idElementValue, - int64_t *startPointIndex, int64_t *pointCount ) - { - if ( ( dataIndex < 0 ) || ( dataIndex >= data3D_.childCount() ) ) - { - return false; - } - - StructureNode scan( data3D_.get( dataIndex ) ); - - if ( !scan.isDefined( "pointGroupingSchemes" ) ) - { - return false; - } - StructureNode pointGroupingSchemes( scan.get( "pointGroupingSchemes" ) ); - - if ( !pointGroupingSchemes.isDefined( "groupingByLine" ) ) - { - return false; - } - StructureNode groupingByLine( pointGroupingSchemes.get( "groupingByLine" ) ); - - if ( !groupingByLine.isDefined( "groups" ) ) - { - return false; - } - CompressedVectorNode groups( groupingByLine.get( "groups" ) ); - - std::vector groupSDBuffers; - groupSDBuffers.emplace_back( imf_, "idElementValue", idElementValue, groupCount, true ); - groupSDBuffers.emplace_back( imf_, "startPointIndex", startPointIndex, groupCount, true ); - groupSDBuffers.emplace_back( imf_, "pointCount", pointCount, groupCount, true ); - - CompressedVectorWriter writer = groups.writer( groupSDBuffers ); - writer.write( groupCount ); - writer.close(); - - return true; - } - -} // end namespace e57 diff --git a/src/3rdParty/libE57Format/src/WriterImpl.h b/src/3rdParty/libE57Format/src/WriterImpl.h deleted file mode 100644 index b0e7d92ace..0000000000 --- a/src/3rdParty/libE57Format/src/WriterImpl.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2010 Stan Coleby (scoleby@intelisum.com) - * Copyright (c) 2020 PTC Inc. - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once - -#include "E57SimpleData.h" - -namespace e57 -{ - - //! most of the functions follows Writer - class WriterImpl - { - public: - WriterImpl( const ustring &filePath, const ustring &coordinateMetaData ); - - ~WriterImpl(); - - bool IsOpen() const; - - bool Close(); - - int64_t NewImage2D( Image2D &image2DHeader ); - - int64_t WriteImage2DData( int64_t imageIndex, Image2DType imageType, Image2DProjection imageProjection, - void *pBuffer, int64_t start, int64_t count ); - - int64_t NewData3D( Data3D &data3DHeader ); - - template - CompressedVectorWriter SetUpData3DPointsData( int64_t dataIndex, size_t pointCount, - const Data3DPointsData_t &buffers ); - - bool WriteData3DGroupsData( int64_t dataIndex, int64_t groupCount, int64_t *idElementValue, - int64_t *startPointIndex, int64_t *pointCount ); - - StructureNode GetRawE57Root(); - - VectorNode GetRawData3D(); - - VectorNode GetRawImages2D(); - - ImageFile GetRawIMF(); - - private: - ImageFile imf_; - StructureNode root_; - - VectorNode data3D_; - - VectorNode images2D_; - - //! @brief This function writes the projection image - //! @param image 1 of 3 projects or the visual - //! @param imageType identifies the image format desired. - //! @param pBuffer pointer the buffer - //! @param start position in the block to start reading - //! @param count size of desired chuck or buffer size - int64_t WriteImage2DNode( StructureNode image, Image2DType imageType, void *pBuffer, int64_t start, - int64_t count ); - }; // end Writer class - -} // end namespace e57