├── .appveyor.yml ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── ion-test-driver-issue.md └── workflows │ ├── codeql-analysis.yml │ ├── ion-test-driver.yml │ ├── main.yml │ └── performance-regression.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Doxyfile ├── LICENSE ├── NOTICE ├── README.md ├── build-debug.sh ├── build-release.sh ├── build_version.h.in ├── cmake ├── CMakeCPack.cmake ├── IonCConfig.cmake.in ├── VersionHeader.cmake └── cmake_uninstall.cmake.in ├── debug-tests.sh ├── decNumber ├── CMakeLists.txt ├── ICU-license.html ├── decBasic.c ├── decCommon.c ├── decContext.c ├── decDouble.c ├── decNumber.c ├── decPacked.c ├── decQuad.c ├── decSingle.c ├── decimal128.c ├── decimal32.c ├── decimal64.c ├── decnumber.pdf ├── example1.c ├── example2.c ├── example3.c ├── example4.c ├── example5.c ├── example6.c ├── example7.c ├── example8.c ├── include │ └── decNumber │ │ ├── decContext.h │ │ ├── decDPD.h │ │ ├── decDouble.h │ │ ├── decNumber.h │ │ ├── decNumberLocal.h │ │ ├── decPacked.h │ │ ├── decQuad.h │ │ ├── decSingle.h │ │ ├── decimal128.h │ │ ├── decimal32.h │ │ └── decimal64.h └── readme.txt ├── ionc ├── CMakeLists.txt ├── decQuadHelpers.c ├── decQuadHelpers.h ├── include │ └── ionc │ │ ├── ion.h │ │ ├── ion_catalog.h │ │ ├── ion_collection.h │ │ ├── ion_debug.h │ │ ├── ion_decimal.h │ │ ├── ion_error_codes.h │ │ ├── ion_errors.h │ │ ├── ion_extractor.h │ │ ├── ion_float.h │ │ ├── ion_int.h │ │ ├── ion_platform_config.h │ │ ├── ion_reader.h │ │ ├── ion_stream.h │ │ ├── ion_string.h │ │ ├── ion_symbol_table.h │ │ ├── ion_timestamp.h │ │ ├── ion_types.h │ │ ├── ion_version.h │ │ └── ion_writer.h ├── ion_alloc.h ├── ion_allocation.c ├── ion_binary.c ├── ion_binary.h ├── ion_catalog.c ├── ion_catalog_impl.h ├── ion_collection.c ├── ion_collection_impl.h ├── ion_const.h ├── ion_debug.c ├── ion_decimal.c ├── ion_decimal_impl.h ├── ion_errors.c ├── ion_extractor.c ├── ion_extractor_impl.h ├── ion_float.c ├── ion_helpers.c ├── ion_helpers.h ├── ion_index.c ├── ion_index.h ├── ion_initialize.c ├── ion_int.c ├── ion_internal.h ├── ion_reader.c ├── ion_reader_binary.c ├── ion_reader_impl.h ├── ion_reader_text.c ├── ion_reader_text.h ├── ion_scanner.c ├── ion_scanner.h ├── ion_stream.c ├── ion_stream_impl.h ├── ion_string.c ├── ion_sub_type_records.h ├── ion_symbol_table.c ├── ion_symbol_table_impl.h ├── ion_timestamp.c ├── ion_timestamp_impl.h ├── ion_version.c ├── ion_writer.c ├── ion_writer_binary.c ├── ion_writer_impl.h ├── ion_writer_text.c └── updated │ ├── ion_helpers.c │ └── ion_tokenizer.c ├── test ├── CMakeLists.txt ├── gather_vectors.cpp ├── gather_vectors.h ├── ion_assert.cpp ├── ion_assert.h ├── ion_test_util.cpp ├── ion_test_util.h ├── test_ion_binary.cpp ├── test_ion_cli.cpp ├── test_ion_decimal.cpp ├── test_ion_extractor.cpp ├── test_ion_integer.cpp ├── test_ion_reader_seek.cpp ├── test_ion_stream.cpp ├── test_ion_symbol.cpp ├── test_ion_text.cpp ├── test_ion_timestamp.cpp ├── test_ion_values.cpp ├── test_ion_writer.cpp └── test_vectors.cpp └── tools ├── CMakeLists.txt ├── cli ├── CMakeLists.txt ├── argtable │ ├── LICENSE │ ├── argtable3.c │ └── argtable3.h ├── cli.cpp ├── cli.h └── main.cpp ├── events ├── CMakeLists.txt ├── floating_point_util.h ├── inc │ ├── ion_event_equivalence.h │ └── ion_event_stream.h ├── ion_event_equivalence.cpp ├── ion_event_equivalence_impl.h ├── ion_event_stream.cpp ├── ion_event_stream_impl.h ├── ion_event_util.cpp └── ion_event_util.h ├── ion-bench ├── CMakeLists.txt └── src │ ├── CMakeLists.txt │ ├── benchmarks.h │ ├── cbor │ └── libcbor.h │ ├── common.cc │ ├── common.h │ ├── ion │ ├── CMakeLists.txt │ ├── common.h │ ├── ionc.h │ ├── reading.h │ ├── writing.cc │ └── writing.h │ ├── json │ ├── common.h │ ├── json-c.h │ └── yy.h │ ├── main.cpp │ ├── memory.c │ ├── memory.h │ └── msgpack │ └── msgpack.h ├── ionizer ├── CMakeLists.txt ├── ionizer.c ├── ionizer.h ├── ionizer_args.c ├── ionizer_stream.c ├── options.c └── options.h └── ionsymbols ├── CMakeLists.txt ├── ionsymbols.c ├── ionsymbols.h ├── ionsymbols_args.c ├── options.c └── options.h /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '1.0.{build}' 2 | 3 | image: Visual Studio 2017 4 | 5 | platform: 6 | - x64 7 | 8 | configuration: 9 | - Debug 10 | - Release 11 | 12 | install: 13 | - git submodule update --init --recursive 14 | 15 | build_script: 16 | - cmake -G "Visual Studio 15 2017 Win64" . 17 | - cmake --build %APPVEYOR_BUILD_FOLDER% --config %CONFIGURATION% 18 | 19 | test_script: 20 | - '%APPVEYOR_BUILD_FOLDER%\test\%CONFIGURATION%\all_tests.exe' 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Issue #, if available:* 2 | 3 | *Description of changes:* 4 | 5 | 6 | By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. 7 | -------------------------------------------------------------------------------- /.github/ion-test-driver-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ion-test-driver issue. 3 | labels: bug 4 | --- 5 | Ion-test-driver complained that behavior changed for the commit {{ env.GITHUB_PR_SHA }} created by `{{ payload.sender.login }}`. 6 | Refer to the [workflow]({{ env.GITHUB_WORKFLOW_URL }}) for more details. 7 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '20 11 * * 4' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'cpp' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | with: 43 | submodules: recursive 44 | fetch-tags: true 45 | fetch-depth: 50 46 | 47 | # Initializes the CodeQL tools for scanning. 48 | - name: Initialize CodeQL 49 | uses: github/codeql-action/init@v1 50 | with: 51 | languages: ${{ matrix.language }} 52 | # If you wish to specify custom queries, you can do so here or in a config file. 53 | # By default, queries listed here will override any specified in a config file. 54 | # Prefix the list here with "+" to use these queries and those in the config file. 55 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 56 | 57 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 58 | # If this step fails, then you should remove it and run the build manually (see below) 59 | # - name: Autobuild 60 | # uses: github/codeql-action/autobuild@v1 61 | 62 | # ℹ️ Command-line programs to run using the OS shell. 63 | # 📚 https://git.io/JvXDl 64 | 65 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 66 | # and modify them (or add more) to build your code if your project 67 | # uses a compiled language 68 | 69 | - name: Create git config 70 | run: git config --add safe.directory $GITHUB_WORKSPACE 71 | - name: Build 72 | run: ./build-release.sh 73 | 74 | - name: Perform CodeQL Analysis 75 | uses: github/codeql-action/analyze@v1 76 | -------------------------------------------------------------------------------- /.github/workflows/ion-test-driver.yml: -------------------------------------------------------------------------------- 1 | name: ion-test-driver 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | ion-test-driver: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout ion-c 10 | uses: actions/checkout@master 11 | with: 12 | repository: amazon-ion/ion-c 13 | ref: master 14 | path: ion-c 15 | 16 | - name: Checkout ion-test-driver 17 | uses: actions/checkout@master 18 | with: 19 | repository: amazon-ion/ion-test-driver 20 | ref: master 21 | path: ion-test-driver 22 | 23 | - name: Setup Python 24 | uses: actions/setup-python@v5 25 | with: 26 | python-version: '3.11' 27 | 28 | - name: Set up python3 env 29 | run: python3 -m venv ion-test-driver/venv && . ion-test-driver/venv/bin/activate 30 | 31 | - name: Pip install 32 | run: pip3 install -r ion-test-driver/requirements.txt && pip3 install -e ion-test-driver 33 | 34 | - name: Get main branch HEAD sha 35 | run: cd ion-c && echo `git rev-parse --short=7 HEAD` && echo "main=`git rev-parse --short=7 HEAD`" >> $GITHUB_ENV 36 | 37 | - name: Get current commit sha 38 | run: cd ion-c && echo `git rev-parse --short=7 ${{ github.event.pull_request.head.sha }}` 39 | && echo "cur=`git rev-parse --short=7 ${{ github.event.pull_request.head.sha }}`" >> $GITHUB_ENV 40 | 41 | - name: Run ion-test-driver 42 | run: python3 ion-test-driver/amazon/iontest/ion_test_driver.py -o output 43 | -i ion-c,${{ github.event.pull_request.head.repo.html_url }},${{ github.event.pull_request.head.sha }} 44 | -I https://github.com/amazon-ion/ion-tests.git,main 45 | --replace ion-c,https://github.com/amazon-ion/ion-c.git,$main 46 | 47 | - name: Upload result 48 | uses: actions/upload-artifact@v4 49 | with: 50 | name: ion-test-driver-result.ion 51 | path: output/results/ion-test-driver-results.ion 52 | 53 | - name: Showing result 54 | run: cat output/results/ion-test-driver-results.ion 55 | 56 | - name: Analyze two implementations 57 | continue-on-error: true 58 | id: result-diff 59 | run: python3 ion-test-driver/amazon/iontest/ion_test_driver.py -R 60 | ion-c,$main ion-c,$cur output/results/ion-test-driver-results.ion 61 | 62 | - name: Upload analysis report 63 | uses: actions/upload-artifact@v4 64 | with: 65 | name: analysis-report.ion 66 | path: result.ion 67 | 68 | - name: Showing report 69 | run: cat result.ion 70 | 71 | - name: Check if ion-test-driver fails 72 | if: ${{ steps.result-diff.outcome == 'failure' }} 73 | run: echo 'Implementation behavior changed, Refer to the analysis report in the previous step for the reason.' && exit 1 74 | 75 | open-issue: 76 | runs-on: ubuntu-latest 77 | needs: ion-test-driver 78 | if: ${{ failure() }} 79 | steps: 80 | - uses: actions/checkout@master 81 | - name: Open an issue 82 | uses: JasonEtco/create-an-issue@v2 83 | env: 84 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 85 | GITHUB_WORKFLOW_URL: https://github.com/${{github.repository}}/actions/runs/${{github.run_id}} 86 | GITHUB_PR_SHA: ${{ github.event.pull_request.head.sha }} 87 | with: 88 | assignees: ${{ github.event.sender.login }} 89 | filename: .github/ion-test-driver-issue.md 90 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ion-tests"] 2 | path = ion-tests 3 | url = https://github.com/amazon-ion/ion-tests.git 4 | [submodule "tools/ion-bench/deps/libcbor"] 5 | path = tools/ion-bench/deps/libcbor 6 | url = https://github.com/PJK/libcbor.git 7 | [submodule "tools/ion-bench/deps/json-c"] 8 | path = tools/ion-bench/deps/json-c 9 | url = https://github.com/json-c/json-c.git 10 | [submodule "tools/ion-bench/deps/msgpack-c"] 11 | path = tools/ion-bench/deps/msgpack-c 12 | url = https://github.com/msgpack/msgpack-c.git 13 | [submodule "tools/ion-bench/deps/yyjson"] 14 | path = tools/ion-bench/deps/yyjson 15 | url = https://github.com/ibireme/yyjson.git 16 | [submodule "tools/ion-bench/deps/google-benchmark"] 17 | path = tools/ion-bench/deps/google-benchmark 18 | url = https://github.com/google/benchmark.git 19 | [submodule "deps/google-test"] 20 | path = deps/google-test 21 | url = https://github.com/google/googletest.git 22 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.6 FATAL_ERROR) 2 | project(IonC 3 | VERSION 1.1.3 4 | LANGUAGES CXX C) 5 | 6 | # we default to 'Release' build type 7 | if(NOT CMAKE_BUILD_TYPE) 8 | set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) 9 | endif() 10 | message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}") 11 | 12 | if (MSVC) 13 | else() 14 | set(BUILD_SHARED_LIBS ON) 15 | add_compile_options("$<$:-O0;-g3;-ggdb3;-Wall>") 16 | endif() 17 | 18 | set(IONC_FORCE_SANITIZERS OFF CACHE BOOL "Force use of compiler sanitizers") 19 | set(IONC_ENABLE_VERBOSE_DEBUG OFF CACHE BOOL "Enable verbose logging for ion-c") 20 | 21 | ## Build Type Settings 22 | if (CMAKE_BUILD_TYPE STREQUAL "Release") 23 | add_compile_definitions(NDEBUG=1) 24 | elseif (CMAKE_BUILD_TYPE STREQUAL "Debug") 25 | include(CheckCXXCompilerFlag) 26 | # check_cxx_compiler_flag doesn't just check compiler flags, it also attempts to link the program, which 27 | # in this case, also requires sanitizer flags. So we have to abuse CMAKE_REQUIRED_LINK_OPTIONS since that's 28 | # the only lever we're given afaict. This does not work with cmake prior to 3.14. 29 | list(INSERT CMAKE_REQUIRED_LINK_OPTIONS 0 "-fsanitize=address,undefined") 30 | check_cxx_compiler_flag("-g -fsanitize=address,undefined -fno-omit-frame-pointer" UBISAN_OK) 31 | list(REMOVE_AT CMAKE_REQUIRED_LINK_OPTIONS 0) 32 | if (UBISAN_OK OR IONC_FORCE_SANITIZERS) 33 | add_compile_options( 34 | -fsanitize=address,undefined 35 | -fsanitize-recover=address 36 | ) 37 | add_link_options(-fsanitize=address,undefined -fsanitize-recover=address) 38 | endif() 39 | add_compile_options(-g -fno-omit-frame-pointer -fno-optimize-sibling-calls) 40 | if (IONC_ENABLE_VERBOSE_DEBUG) 41 | add_compile_definitions(DEBUG=1) 42 | endif() 43 | elseif (CMAKE_BUILD_TYPE STREQUAL "Profiling") 44 | add_compile_options( 45 | -O3 -march=native 46 | -fno-omit-frame-pointer 47 | -fno-optimize-sibling-calls 48 | -g 49 | ) 50 | add_compile_definitions(NDEBUG=1) 51 | set(IONC_BENCHMARKING_ENABLED ON CACHE BOOL "Enable Benchmarking") 52 | endif() 53 | 54 | ## ion-c Build Version 55 | set(IONC_FULL_VERSION "v${CMAKE_PROJECT_VERSION}-0-g000000") # Format cmake project version to match git describe output 56 | find_program(GIT_EXECUTABLE "git") 57 | add_custom_target( 58 | version 59 | ${CMAKE_COMMAND} -D SRC=${CMAKE_CURRENT_SOURCE_DIR}/build_version.h.in 60 | -D DST=${CMAKE_CURRENT_BINARY_DIR}/build_version.h 61 | -D GIT_EXECUTABLE=${GIT_EXECUTABLE} 62 | -D IONC_FULL_VERSION=${IONC_FULL_VERSION} 63 | -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/VersionHeader.cmake 64 | ) 65 | 66 | include(GNUInstallDirs) 67 | 68 | set(IONC_DECIMAL_NUM_DIGITS "34" CACHE STRING "Number of digits supported without added allocation") 69 | option(IONC_BUILD_TESTS "Enable or Disable building of ion-c tests" ON) 70 | 71 | # NOTE: DECNUMDIGITS must be set across all compilation units to at least DECQUAD_Pmax (34), so that the value is 72 | # guaranteed to be consistent between ionc and decNumber. This is required for conversions between decQuad and 73 | # decNumber. This is NOT the limit on decimal precision; ION_DECIMAL can handle arbitrarily large precision. 74 | add_definitions(-DDECNUMDIGITS=${IONC_DECIMAL_NUM_DIGITS}) 75 | message(STATUS "Setting DECNUMBER max digits to ${IONC_DECIMAL_NUM_DIGITS}") 76 | 77 | set(CMAKE_INSTALL_RPATH "$ORIGIN") 78 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 79 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 80 | 81 | export(PACKAGE IonC) 82 | 83 | include(cmake/CMakeCPack.cmake) 84 | 85 | ## Convenience target to build and install 86 | add_custom_target(release 87 | COMMENT "Build and install the library" 88 | COMMENT "Binary Dir : ${CMAKE_BINARY_DIR}" 89 | COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --target install 90 | USES_TERMINAL) 91 | 92 | #### 93 | ## Create cmake uninstall target 94 | #### 95 | 96 | # First, create the cmake script that will do the actual uninstall. 97 | 98 | configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" 99 | "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" @ONLY ) 100 | 101 | # Define an uninstall target that will run the above script. 102 | 103 | add_custom_target(uninstall 104 | COMMAND ${CMAKE_COMMAND} -P 105 | "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" ) 106 | 107 | 108 | add_subdirectory(decNumber) 109 | add_subdirectory(ionc) 110 | add_subdirectory(tools) 111 | if (IONC_BUILD_TESTS) 112 | if (NOT TARGET gtest_main) 113 | message("Using included google-test") 114 | # Prevent googletest from linking against different versions of the C Runtime Library on 115 | # Windows. 116 | set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) 117 | add_subdirectory(deps/google-test EXCLUDE_FROM_ALL) 118 | endif() 119 | add_subdirectory(test) 120 | endif() 121 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check [existing open](https://github.com/amazon-ion/ion-c/issues), or [recently closed](https://github.com/amazon-ion/ion-c/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels ((enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/amazon-ion/ion-c/labels/help%20wanted) issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](https://github.com/amazon-ion/ion-c/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Amazon Ion C 2 | Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Amazon Ion C 2 | A C implementation of the [Ion data notation](https://amazon-ion.github.io/ion-docs). 3 | 4 | [![Build Status](https://travis-ci.org/amazon-ion/ion-c.svg?branch=master)](https://travis-ci.org/amazon-ion/ion-c) 5 | [![Build status](https://ci.appveyor.com/api/projects/status/x6xfom3x3hs3y945/branch/master?svg=true)](https://ci.appveyor.com/project/tgregg/ion-c-3akm7/branch/master) 6 | 7 | 8 | ## Setup 9 | This repository contains a [git submodule](https://git-scm.com/docs/git-submodule) 10 | called `ion-tests`, which holds test data used by `ion-c`'s unit tests. 11 | 12 | The easiest way to clone the `ion-c` repository and initialize its `ion-tests` 13 | submodule is to run the following command. 14 | 15 | ``` 16 | $ git clone --recursive https://github.com/amazon-ion/ion-c.git ion-c 17 | ``` 18 | 19 | Alternatively, the submodule may be initialized independently from the clone 20 | by running the following commands. 21 | 22 | ``` 23 | $ git submodule init 24 | $ git submodule update 25 | ``` 26 | 27 | The submodule points to the tip of the branch of the `ion-tests` repository 28 | specified in `ion-c`'s `.gitmodules` file. 29 | 30 | ### Pulling in Upstream Changes 31 | To pull upstream changes into `ion-c`, start with a simple `git pull`. 32 | This will pull in any changes to `ion-c` itself (including any changes 33 | to its `.gitmodules` file), but not any changes to the `ion-tests` 34 | submodule. To make sure the submodule is up-to-date, use the following 35 | command. 36 | 37 | ``` 38 | $ git submodule update --remote 39 | ``` 40 | 41 | This will fetch and update the ion-tests submodule from the `ion-tests` branch 42 | currently specified in the `.gitmodules` file. 43 | 44 | For detailed walkthroughs of git submodule usage, see the 45 | [Git Tools documentation](https://git-scm.com/book/en/v2/Git-Tools-Submodules). 46 | 47 | ## Building the Library 48 | Use the provided scripts `build-release.sh` and `build-debug.sh`. Ensure that `cmake` is installed first. 49 | 50 | ### On macOS 51 | `cmake` can be installed using [Homebrew](https://brew.sh/): `brew install cmake` 52 | 53 | ## Using the Library 54 | A great way to get started is to use the [Ion cookbook](https://amazon-ion.github.io/ion-docs/guides/cookbook.html). 55 | -------------------------------------------------------------------------------- /build-debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -- 2 | 3 | set -x 4 | 5 | export LD="$CXX" 6 | 7 | if ! [ -x "$(command -v cmake)" ]; then 8 | echo 'Error: cmake is not installed.' >&2 9 | exit 1 10 | fi 11 | 12 | mkdir -p build/debug && cd build/debug 13 | cmake \ 14 | -DCMAKE_BUILD_TYPE=Debug \ 15 | ${CMAKE_FLAGS} \ 16 | ../.. 17 | make clean && make -j"$(nproc || sysctl -n hw.ncpu)" 18 | -------------------------------------------------------------------------------- /build-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -- 2 | 3 | set -x 4 | 5 | export LD="$CXX" 6 | 7 | mkdir -p build/release 8 | cd build/release 9 | 10 | if ! [ -x "$(command -v cmake)" ]; then 11 | echo 'Error: cmake is not installed.' >&2 12 | exit 1 13 | fi 14 | 15 | cmake \ 16 | -DCMAKE_BUILD_TYPE=Release \ 17 | ${CMAKE_FLAGS} \ 18 | ../.. 19 | 20 | make clean && make -j"$(nproc || sysctl -n hw.ncpu)" 21 | -------------------------------------------------------------------------------- /build_version.h.in: -------------------------------------------------------------------------------- 1 | #ifndef IONC_VERSION_H__ 2 | #define IONC_VERSION_H__ 3 | #define IONC_BUILD_VERSION "@IONC_VERSION@ (rev: @IONC_VERSION_HASH@)" 4 | #define IONC_VERSION "@IONC_VERSION@" 5 | #define IONC_VERSION_MAJOR @IONC_VERSION_MAJOR@ 6 | #define IONC_VERSION_MINOR @IONC_VERSION_MINOR@ 7 | #define IONC_VERSION_PATCH @IONC_VERSION_PATCH@ 8 | #define IONC_VERSION_HASH "@IONC_VERSION_HASH@" 9 | #endif /* IONC_VERSION_H__ */ 10 | -------------------------------------------------------------------------------- /cmake/CMakeCPack.cmake: -------------------------------------------------------------------------------- 1 | set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") 2 | set(CPACK_PACKAGE_VENDOR "The Ion Team") 3 | set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md") 4 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "message: Ion C library and tools") 5 | set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") 6 | 7 | set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/${PROJECT_NAME}") 8 | 9 | set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") 10 | set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}") 11 | set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") 12 | 13 | set(CPACK_SOURCE_IGNORE_FILES 14 | "${PROJECT_BINARY_DIR};/.idea;./.github;/.git/;.gitignore;.travis.yml;.appveyor.yml") 15 | set(CPACK_SOURCE_GENERATOR "ZIP;TGZ") 16 | set(CPACK_GENERATOR "ZIP;TGZ") 17 | 18 | if(UNIX) 19 | if(CMAKE_SYSTEM_NAME MATCHES Linux) 20 | list(APPEND CPACK_GENERATOR "DEB") 21 | set(CPACK_DEBIAN_PACKAGE_MAINTAINER "ion-team") 22 | set(CPACK_DEBIAN_PACKAGE_SECTION "devel") 23 | # set(CPACK_DEBIAN_PACKAGE_DEPENDS "uuid-dev") 24 | 25 | list(APPEND CPACK_GENERATOR "RPM") 26 | set(CPACK_RPM_PACKAGE_RELEASE "1") 27 | set(CPACK_RPM_PACKAGE_LICENSE "Apache") 28 | # set(CPACK_RPM_PACKAGE_REQUIRES "uuid-devel") 29 | endif() 30 | endif() 31 | 32 | message(STATUS "CPack generators: ${CPACK_GENERATOR}") 33 | 34 | include(CPack) 35 | -------------------------------------------------------------------------------- /cmake/IonCConfig.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | if(NOT TARGET IonC::ionc) 4 | include(${CMAKE_CURRENT_LIST_DIR}/IonCTargets.cmake) 5 | endif() 6 | -------------------------------------------------------------------------------- /cmake/VersionHeader.cmake: -------------------------------------------------------------------------------- 1 | if (GIT_EXECUTABLE) 2 | execute_process( 3 | COMMAND ${GIT_EXECUTABLE} describe --long --tags --dirty --match "v*" 4 | OUTPUT_VARIABLE GIT_DESCRIBE_OUTPUT 5 | RESULT_VARIABLE GIT_DESCRIBE_ERROR 6 | OUTPUT_STRIP_TRAILING_WHITESPACE 7 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} 8 | ) 9 | if (NOT GIT_DESCRIBE_ERROR) 10 | # Describe output will be in the form v--g[-dirty] 11 | set(IONC_FULL_VERSION ${GIT_DESCRIBE_OUTPUT}) 12 | endif() 13 | endif() 14 | 15 | string(REGEX MATCH "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)-[0-9]+-g([a-zA-Z0-9-]+)$" IONC_FULL_VERSION_MATCH "${IONC_FULL_VERSION}") 16 | set(IONC_VERSION_MAJOR ${CMAKE_MATCH_1}) 17 | set(IONC_VERSION_MINOR ${CMAKE_MATCH_2}) 18 | set(IONC_VERSION_PATCH ${CMAKE_MATCH_3}) 19 | set(IONC_VERSION_HASH ${CMAKE_MATCH_4}) 20 | set(IONC_VERSION "v${IONC_VERSION_MAJOR}.${IONC_VERSION_MINOR}.${IONC_VERSION_PATCH}") 21 | 22 | configure_file(${SRC} ${DST} @ONLY) 23 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | #### 2 | ## CMake creates a file called "install_manifest.txt" when executing 3 | ## the 'install' target (i.e. "make install"). This file is just a 4 | ## simple list of all of the files which were installed. The below 5 | ## cmake script simply reads the contents of this file, converts it 6 | ## into a semicolon delimited cmake LIST and then passes each LIST 7 | ## entry in turn to cmake for deletion ("-E" Command-Line Tool Mode 8 | ## with the cmake command being "remove", which deletes the file). 9 | #### 10 | 11 | if( NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" ) 12 | message( FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" ) 13 | endif() 14 | 15 | file( READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files ) 16 | string( REGEX REPLACE "\n" ";" files "${files}" ) 17 | 18 | foreach( file ${files} ) 19 | set( _this_file "$ENV{DESTDIR}${file}" ) 20 | message( STATUS "Uninstalling \"${_this_file}\"" ) 21 | if( IS_SYMLINK "${_this_file}" OR EXISTS "${_this_file}" ) 22 | execute_process( COMMAND "@CMAKE_COMMAND@" -E remove "${_this_file}" 23 | OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE _exit_code ) 24 | if( NOT "${_exit_code}" STREQUAL 0 ) 25 | message( FATAL_ERROR "Problem removing file \"${_this_file}\"" ) 26 | endif() 27 | else() 28 | message( STATUS "File \"${_this_file}\" does not exist." ) 29 | endif() 30 | endforeach() 31 | 32 | -------------------------------------------------------------------------------- /debug-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gdb --args build/debug/test/tester ion-tests 4 | -------------------------------------------------------------------------------- /decNumber/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(declibsrc 3 | decContext.c 4 | decimal128.c 5 | decimal64.c 6 | decimal32.c 7 | decNumber.c 8 | decPacked.c 9 | decQuad.c) 10 | 11 | set(DEC_PUB_HEADERS 12 | include/decNumber/decContext.h 13 | include/decNumber/decDouble.h 14 | include/decNumber/decDPD.h 15 | include/decNumber/decimal128.h 16 | include/decNumber/decimal32.h 17 | include/decNumber/decimal64.h 18 | include/decNumber/decNumber.h 19 | include/decNumber/decNumberLocal.h 20 | include/decNumber/decPacked.h 21 | include/decNumber/decQuad.h 22 | include/decNumber/decSingle.h) 23 | 24 | add_library(decNumber ${declibsrc}) 25 | set_property(TARGET decNumber PROPERTY POSITION_INDEPENDENT_CODE 1) 26 | 27 | target_include_directories(decNumber 28 | PUBLIC 29 | $ 30 | $) 31 | 32 | set_target_properties(decNumber 33 | PROPERTIES 34 | VERSION "3.68" 35 | SOVERSION "3.68" 36 | PUBLIC_HEADER "${DEC_PUB_HEADERS}") 37 | 38 | # --- 39 | 40 | add_library(decNumber_static STATIC ${declibsrc}) 41 | set_property(TARGET decNumber_static PROPERTY POSITION_INDEPENDENT_CODE 1) 42 | 43 | target_include_directories(decNumber_static 44 | PUBLIC 45 | $ 46 | $) 47 | 48 | set_target_properties(decNumber_static 49 | PROPERTIES 50 | PUBLIC_HEADER "${DEC_PUB_HEADERS}") 51 | 52 | # --- 53 | 54 | install(TARGETS decNumber decNumber_static 55 | EXPORT IonCTargets 56 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 57 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 58 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 59 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/decNumber) 60 | 61 | 62 | install(DIRECTORY include/decNumber 63 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 64 | FILES_MATCHING PATTERN "*.h") 65 | -------------------------------------------------------------------------------- /decNumber/ICU-license.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ICU License - ICU 1.8.1 and later 6 | 7 | 8 | 9 |

ICU License - ICU 1.8.1 and later

10 |
11 | COPYRIGHT AND PERMISSION NOTICE
12 | 
13 | Copyright (c) 1995-2005 International Business Machines Corporation and others
14 | All rights reserved.
15 | 
16 | Permission is hereby granted, free of charge, to any person obtaining a
17 | copy of this software and associated documentation files (the
18 | "Software"), to deal in the Software without restriction, including
19 | without limitation the rights to use, copy, modify, merge, publish,
20 | distribute, and/or sell copies of the Software, and to permit persons
21 | to whom the Software is furnished to do so, provided that the above
22 | copyright notice(s) and this permission notice appear in all copies of
23 | the Software and that both the above copyright notice(s) and this
24 | permission notice appear in supporting documentation.
25 | 
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
29 | OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
30 | HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
31 | INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
32 | FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
33 | NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
34 | WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
35 | 
36 | Except as contained in this notice, the name of a copyright holder
37 | shall not be used in advertising or otherwise to promote the sale, use
38 | or other dealings in this Software without prior written authorization
39 | of the copyright holder.
40 | 
41 | --------------------------------------------------------------------------------
42 | All trademarks and registered trademarks mentioned herein are the property of their respective owners.
43 | 
44 | 45 | 46 | -------------------------------------------------------------------------------- /decNumber/decSingle.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* decSingle.c -- decSingle operations module */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2000, 2008. All rights reserved. */ 5 | /* */ 6 | /* This software is made available under the terms of the */ 7 | /* ICU License -- ICU 1.8.1 and later. */ 8 | /* */ 9 | /* The description and User's Guide ("The decNumber C Library") for */ 10 | /* this software is included in the package as decNumber.pdf. This */ 11 | /* document is also available in HTML, together with specifications, */ 12 | /* testcases, and Web links, on the General Decimal Arithmetic page. */ 13 | /* */ 14 | /* Please send comments, suggestions, and corrections to the author: */ 15 | /* mfc@uk.ibm.com */ 16 | /* Mike Cowlishaw, IBM Fellow */ 17 | /* IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK */ 18 | /* ------------------------------------------------------------------ */ 19 | /* This module comprises decSingle operations (including conversions) */ 20 | /* ------------------------------------------------------------------ */ 21 | 22 | #include "decNumber/decContext.h" // public includes 23 | #include "decNumber/decSingle.h" // public includes 24 | 25 | /* Constant mappings for shared code */ 26 | #define DECPMAX DECSINGLE_Pmax 27 | #define DECEMIN DECSINGLE_Emin 28 | #define DECEMAX DECSINGLE_Emax 29 | #define DECEMAXD DECSINGLE_EmaxD 30 | #define DECBYTES DECSINGLE_Bytes 31 | #define DECSTRING DECSINGLE_String 32 | #define DECECONL DECSINGLE_EconL 33 | #define DECBIAS DECSINGLE_Bias 34 | #define DECLETS DECSINGLE_Declets 35 | #define DECQTINY (-DECSINGLE_Bias) 36 | // parameters of next-wider format 37 | #define DECWBYTES DECDOUBLE_Bytes 38 | #define DECWPMAX DECDOUBLE_Pmax 39 | #define DECWECONL DECDOUBLE_EconL 40 | #define DECWBIAS DECDOUBLE_Bias 41 | 42 | /* Type and function mappings for shared code */ 43 | #define decFloat decSingle // Type name 44 | #define decFloatWider decDouble // Type name 45 | 46 | // Utility (binary results, extractors, etc.) 47 | #define decFloatFromBCD decSingleFromBCD 48 | #define decFloatFromPacked decSingleFromPacked 49 | #define decFloatFromPackedChecked decSingleFromPackedChecked 50 | #define decFloatFromString decSingleFromString 51 | #define decFloatFromWider decSingleFromWider 52 | #define decFloatGetCoefficient decSingleGetCoefficient 53 | #define decFloatGetExponent decSingleGetExponent 54 | #define decFloatSetCoefficient decSingleSetCoefficient 55 | #define decFloatSetExponent decSingleSetExponent 56 | #define decFloatShow decSingleShow 57 | #define decFloatToBCD decSingleToBCD 58 | #define decFloatToEngString decSingleToEngString 59 | #define decFloatToPacked decSingleToPacked 60 | #define decFloatToString decSingleToString 61 | #define decFloatToWider decSingleToWider 62 | #define decFloatZero decSingleZero 63 | 64 | // Non-computational 65 | #define decFloatRadix decSingleRadix 66 | #define decFloatVersion decSingleVersion 67 | 68 | #include "decNumber/decNumberLocal.h" // local includes (need DECPMAX) 69 | #include "decCommon.c" // non-basic decFloat routines 70 | // [Do not include decBasic.c for decimal32] 71 | 72 | -------------------------------------------------------------------------------- /decNumber/decnumber.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazon-ion/ion-c/2a2bae491667bfa3bc901ff05c24935165105ad5/decNumber/decnumber.pdf -------------------------------------------------------------------------------- /decNumber/example1.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal Number Library Demonstration program */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2001, 2007. All rights reserved. */ 5 | /* ----------------------------------------------------------------+- */ 6 | /* right margin -->| */ 7 | 8 | // example1.c -- convert the first two argument words to decNumber, 9 | // add them together, and display the result 10 | 11 | #define DECNUMDIGITS 34 // work with up to 34 digits 12 | #include "decNumber/decNumber.h" // base number library 13 | #include // for printf 14 | 15 | int main(int argc, char *argv[]) { 16 | decNumber a, b; // working numbers 17 | decContext set; // working context 18 | char string[DECNUMDIGITS+14]; // conversion buffer 19 | 20 | decContextTestEndian(0); // warn if DECLITEND is wrong 21 | 22 | if (argc<3) { // not enough words 23 | printf("Please supply two numbers to add.\n"); 24 | return 1; 25 | } 26 | decContextDefault(&set, DEC_INIT_BASE); // initialize 27 | set.traps=0; // no traps, thank you 28 | set.digits=DECNUMDIGITS; // set precision 29 | 30 | decNumberFromString(&a, argv[1], &set); 31 | decNumberFromString(&b, argv[2], &set); 32 | 33 | decNumberAdd(&a, &a, &b, &set); // a=a+b 34 | decNumberToString(&a, string); 35 | 36 | printf("%s + %s => %s\n", argv[1], argv[2], string); 37 | return 0; 38 | } // main 39 | -------------------------------------------------------------------------------- /decNumber/example2.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal Number Library Demonstration program */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2001. All rights reserved. */ 5 | /* ----------------------------------------------------------------+- */ 6 | /* right margin -->| */ 7 | 8 | // example2.c -- calculate compound interest 9 | // Arguments are investment, rate (%), and years 10 | 11 | #define DECNUMDIGITS 38 // work with up to 38 digits 12 | #include "decNumber/decNumber.h" // base number library 13 | #include // for printf 14 | 15 | int main(int argc, char *argv[]) { 16 | int need=3; 17 | if (argc %s\n", 48 | argv[1], argv[2], argv[3], string); 49 | 50 | } //---------------------------------------------------------------| 51 | return 0; 52 | } // main 53 | -------------------------------------------------------------------------------- /decNumber/example3.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal Number Library Demonstration program */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2001. All rights reserved. */ 5 | /* ----------------------------------------------------------------+- */ 6 | /* right margin -->| */ 7 | 8 | // example3.c -- calculate compound interest, passive checking 9 | // Arguments are investment, rate (%), and years 10 | 11 | #define DECNUMDIGITS 38 // work with up to 38 digits 12 | #include "decNumber/decNumber.h" // base number library 13 | #include // for printf 14 | 15 | int main(int argc, char *argv[]) { 16 | int need=3; 17 | if (argc %s\n", 60 | argv[1], argv[2], argv[3], string); 61 | 62 | } //---------------------------------------------------------------| 63 | return 0; 64 | } // main 65 | -------------------------------------------------------------------------------- /decNumber/example4.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal Number Library Demonstration program */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2001. All rights reserved. */ 5 | /* ----------------------------------------------------------------+- */ 6 | /* right margin -->| */ 7 | 8 | // example4.c -- add two numbers, active error handling 9 | // Arguments are two numbers 10 | 11 | #define DECNUMDIGITS 38 // work with up to 38 digits 12 | #include "decNumber/decNumber.h" // base number library 13 | #include // for printf 14 | 15 | // [snip... 16 | #include // signal handling 17 | #include // setjmp/longjmp 18 | 19 | jmp_buf preserve; // stack snapshot 20 | 21 | void signalHandler(int); // prototype for GCC 22 | void signalHandler(int sig) { 23 | signal(SIGFPE, signalHandler); // re-enable 24 | longjmp(preserve, sig); // branch to preserved point 25 | } 26 | // ...snip] 27 | int main(int argc, char *argv[]) { 28 | decNumber a, b; // working numbers 29 | decContext set; // working context 30 | char string[DECNUMDIGITS+14]; // conversion buffer 31 | int value; // work variable 32 | 33 | if (argc<3) { // not enough words 34 | printf("Please supply two numbers to add.\n"); 35 | return 1; 36 | } 37 | decContextDefault(&set, DEC_INIT_BASE); // initialize 38 | 39 | // [snip... 40 | signal(SIGFPE, signalHandler); // set up signal handler 41 | value=setjmp(preserve); // preserve and test environment 42 | if (value) { // (non-0 after longjmp) 43 | set.status &= DEC_Errors; // keep only errors 44 | printf("Signal trapped [%s].\n", decContextStatusToString(&set)); 45 | return 1; 46 | } 47 | // ...snip] 48 | 49 | // [change from Example 1, here] 50 | // leave traps enabled 51 | set.digits=DECNUMDIGITS; // set precision 52 | 53 | decNumberFromString(&a, argv[1], &set); 54 | decNumberFromString(&b, argv[2], &set); 55 | 56 | decNumberAdd(&a, &a, &b, &set); // A=A+B 57 | decNumberToString(&a, string); 58 | 59 | printf("%s + %s => %s\n", argv[1], argv[2], string); 60 | return 0; 61 | } // main 62 | -------------------------------------------------------------------------------- /decNumber/example5.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal Number Library Demonstration program */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2001, 2007. All rights reserved. */ 5 | /* ----------------------------------------------------------------+- */ 6 | /* right margin -->| */ 7 | 8 | // example5.c -- decimal64 conversions 9 | 10 | #include "decNumber/decimal64.h" // decimal64 and decNumber library 11 | #include // for (s)printf 12 | 13 | int main(int argc, char *argv[]) { 14 | decimal64 a; // working decimal64 number 15 | decNumber d; // working number 16 | decContext set; // working context 17 | char string[DECIMAL64_String]; // number->string buffer 18 | char hexes[25]; // decimal64->hex buffer 19 | int i; // counter 20 | 21 | if (argc<2) { // not enough words 22 | printf("Please supply a number.\n"); 23 | return 1; 24 | } 25 | decContextDefault(&set, DEC_INIT_DECIMAL64); // initialize 26 | 27 | decimal64FromString(&a, argv[1], &set); 28 | // lay out the decimal64 as eight hexadecimal pairs 29 | for (i=0; i<8; i++) { 30 | sprintf(&hexes[i*3], "%02x ", a.bytes[i]); 31 | } 32 | decimal64ToNumber(&a, &d); 33 | decNumberToString(&d, string); 34 | printf("%s => %s=> %s\n", argv[1], hexes, string); 35 | return 0; 36 | } // main 37 | -------------------------------------------------------------------------------- /decNumber/example6.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal Number Library Demonstration program */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2001. All rights reserved. */ 5 | /* ----------------------------------------------------------------+- */ 6 | /* right margin -->| */ 7 | 8 | // example6.c -- calculate compound interest, using Packed Decimal 9 | // Values are investment, rate (%), and years 10 | 11 | #include "decNumber/decPacked.h" // base number library 12 | #include // for printf 13 | 14 | int main(int argc, char *argv[]) { 15 | { // excerpt for User's Guide starts here--------------------------| 16 | decNumber one, mtwo, hundred; // constants 17 | decNumber start, rate, years; // parameters 18 | decNumber total; // result 19 | decContext set; // working context 20 | 21 | uint8_t startpack[]={0x01, 0x00, 0x00, 0x0C}; // investment=100000 22 | int32_t startscale=0; 23 | uint8_t ratepack[]={0x06, 0x5C}; // rate=6.5% 24 | int32_t ratescale=1; 25 | uint8_t yearspack[]={0x02, 0x0C}; // years=20 26 | int32_t yearsscale=0; 27 | uint8_t respack[16]; // result, packed 28 | int32_t resscale; // .. 29 | char hexes[49]; // for packed->hex 30 | int i; // counter 31 | 32 | if (argc<0) printf("%s", argv[1]); // noop for warning 33 | 34 | decContextDefault(&set, DEC_INIT_BASE); // initialize 35 | set.traps=0; // no traps 36 | set.digits=25; // precision 25 37 | decNumberFromString(&one, "1", &set); // set constants 38 | decNumberFromString(&mtwo, "-2", &set); 39 | decNumberFromString(&hundred, "100", &set); 40 | 41 | decPackedToNumber(startpack, sizeof(startpack), &startscale, &start); 42 | decPackedToNumber(ratepack, sizeof(ratepack), &ratescale, &rate); 43 | decPackedToNumber(yearspack, sizeof(yearspack), &yearsscale, &years); 44 | 45 | decNumberDivide(&rate, &rate, &hundred, &set); // rate=rate/100 46 | decNumberAdd(&rate, &rate, &one, &set); // rate=rate+1 47 | decNumberPower(&rate, &rate, &years, &set); // rate=rate^years 48 | decNumberMultiply(&total, &rate, &start, &set); // total=rate*start 49 | decNumberRescale(&total, &total, &mtwo, &set); // two digits please 50 | 51 | decPackedFromNumber(respack, sizeof(respack), &resscale, &total); 52 | 53 | // lay out the total as sixteen hexadecimal pairs 54 | for (i=0; i<16; i++) { 55 | sprintf(&hexes[i*3], "%02x ", respack[i]); 56 | } 57 | printf("Result: %s (scale=%ld)\n", hexes, (long int)resscale); 58 | 59 | } //---------------------------------------------------------------| 60 | return 0; 61 | } // main 62 | -------------------------------------------------------------------------------- /decNumber/example7.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal Number Library Demonstration program */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2001, 2008. All rights reserved. */ 5 | /* ----------------------------------------------------------------+- */ 6 | /* right margin -->| */ 7 | 8 | // example7.c -- using decQuad to add two numbers together 9 | 10 | // compile: example7.c decContext.c decQuad.c 11 | 12 | #include "decNumber/decQuad.h" // decQuad library 13 | #include // for printf 14 | 15 | int main(int argc, char *argv[]) { 16 | decQuad a, b; // working decQuads 17 | decContext set; // working context 18 | char string[DECQUAD_String]; // number->string buffer 19 | 20 | decContextTestEndian(0); // warn if DECLITEND is wrong 21 | 22 | if (argc<3) { // not enough words 23 | printf("Please supply two numbers to add.\n"); 24 | return 1; 25 | } 26 | decContextDefault(&set, DEC_INIT_DECQUAD); // initialize 27 | 28 | decQuadFromString(&a, argv[1], &set); 29 | decQuadFromString(&b, argv[2], &set); 30 | decQuadAdd(&a, &a, &b, &set); // a=a+b 31 | decQuadToString(&a, string); 32 | 33 | printf("%s + %s => %s\n", argv[1], argv[2], string); 34 | return 0; 35 | } // main 36 | -------------------------------------------------------------------------------- /decNumber/example8.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal Number Library Demonstration program */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2001, 2007. All rights reserved. */ 5 | /* ----------------------------------------------------------------+- */ 6 | /* right margin -->| */ 7 | 8 | // example8.c -- using decQuad with the decNumber module 9 | 10 | // compile: example8.c decContext.c decQuad.c 11 | // and: decNumber.c decimal128.c decimal64.c 12 | 13 | #include "decNumber/decQuad.h" // decQuad library 14 | #include "decNumber/decimal128.h" // interface to decNumber 15 | #include // for printf 16 | 17 | int main(int argc, char *argv[]) { 18 | decQuad a; // working decQuad 19 | decNumber numa, numb; // working decNumbers 20 | decContext set; // working context 21 | char string[DECQUAD_String]; // number->string buffer 22 | 23 | if (argc<3) { // not enough words 24 | printf("Please supply two numbers for power(2*a, b).\n"); 25 | return 1; 26 | } 27 | decContextDefault(&set, DEC_INIT_DECQUAD); // initialize 28 | 29 | decQuadFromString(&a, argv[1], &set); // get a 30 | decQuadAdd(&a, &a, &a, &set); // double a 31 | decQuadToNumber(&a, &numa); // convert to decNumber 32 | decNumberFromString(&numb, argv[2], &set); 33 | decNumberPower(&numa, &numa, &numb, &set); // numa=numa**numb 34 | decQuadFromNumber(&a, &numa, &set); // back via a Quad 35 | decQuadToString(&a, string); // .. 36 | 37 | printf("power(2*%s, %s) => %s\n", argv[1], argv[2], string); 38 | return 0; 39 | } // main 40 | -------------------------------------------------------------------------------- /decNumber/include/decNumber/decPacked.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Packed Decimal conversion module header */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2000, 2005. All rights reserved. */ 5 | /* */ 6 | /* This software is made available under the terms of the */ 7 | /* ICU License -- ICU 1.8.1 and later. */ 8 | /* */ 9 | /* The description and User's Guide ("The decNumber C Library") for */ 10 | /* this software is called decNumber.pdf. This document is */ 11 | /* available, together with arithmetic and format specifications, */ 12 | /* testcases, and Web links, on the General Decimal Arithmetic page. */ 13 | /* */ 14 | /* Please send comments, suggestions, and corrections to the author: */ 15 | /* mfc@uk.ibm.com */ 16 | /* Mike Cowlishaw, IBM Fellow */ 17 | /* IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK */ 18 | /* ------------------------------------------------------------------ */ 19 | 20 | #if !defined(DECPACKED) 21 | #define DECPACKED 22 | #define DECPNAME "decPacked" /* Short name */ 23 | #define DECPFULLNAME "Packed Decimal conversions" /* Verbose name */ 24 | #define DECPAUTHOR "Mike Cowlishaw" /* Who to blame */ 25 | 26 | #define DECPACKED_DefP 32 /* default precision */ 27 | 28 | #ifndef DECNUMDIGITS 29 | #define DECNUMDIGITS DECPACKED_DefP /* size if not already defined*/ 30 | #endif 31 | #include "decNumber.h" /* context and number library */ 32 | 33 | /* Sign nibble constants */ 34 | #if !defined(DECPPLUSALT) 35 | #define DECPPLUSALT 0x0A /* alternate plus nibble */ 36 | #define DECPMINUSALT 0x0B /* alternate minus nibble */ 37 | #define DECPPLUS 0x0C /* preferred plus nibble */ 38 | #define DECPMINUS 0x0D /* preferred minus nibble */ 39 | #define DECPPLUSALT2 0x0E /* alternate plus nibble */ 40 | #define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */ 41 | #endif 42 | 43 | /* ---------------------------------------------------------------- */ 44 | /* decPacked public routines */ 45 | /* ---------------------------------------------------------------- */ 46 | /* Conversions */ 47 | uint8_t * decPackedFromNumber(uint8_t *, int32_t, int32_t *, 48 | const decNumber *); 49 | decNumber * decPackedToNumber(const uint8_t *, int32_t, const int32_t *, 50 | decNumber *); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /decNumber/include/decNumber/decSingle.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* decSingle.h -- Decimal 32-bit format module header */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2000, 2008. All rights reserved. */ 5 | /* */ 6 | /* This software is made available under the terms of the */ 7 | /* ICU License -- ICU 1.8.1 and later. */ 8 | /* */ 9 | /* The description and User's Guide ("The decNumber C Library") for */ 10 | /* this software is included in the package as decNumber.pdf. This */ 11 | /* document is also available in HTML, together with specifications, */ 12 | /* testcases, and Web links, on the General Decimal Arithmetic page. */ 13 | /* */ 14 | /* Please send comments, suggestions, and corrections to the author: */ 15 | /* mfc@uk.ibm.com */ 16 | /* Mike Cowlishaw, IBM Fellow */ 17 | /* IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK */ 18 | /* ------------------------------------------------------------------ */ 19 | 20 | #if !defined(DECSINGLE) 21 | #define DECSINGLE 22 | 23 | #define DECSINGLENAME "decSingle" /* Short name */ 24 | #define DECSINGLETITLE "Decimal 32-bit datum" /* Verbose name */ 25 | #define DECSINGLEAUTHOR "Mike Cowlishaw" /* Who to blame */ 26 | 27 | /* parameters for decSingles */ 28 | #define DECSINGLE_Bytes 4 /* length */ 29 | #define DECSINGLE_Pmax 7 /* maximum precision (digits) */ 30 | #define DECSINGLE_Emin -95 /* minimum adjusted exponent */ 31 | #define DECSINGLE_Emax 96 /* maximum adjusted exponent */ 32 | #define DECSINGLE_EmaxD 3 /* maximum exponent digits */ 33 | #define DECSINGLE_Bias 101 /* bias for the exponent */ 34 | #define DECSINGLE_String 16 /* maximum string length, +1 */ 35 | #define DECSINGLE_EconL 6 /* exponent continuation length */ 36 | #define DECSINGLE_Declets 2 /* count of declets */ 37 | /* highest biased exponent (Elimit-1) */ 38 | #define DECSINGLE_Ehigh (DECSINGLE_Emax + DECSINGLE_Bias - (DECSINGLE_Pmax-1)) 39 | 40 | /* Required includes */ 41 | #include "decNumber/decContext.h" 42 | #include "decNumber/decQuad.h" 43 | #include "decNumber/decDouble.h" 44 | 45 | /* The decSingle decimal 32-bit type, accessible by all sizes */ 46 | typedef union { 47 | uint8_t bytes[DECSINGLE_Bytes]; /* fields: 1, 5, 6, 20 bits */ 48 | uint16_t shorts[DECSINGLE_Bytes/2]; 49 | uint32_t words[DECSINGLE_Bytes/4]; 50 | } decSingle; 51 | 52 | /* ---------------------------------------------------------------- */ 53 | /* Routines -- implemented as decFloat routines in common files */ 54 | /* ---------------------------------------------------------------- */ 55 | 56 | /* Utilities (binary argument(s) or result, extractors, etc.) */ 57 | extern decSingle * decSingleFromBCD(decSingle *, int32_t, const uint8_t *, int32_t); 58 | extern decSingle * decSingleFromPacked(decSingle *, int32_t, const uint8_t *); 59 | extern decSingle * decSingleFromPackedChecked(decSingle *, int32_t, const uint8_t *); 60 | extern decSingle * decSingleFromString(decSingle *, const char *, decContext *); 61 | extern decSingle * decSingleFromWider(decSingle *, const decDouble *, decContext *); 62 | extern int32_t decSingleGetCoefficient(const decSingle *, uint8_t *); 63 | extern int32_t decSingleGetExponent(const decSingle *); 64 | extern decSingle * decSingleSetCoefficient(decSingle *, const uint8_t *, int32_t); 65 | extern decSingle * decSingleSetExponent(decSingle *, decContext *, int32_t); 66 | extern void decSingleShow(const decSingle *, const char *); 67 | extern int32_t decSingleToBCD(const decSingle *, int32_t *, uint8_t *); 68 | extern char * decSingleToEngString(const decSingle *, char *); 69 | extern int32_t decSingleToPacked(const decSingle *, int32_t *, uint8_t *); 70 | extern char * decSingleToString(const decSingle *, char *); 71 | extern decDouble * decSingleToWider(const decSingle *, decDouble *); 72 | extern decSingle * decSingleZero(decSingle *); 73 | 74 | /* (No Arithmetic routines for decSingle) */ 75 | 76 | /* Non-computational */ 77 | extern uint32_t decSingleRadix(const decSingle *); 78 | extern const char * decSingleVersion(void); 79 | 80 | /* decNumber conversions; these are implemented as macros so as not */ 81 | /* to force a dependency on decimal32 and decNumber in decSingle. */ 82 | /* decSingleFromNumber returns a decimal32 * to avoid warnings. */ 83 | #define decSingleToNumber(dq, dn) decimal32ToNumber((decimal32 *)(dq), dn) 84 | #define decSingleFromNumber(dq, dn, set) decimal32FromNumber((decimal32 *)(dq), dn, set) 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /decNumber/include/decNumber/decimal128.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal 128-bit format module header */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2000, 2005. All rights reserved. */ 5 | /* */ 6 | /* This software is made available under the terms of the */ 7 | /* ICU License -- ICU 1.8.1 and later. */ 8 | /* */ 9 | /* The description and User's Guide ("The decNumber C Library") for */ 10 | /* this software is called decNumber.pdf. This document is */ 11 | /* available, together with arithmetic and format specifications, */ 12 | /* testcases, and Web links, on the General Decimal Arithmetic page. */ 13 | /* */ 14 | /* Please send comments, suggestions, and corrections to the author: */ 15 | /* mfc@uk.ibm.com */ 16 | /* Mike Cowlishaw, IBM Fellow */ 17 | /* IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK */ 18 | /* ------------------------------------------------------------------ */ 19 | 20 | #if !defined(DECIMAL128) 21 | #define DECIMAL128 22 | #define DEC128NAME "decimal128" /* Short name */ 23 | #define DEC128FULLNAME "Decimal 128-bit Number" /* Verbose name */ 24 | #define DEC128AUTHOR "Mike Cowlishaw" /* Who to blame */ 25 | 26 | /* parameters for decimal128s */ 27 | #define DECIMAL128_Bytes 16 /* length */ 28 | #define DECIMAL128_Pmax 34 /* maximum precision (digits) */ 29 | #define DECIMAL128_Emax 6144 /* maximum adjusted exponent */ 30 | #define DECIMAL128_Emin -6143 /* minimum adjusted exponent */ 31 | #define DECIMAL128_Bias 6176 /* bias for the exponent */ 32 | #define DECIMAL128_String 43 /* maximum string length, +1 */ 33 | #define DECIMAL128_EconL 12 /* exp. continuation length */ 34 | /* highest biased exponent (Elimit-1) */ 35 | #define DECIMAL128_Ehigh (DECIMAL128_Emax+DECIMAL128_Bias-DECIMAL128_Pmax+1) 36 | 37 | /* check enough digits, if pre-defined */ 38 | #if defined(DECNUMDIGITS) 39 | #if (DECNUMDIGITS=34 for safe use 41 | #endif 42 | #endif 43 | 44 | #ifndef DECNUMDIGITS 45 | #define DECNUMDIGITS DECIMAL128_Pmax /* size if not already defined*/ 46 | #endif 47 | #ifndef DECNUMBER 48 | #include "decNumber.h" /* context and number library */ 49 | #endif 50 | 51 | /* Decimal 128-bit type, accessible by bytes */ 52 | typedef struct { 53 | uint8_t bytes[DECIMAL128_Bytes]; /* decimal128: 1, 5, 12, 110 bits*/ 54 | } decimal128; 55 | 56 | /* special values [top byte excluding sign bit; last two bits are */ 57 | /* don't-care for Infinity on input, last bit don't-care for NaN] */ 58 | #if !defined(DECIMAL_NaN) 59 | #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */ 60 | #define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */ 61 | #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */ 62 | #endif 63 | 64 | /* ---------------------------------------------------------------- */ 65 | /* Routines */ 66 | /* ---------------------------------------------------------------- */ 67 | /* String conversions */ 68 | decimal128 * decimal128FromString(decimal128 *, const char *, decContext *); 69 | char * decimal128ToString(const decimal128 *, char *); 70 | char * decimal128ToEngString(const decimal128 *, char *); 71 | 72 | /* decNumber conversions */ 73 | decimal128 * decimal128FromNumber(decimal128 *, const decNumber *, 74 | decContext *); 75 | decNumber * decimal128ToNumber(const decimal128 *, decNumber *); 76 | 77 | /* Format-dependent utilities */ 78 | uint32_t decimal128IsCanonical(const decimal128 *); 79 | decimal128 * decimal128Canonical(decimal128 *, const decimal128 *); 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /decNumber/include/decNumber/decimal32.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal 32-bit format module header */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2000, 2006. All rights reserved. */ 5 | /* */ 6 | /* This software is made available under the terms of the */ 7 | /* ICU License -- ICU 1.8.1 and later. */ 8 | /* */ 9 | /* The description and User's Guide ("The decNumber C Library") for */ 10 | /* this software is called decNumber.pdf. This document is */ 11 | /* available, together with arithmetic and format specifications, */ 12 | /* testcases, and Web links, on the General Decimal Arithmetic page. */ 13 | /* */ 14 | /* Please send comments, suggestions, and corrections to the author: */ 15 | /* mfc@uk.ibm.com */ 16 | /* Mike Cowlishaw, IBM Fellow */ 17 | /* IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK */ 18 | /* ------------------------------------------------------------------ */ 19 | 20 | #if !defined(DECIMAL32) 21 | #define DECIMAL32 22 | #define DEC32NAME "decimal32" /* Short name */ 23 | #define DEC32FULLNAME "Decimal 32-bit Number" /* Verbose name */ 24 | #define DEC32AUTHOR "Mike Cowlishaw" /* Who to blame */ 25 | 26 | /* parameters for decimal32s */ 27 | #define DECIMAL32_Bytes 4 /* length */ 28 | #define DECIMAL32_Pmax 7 /* maximum precision (digits) */ 29 | #define DECIMAL32_Emax 96 /* maximum adjusted exponent */ 30 | #define DECIMAL32_Emin -95 /* minimum adjusted exponent */ 31 | #define DECIMAL32_Bias 101 /* bias for the exponent */ 32 | #define DECIMAL32_String 15 /* maximum string length, +1 */ 33 | #define DECIMAL32_EconL 6 /* exp. continuation length */ 34 | /* highest biased exponent (Elimit-1) */ 35 | #define DECIMAL32_Ehigh (DECIMAL32_Emax+DECIMAL32_Bias-DECIMAL32_Pmax+1) 36 | 37 | /* check enough digits, if pre-defined */ 38 | #if defined(DECNUMDIGITS) 39 | #if (DECNUMDIGITS=7 for safe use 41 | #endif 42 | #endif 43 | 44 | #ifndef DECNUMDIGITS 45 | #define DECNUMDIGITS DECIMAL32_Pmax /* size if not already defined*/ 46 | #endif 47 | #ifndef DECNUMBER 48 | #include "decNumber.h" /* context and number library */ 49 | #endif 50 | 51 | /* Decimal 32-bit type, accessible by bytes */ 52 | typedef struct { 53 | uint8_t bytes[DECIMAL32_Bytes]; /* decimal32: 1, 5, 6, 20 bits*/ 54 | } decimal32; 55 | 56 | /* special values [top byte excluding sign bit; last two bits are */ 57 | /* don't-care for Infinity on input, last bit don't-care for NaN] */ 58 | #if !defined(DECIMAL_NaN) 59 | #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */ 60 | #define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */ 61 | #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */ 62 | #endif 63 | 64 | /* ---------------------------------------------------------------- */ 65 | /* Routines */ 66 | /* ---------------------------------------------------------------- */ 67 | /* String conversions */ 68 | decimal32 * decimal32FromString(decimal32 *, const char *, decContext *); 69 | char * decimal32ToString(const decimal32 *, char *); 70 | char * decimal32ToEngString(const decimal32 *, char *); 71 | 72 | /* decNumber conversions */ 73 | decimal32 * decimal32FromNumber(decimal32 *, const decNumber *, 74 | decContext *); 75 | decNumber * decimal32ToNumber(const decimal32 *, decNumber *); 76 | 77 | /* Format-dependent utilities */ 78 | uint32_t decimal32IsCanonical(const decimal32 *); 79 | decimal32 * decimal32Canonical(decimal32 *, const decimal32 *); 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /decNumber/include/decNumber/decimal64.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ */ 2 | /* Decimal 64-bit format module header */ 3 | /* ------------------------------------------------------------------ */ 4 | /* Copyright (c) IBM Corporation, 2000, 2005. All rights reserved. */ 5 | /* */ 6 | /* This software is made available under the terms of the */ 7 | /* ICU License -- ICU 1.8.1 and later. */ 8 | /* */ 9 | /* The description and User's Guide ("The decNumber C Library") for */ 10 | /* this software is called decNumber.pdf. This document is */ 11 | /* available, together with arithmetic and format specifications, */ 12 | /* testcases, and Web links, on the General Decimal Arithmetic page. */ 13 | /* */ 14 | /* Please send comments, suggestions, and corrections to the author: */ 15 | /* mfc@uk.ibm.com */ 16 | /* Mike Cowlishaw, IBM Fellow */ 17 | /* IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK */ 18 | /* ------------------------------------------------------------------ */ 19 | 20 | #if !defined(DECIMAL64) 21 | #define DECIMAL64 22 | #define DEC64NAME "decimal64" /* Short name */ 23 | #define DEC64FULLNAME "Decimal 64-bit Number" /* Verbose name */ 24 | #define DEC64AUTHOR "Mike Cowlishaw" /* Who to blame */ 25 | 26 | 27 | /* parameters for decimal64s */ 28 | #define DECIMAL64_Bytes 8 /* length */ 29 | #define DECIMAL64_Pmax 16 /* maximum precision (digits) */ 30 | #define DECIMAL64_Emax 384 /* maximum adjusted exponent */ 31 | #define DECIMAL64_Emin -383 /* minimum adjusted exponent */ 32 | #define DECIMAL64_Bias 398 /* bias for the exponent */ 33 | #define DECIMAL64_String 24 /* maximum string length, +1 */ 34 | #define DECIMAL64_EconL 8 /* exp. continuation length */ 35 | /* highest biased exponent (Elimit-1) */ 36 | #define DECIMAL64_Ehigh (DECIMAL64_Emax+DECIMAL64_Bias-DECIMAL64_Pmax+1) 37 | 38 | /* check enough digits, if pre-defined */ 39 | #if defined(DECNUMDIGITS) 40 | #if (DECNUMDIGITS=16 for safe use 42 | #endif 43 | #endif 44 | 45 | 46 | #ifndef DECNUMDIGITS 47 | #define DECNUMDIGITS DECIMAL64_Pmax /* size if not already defined*/ 48 | #endif 49 | #ifndef DECNUMBER 50 | #include "decNumber.h" /* context and number library */ 51 | #endif 52 | 53 | /* Decimal 64-bit type, accessible by bytes */ 54 | typedef struct { 55 | uint8_t bytes[DECIMAL64_Bytes]; /* decimal64: 1, 5, 8, 50 bits*/ 56 | } decimal64; 57 | 58 | /* special values [top byte excluding sign bit; last two bits are */ 59 | /* don't-care for Infinity on input, last bit don't-care for NaN] */ 60 | #if !defined(DECIMAL_NaN) 61 | #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */ 62 | #define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */ 63 | #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */ 64 | #endif 65 | 66 | /* ---------------------------------------------------------------- */ 67 | /* Routines */ 68 | /* ---------------------------------------------------------------- */ 69 | /* String conversions */ 70 | decimal64 * decimal64FromString(decimal64 *, const char *, decContext *); 71 | char * decimal64ToString(const decimal64 *, char *); 72 | char * decimal64ToEngString(const decimal64 *, char *); 73 | 74 | /* decNumber conversions */ 75 | decimal64 * decimal64FromNumber(decimal64 *, const decNumber *, 76 | decContext *); 77 | decNumber * decimal64ToNumber(const decimal64 *, decNumber *); 78 | 79 | /* Format-dependent utilities */ 80 | uint32_t decimal64IsCanonical(const decimal64 *); 81 | decimal64 * decimal64Canonical(decimal64 *, const decimal64 *); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /decNumber/readme.txt: -------------------------------------------------------------------------------- 1 | This is the readme.txt for the decNumber package. It includes 2 | instructions for compiling and testing the package; please read them. 3 | --------------------------------------------------------------------- 4 | 5 | decNumber is distributed in two forms; as a complete package from 6 | the International Components for Unicode (ICU) site (under an as-is 7 | license), or as a collection of Open Source files from the GCC source 8 | repository (under the GPL license). 9 | 10 | If you are using the GCC files, you can obtain the documentation, the 11 | example files mentioned below, and this readme from the General 12 | Decimal Arithmetic web page -- http://speleotrove.com/decimal/ (the 13 | URL for the open source files is also linked from there). 14 | 15 | 16 | The ICU package 17 | --------------- 18 | 19 | The ICU package includes the files: 20 | 21 | * readme.txt (this file) 22 | 23 | * ICU-license.html 24 | 25 | * decNumber.pdf (documentation) 26 | 27 | * The .c and .h file for each module in the package (see the 28 | decNumber documentation), together with other included files. 29 | 30 | * The .c files for each of the examples (example1.c through 31 | example8.c). 32 | 33 | The ICU package is made available under the terms of the ICU License 34 | (ICU 1.8.1 and later) included in the package as ICU-license.html. 35 | Your use of that package indicates your acceptance of the terms and 36 | conditions of that Agreement. 37 | 38 | 39 | To use and check decNumber 40 | -------------------------- 41 | 42 | Please read the appropriate license and documentation before using 43 | this package. If you are upgrading an existing use of decNumber 44 | (with version <= 3.37) please read the Changes Appendix for later 45 | versions -- you may need to change the DECLITEND flag. 46 | 47 | 1. Compile and link example1.c, decNumber.c, and decContext.c 48 | For instance, use: 49 | 50 | gcc -o example1 example1.c decNumber.c decContext.c 51 | 52 | Note: If your compiler does not provide stdint.h or if your C 53 | compiler does not handle line comments (// ...), then see the 54 | User's Guide section in the documentation for further information 55 | (including a sample minimal stdint.h). 56 | 57 | The use of compiler optimization is strongly recommended (e.g., 58 | -O3 for GCC or /O2 for Visual Studio). 59 | 60 | 2. Run example1 with two numeric arguments, for example: 61 | 62 | example1 1.23 1.27 63 | 64 | this should display: 65 | 66 | 1.23 + 1.27 => 2.50 67 | 68 | 3. Similarly, try the other examples, at will. 69 | 70 | Examples 2->4 require three files to be compiled, like Example 1. 71 | 72 | Example 5 requires decimal64.c in addition to the core modules. 73 | 74 | Example 6 requires decPacked.c in addition to the core modules. 75 | 76 | Example 7 requires only example7.c decContext.c and decQuad.c 77 | 78 | Example 8 requires example8.c, decContext.c, and decQuad.c, plus 79 | decNumber.c, decimal128.c, and decimal64.c (the latter 80 | for shared tables and code) 81 | 82 | -------------------------------------------------------------------------------- /ionc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(libsrc 3 | decQuadHelpers.c 4 | ion_allocation.c 5 | ion_binary.c 6 | ion_catalog.c 7 | ion_collection.c 8 | ion_debug.c 9 | ion_errors.c 10 | ion_helpers.c 11 | ion_index.c 12 | ion_initialize.c 13 | ion_int.c 14 | ion_reader_binary.c 15 | ion_reader.c 16 | ion_reader_text.c 17 | ion_scanner.c 18 | ion_stream.c 19 | ion_string.c 20 | ion_symbol_table.c 21 | ion_timestamp.c 22 | ion_writer_binary.c 23 | ion_writer.c 24 | ion_writer_text.c 25 | ion_decimal.c 26 | ion_float.c 27 | ion_extractor.c 28 | ion_version.c 29 | ) 30 | 31 | set(LIB_PUB_HEADERS 32 | include/ionc/ion_catalog.h 33 | include/ionc/ion_collection.h 34 | include/ionc/ion_debug.h 35 | include/ionc/ion_decimal.h 36 | include/ionc/ion_error_codes.h 37 | include/ionc/ion_errors.h 38 | include/ionc/ion_extractor.h 39 | include/ionc/ion_float.h 40 | include/ionc/ion.h 41 | include/ionc/ion_int.h 42 | include/ionc/ion_platform_config.h 43 | include/ionc/ion_reader.h 44 | include/ionc/ion_stream.h 45 | include/ionc/ion_string.h 46 | include/ionc/ion_symbol_table.h 47 | include/ionc/ion_timestamp.h 48 | include/ionc/ion_types.h 49 | include/ionc/ion_version.h 50 | include/ionc/ion_writer.h) 51 | 52 | 53 | 54 | # this is the "object library" target: compiles the sources only once 55 | add_library(objlib OBJECT ${libsrc}) 56 | 57 | # shared libraries need PIC 58 | set_target_properties(objlib 59 | PROPERTIES 60 | POSITION_INDEPENDENT_CODE 1 61 | C_STANDARD 99) 62 | 63 | target_include_directories(objlib 64 | PUBLIC 65 | $ 66 | $ 67 | $ 68 | PRIVATE 69 | ${CMAKE_CURRENT_SOURCE_DIR} 70 | ${CMAKE_CURRENT_BINARY_DIR}/../ 71 | ) 72 | 73 | add_dependencies(objlib version) 74 | 75 | 76 | if (MSVC) 77 | add_library(ionc $) 78 | else() 79 | add_library(ionc SHARED $) 80 | target_include_directories(ionc 81 | PUBLIC 82 | $ 83 | $ 84 | $ 85 | PRIVATE 86 | ${CMAKE_CURRENT_SOURCE_DIR} 87 | 88 | ) 89 | set_target_properties(ionc 90 | PROPERTIES 91 | VERSION ${PROJECT_VERSION} 92 | SOVERSION ${PROJECT_VERSION} 93 | PUBLIC_HEADER "${LIB_PUB_HEADERS}") 94 | endif() 95 | 96 | add_library(ionc_static STATIC $) 97 | 98 | 99 | if (MSVC) 100 | target_link_libraries(ionc decNumber) 101 | else() 102 | # Unix requires linking against lib m explicitly. 103 | target_link_libraries(ionc PUBLIC decNumber m) 104 | endif() 105 | 106 | set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/IonC) 107 | 108 | install(TARGETS ionc ionc_static 109 | EXPORT IonCTargets 110 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 111 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 112 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 113 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ionc) 114 | 115 | install(EXPORT IonCTargets 116 | FILE IonCTargets.cmake 117 | NAMESPACE IonC:: 118 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/IonC) 119 | 120 | install(DIRECTORY include/ionc 121 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 122 | FILES_MATCHING PATTERN "*.h") 123 | 124 | #### 125 | ## CMake packaging. Allows other CMake projects to detect and use IonC. 126 | #### 127 | include(CMakePackageConfigHelpers) 128 | 129 | message("CURRENT_SOURCE_DIR : ${CMAKE_CURRENT_SOURCE_DIR}") 130 | message("SOURCE_DIR : ${CMAKE_SOURCE_DIR}") 131 | configure_package_config_file( 132 | ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/IonCConfig.cmake.in 133 | ${CMAKE_BINARY_DIR}/cmake/IonCConfig.cmake 134 | INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/IonC) 135 | 136 | 137 | write_basic_package_version_file( 138 | ${CMAKE_BINARY_DIR}/cmake/IonCConfigVersion.cmake 139 | VERSION ${PROJECT_VERSION} 140 | COMPATIBILITY SameMajorVersion) 141 | 142 | install( 143 | FILES 144 | ${CMAKE_BINARY_DIR}/cmake/IonCConfig.cmake 145 | ${CMAKE_BINARY_DIR}/cmake/IonCConfigVersion.cmake 146 | DESTINATION 147 | ${CMAKE_INSTALL_LIBDIR}/cmake/IonC) 148 | -------------------------------------------------------------------------------- /ionc/decQuadHelpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef DECQUADHELPERS_H_ 16 | #define DECQUADHELPERS_H_ 17 | 18 | #include 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | #define BILLION (int64_t)1000000000 /* 10**9 */ 26 | 27 | // 28 | // these are actually in decQuadHelpers.c 29 | // they really should be part of the decimal package, but 30 | // that's a bit more trouble than it's worth just at the moment (and 31 | // that would also be more work than the specific cases we need just now as well) 32 | // 33 | ION_API_EXPORT void ion_quad_get_exponent_and_shift(const decQuad *quad_value, decContext *set, decQuad *p_int_mantissa, int32_t *p_exp); 34 | ION_API_EXPORT iERR ion_quad_get_quad_from_digits_and_exponent(uint64_t value, int32_t exp, decContext *set, BOOL is_negative, decQuad *p_quad); 35 | 36 | // exported method for getting packed representation. 37 | // decimal package may be statically linked into the DLL (on win32) with no export 38 | // this makes sure this facility is exported. 39 | // This is equivalent to decQuadToPacked. 40 | ION_API_EXPORT void ion_quad_get_packed_and_exponent_from_quad(const decQuad *quad_value, uint8_t *p_packed, int32_t *p_exp); 41 | 42 | uint64_t decQuadToUInt64(const decQuad *df, decContext *set, BOOL *p_overflow, BOOL *p_is_negative); 43 | double decQuadToDouble(const decQuad *dec, decContext *set); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif /* DECQUADHELPERS_H_ */ 50 | -------------------------------------------------------------------------------- /ionc/include/ionc/ion.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | /**@file */ 16 | 17 | /** 18 | * Public interfaces and definitions 19 | */ 20 | 21 | #ifndef ION_H_ 22 | #define ION_H_ 23 | 24 | #include "ion_types.h" /// ion_types.h includes ion_errors.h 25 | #include "ion_string.h" 26 | #include "ion_timestamp.h" 27 | #include "ion_decimal.h" 28 | #include "ion_float.h" 29 | #include "ion_int.h" 30 | #include "ion_collection.h" 31 | #include "ion_symbol_table.h" 32 | #include "ion_stream.h" 33 | #include "ion_reader.h" 34 | #include "ion_writer.h" 35 | #include "ion_catalog.h" 36 | #include "ion_debug.h" 37 | #include "ion_version.h" 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /ionc/include/ionc/ion_catalog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | /**@file */ 16 | 17 | #ifndef ION_CATALOG_H_ 18 | #define ION_CATALOG_H_ 19 | 20 | #include "ion_types.h" 21 | #include "ion_platform_config.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | // Ion Symbol Catalog implementation 28 | // 29 | 30 | /** 31 | * Allocates a new catalog with itself as its memory owner. Must be freed using `ion_catalog_close`. 32 | * @param p_hcatalog - Pointer to a handle to the newly-allocated catalog. 33 | */ 34 | ION_API_EXPORT iERR ion_catalog_open (hCATALOG *p_hcatalog); 35 | 36 | /** 37 | * Allocates a new catalog with the given owner as its memory owner. 38 | * @param p_hcatalog - Pointer to a handle to the newly-allocated catalog. 39 | * @param owner - Handle to the new catalog's memory owner. If NULL, the resulting catalog is its own memory owner and 40 | * must be freed using `ion_catalog_close`. 41 | */ 42 | ION_API_EXPORT iERR ion_catalog_open_with_owner (hCATALOG *p_hcatalog, hOWNER owner); 43 | ION_API_EXPORT iERR ion_catalog_get_symbol_table_count (hCATALOG hcatalog, int32_t *p_count); 44 | ION_API_EXPORT iERR ion_catalog_add_symbol_table (hCATALOG hcatalog, hSYMTAB symtab); 45 | ION_API_EXPORT iERR ion_catalog_find_symbol_table (hCATALOG hcatalog, iSTRING name, long version, hSYMTAB *p_symtab); 46 | ION_API_EXPORT iERR ion_catalog_find_best_match (hCATALOG hcatalog, iSTRING name, long version, hSYMTAB *p_symtab); // or newest version of a symtab pass in version == 0 47 | ION_API_EXPORT iERR ion_catalog_release_symbol_table (hCATALOG hcatalog, hSYMTAB symtab); 48 | 49 | /** 50 | * If the given catalog is its own memory owner, its memory and everything it owns is freed. If the given catalog has an 51 | * external owner and that owner has not been freed, this does nothing; this catalog will be freed when its memory owner 52 | * is freed. If the given symbol table has an external owner which has been freed, the behavior of this function is 53 | * undefined. 54 | */ 55 | ION_API_EXPORT iERR ion_catalog_close (hCATALOG hcatalog); 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif /* ION_CATALOG_H_ */ 62 | -------------------------------------------------------------------------------- /ionc/include/ionc/ion_collection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | /**@file */ 16 | 17 | #ifndef ION_COLLECTION_H_ 18 | #define ION_COLLECTION_H_ 19 | 20 | #include "ion_types.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct _ion_collection_node ION_COLLECTION_NODE; 27 | typedef struct _ion_collection_node *ION_COLLECTION_CURSOR; 28 | 29 | 30 | #define IPCN_DATA_SIZE sizeof(void *) 31 | #define IPCN_OVERHEAD_SIZE (sizeof(ION_COLLECTION_NODE) - IPCN_DATA_SIZE) 32 | 33 | #define IPCN_pNODE_TO_pDATA(x) (&((x)->_data[0])) 34 | #define IPCN_pDATA_TO_pNODE(x) ((ION_COLLECTION_NODE *) (((uint8_t *)(x)) - IPCN_OVERHEAD_SIZE)) 35 | 36 | 37 | /** The node allocation scheme depends on this layout ! 38 | * currently that there are only 2 members so it uses 39 | * the size of the ptr as the base to allocate 40 | */ 41 | struct _ion_collection_node 42 | { 43 | ION_COLLECTION_NODE *_next; 44 | ION_COLLECTION_NODE *_prev; 45 | uint8_t _data[IPCN_DATA_SIZE]; // this is a place holder, length is max value length 46 | }; 47 | 48 | 49 | /** The collections used by the parser are linked lists which are 50 | * managed by the collection header. 51 | * the memory used for the nodes is allocated on the parent, which 52 | * is passed in when the user initializes the collection 53 | * 54 | * the nodes in the list have a user sized data buffer, which is 55 | * expected to a small struct (like ion string) or a scaler (like an 56 | * int or pointer). 57 | * 58 | * the push, pop, and append routines return the address of this 59 | * data buffer - for push and append it is the buffer of the new node 60 | * for pop it is the buffer of the released node - which is still 61 | * allocated and is, therefore, good UNTIL ANOTHER push or append 62 | * or copy is executed against the containing collection. 63 | * 64 | * each collections holds a high water mark free list of nodes that 65 | * were previously used but aren't currently being used 66 | * 67 | * to use this as a: 68 | * queue you'll want to "append" and "pop head" 69 | * stack you'll want to "push" and "pop head" 70 | */ 71 | struct _ion_collection 72 | { 73 | void *_owner; 74 | int32_t _node_size; 75 | int32_t _count; 76 | ION_COLLECTION_NODE *_head; 77 | ION_COLLECTION_NODE *_tail; 78 | ION_COLLECTION_NODE *_freelist; 79 | }; 80 | 81 | // BOOL ion_collection_is_empty(ION_COLLECTION *collection) 82 | #define ION_COLLECTION_IS_EMPTY(collection) \ 83 | ((collection)->_head == NULL) 84 | 85 | // SIZE count = ion_collection_size(ION_COLLECTION_CURSOR *pcursor) 86 | #define ION_COLLECTION_SIZE(pcol) \ 87 | ((pcol)->_count) 88 | 89 | // ION_COLLECTION_CURSOR pcursor = ion_collection_open(ION_COLLECTION *collection) 90 | #define ION_COLLECTION_OPEN(collection, pcursor) \ 91 | (pcursor) = (collection)->_head 92 | 93 | // void *pbuf = ion_collection_next(ION_COLLECTION_CURSOR *pcursor) 94 | #define ION_COLLECTION_NEXT(pcursor, pbuf) \ 95 | if ((pcursor) != NULL) { \ 96 | *((void **)&(pbuf)) = IPCN_pNODE_TO_pDATA(pcursor); \ 97 | (pcursor) = (pcursor)->_next; \ 98 | } else { \ 99 | *((void **)&(pbuf)) = NULL; \ 100 | } 101 | 102 | // ION_COLLECTION_CURSOR *pcursor = ion_collection_close(); 103 | #define ION_COLLECTION_CLOSE(pcursor) \ 104 | (pcursor) = NULL 105 | 106 | 107 | #ifdef __cplusplus 108 | } 109 | #endif 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /ionc/include/ionc/ion_debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | /**@file */ 16 | 17 | #ifndef ION_DEBUG_H_ 18 | #define ION_DEBUG_H_ 19 | 20 | #include "ion_types.h" 21 | #include "ion_platform_config.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | // 28 | // support routines for error handling 29 | // 30 | 31 | #define ION_ERROR_MESSAGE_MAX_LENGTH 1024 32 | 33 | 34 | #ifdef DEBUG 35 | 36 | #define DEBUG_ERR(x) fprintf(stderr,"\nERROR %d [%s] AT LINE %d IN %s\n" \ 37 | , (int)(x), ion_error_to_str(x) \ 38 | , (int)__LINE__, __location_display_name__) 39 | #define DEBUG_ERRMSG(x,m) fprintf(stderr,"\nERROR %d [%s] WITH MESSAGE '%s' AT LINE %d IN %s\n" \ 40 | , (int)(x), ion_error_to_str(x) \ 41 | , (char *)(m) \ 42 | , (int)__LINE__, __location_display_name__) 43 | #define BREAK ion_helper_breakpoint() 44 | #define ENTER(f,l,c) ion_helper_enter(f, l, c) 45 | #define RETURN(f,l,c,e) return ion_helper_return(f, l, c, e) 46 | #ifndef __func__ 47 | #define __location_name__ __file__ 48 | #define __location_display_name__ ion_helper_short_filename(__file__) 49 | #define ENTER_FILE static /*const*/ char *__file__ = __FILE__ 50 | #else 51 | #define __location_name__ __func__ 52 | #define __location_display_name__ __func__ 53 | #define ENTER_FILE static const char *__file__ = __func__ 54 | #endif 55 | #define FN_DEF static long __count__ = 0; \ 56 | ENTER_FILE; \ 57 | /* static const*/ int __line__ = __LINE__; \ 58 | long __temp__ = ENTER(__file__, __line__, __count__); 59 | #else 60 | #define DEBUG_ERR(x) /* nothing */ 61 | #define DEBUG_ERRMSG(x,m) /* nothing */ 62 | #define BREAK ion_helper_breakpoint() /* nothing */ 63 | #define ENTER(f,l,c) /* nothing */ 64 | #define RETURN(f,l,c,e) return e 65 | #define FN_DEF /* nothing */ 66 | #endif 67 | 68 | #define iENTER FN_DEF iERR err = IERR_OK 69 | #define DONTFAILWITH(x) { err = x; goto fail; } 70 | #define FAILWITH(x) { BREAK; DEBUG_ERR(x); err = x; goto fail; } 71 | #define FAILWITHMSG(x,s) { BREAK; DEBUG_ERRMSG(x,s); err = x; goto fail; } 72 | #define IONCHECK(x) { err = x; if (err) goto fail; } 73 | #define SUCCEED() { err = IERR_OK; goto fail; } 74 | #define iRETURN fail: RETURN(__location_name__, __line__, __count__++, err) 75 | 76 | /** The purpose of this Macro is enabling executing a list of functions while 77 | * keeping the first error encountered. 78 | * 79 | * Each function(x) to be executed must have return type of iERR, and need to be enclosed by this Macro. 80 | * 81 | * If error has already happened before, the error code of the current function will be ignored. 82 | * If there're no previous errors, the return code of the current function will be kept. 83 | */ 84 | #define UPDATEERROR(x) { iERR errBackup = (x); if (err == IERR_OK) { err = errBackup; }} 85 | 86 | #define ION_TIMESTAMP_STRING_LENGTH 55 /* does NOT include null terminator */ 87 | 88 | #define ION_VERSION_MARKER_LENGTH 4 89 | 90 | /** DEPRECATED - use the accessor functions below. */ 91 | GLOBAL BOOL g_ion_debug_tracing INITTO(FALSE); 92 | 93 | ION_API_EXPORT BOOL ion_debug_has_tracing(void); 94 | ION_API_EXPORT void ion_debug_set_tracing(BOOL state); 95 | 96 | #ifdef __cplusplus 97 | } 98 | #endif 99 | 100 | #endif /* ION_DEBUG_H_ */ 101 | -------------------------------------------------------------------------------- /ionc/include/ionc/ion_error_codes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | /**@file */ 16 | 17 | 18 | #ifdef ERROR_CODE 19 | 20 | /* IERR_EOF is the short form of IERR_EOF */ 21 | 22 | ERROR_CODE( IERR_OK, 0 ) 23 | ERROR_CODE( IERR_BAD_HANDLE, 1 ) 24 | ERROR_CODE( IERR_INVALID_ARG, 2 ) 25 | ERROR_CODE( IERR_NO_MEMORY, 3 ) 26 | /** Unexpected end of stream. 27 | * E.g. reader reached EOF before closing struct } 28 | */ 29 | ERROR_CODE( IERR_EOF, 4 ) 30 | 31 | /** Usually caused by invalid application calling sequence. 32 | * E.g. read_int when get_type returns string. 33 | */ 34 | ERROR_CODE( IERR_INVALID_STATE, 5 ) 35 | ERROR_CODE( IERR_TOO_MANY_ANNOTATIONS, 6 ) 36 | ERROR_CODE( IERR_UNRECOGNIZED_FLOAT, 7 ) 37 | 38 | /** Usually caused by invalid application calling sequence. 39 | * E.g. read_int when is_null is true. 40 | */ 41 | ERROR_CODE( IERR_NULL_VALUE, 8 ) 42 | ERROR_CODE( IERR_BUFFER_TOO_SMALL, 9 ) 43 | ERROR_CODE( IERR_INVALID_TIMESTAMP, 10 ) 44 | ERROR_CODE( IERR_INVALID_UNICODE_SEQUENCE, 12 ) 45 | ERROR_CODE( IERR_UNREAD_LIMIT_EXCEEDED, 13 ) 46 | ERROR_CODE( IERR_INVALID_TOKEN, 14 ) 47 | ERROR_CODE( IERR_INVALID_UTF8, 15 ) 48 | ERROR_CODE( IERR_LOOKAHEAD_OVERFLOW, 16 ) 49 | ERROR_CODE( IERR_BAD_BASE64_BLOB, 17 ) 50 | ERROR_CODE( IERR_TOKEN_TOO_LONG, 18 ) 51 | ERROR_CODE( IERR_INVALID_UTF8_CHAR, 19 ) 52 | ERROR_CODE( IERR_UNEXPECTED_EOF, 20 ) 53 | ERROR_CODE( IERR_INVALID_ESCAPE_SEQUENCE, 21 ) 54 | 55 | /** Invalid Ion syntax during parsing Ion text input. 56 | * 57 | */ 58 | ERROR_CODE( IERR_INVALID_SYNTAX, 22 ) 59 | ERROR_CODE( IERR_INVALID_TOKEN_CHAR, 23 ) 60 | ERROR_CODE( IERR_INVALID_SYMBOL, 24 ) 61 | ERROR_CODE( IERR_STACK_UNDERFLOW, 25 ) 62 | ERROR_CODE( IERR_INVALID_SYMBOL_LIST, 26 ) 63 | ERROR_CODE( IERR_PARSER_INTERNAL, 27 ) 64 | ERROR_CODE( IERR_INVALID_SYMBOL_TABLE, 28 ) 65 | ERROR_CODE( IERR_IS_IMMUTABLE, 29 ) 66 | ERROR_CODE( IERR_DUPLICATE_SYMBOL, 30 ) 67 | ERROR_CODE( IERR_DUPLICATE_SYMBOL_ID, 31 ) 68 | ERROR_CODE( IERR_NO_SUCH_ELEMENT, 32 ) 69 | 70 | ERROR_CODE( IERR_INVALID_FIELDNAME, 33 ) 71 | 72 | /** Corrupted binary data (not comforms to Ion spec. */ 73 | ERROR_CODE( IERR_INVALID_BINARY, 34 ) 74 | ERROR_CODE( IERR_IMPORT_NOT_FOUND, 35 ) 75 | ERROR_CODE( IERR_NUMERIC_OVERFLOW, 36 ) 76 | ERROR_CODE( IERR_INVALID_ION_VERSION, 37 ) 77 | ERROR_CODE( IERR_ENTRY_NOT_FOUND, 38 ) 78 | ERROR_CODE( IERR_CANT_FIND_FILE, 39 ) 79 | ERROR_CODE( IERR_STREAM_FAILED, 40 ) 80 | ERROR_CODE( IERR_KEY_ALREADY_EXISTS, 41 ) 81 | ERROR_CODE( IERR_KEY_NOT_FOUND, 42 ) 82 | ERROR_CODE( IERR_KEY_ADDED, 43 ) 83 | ERROR_CODE( IERR_HAS_LOCAL_SYMBOLS, 44 ) 84 | ERROR_CODE( IERR_NOT_A_SYMBOL_TABLE, 45 ) 85 | ERROR_CODE( IERR_MARK_NOT_SET, 46 ) 86 | ERROR_CODE( IERR_WRITE_ERROR, 47 ) 87 | ERROR_CODE( IERR_SEEK_ERROR, 48 ) 88 | ERROR_CODE( IERR_READ_ERROR, 49 ) 89 | ERROR_CODE( IERR_INTERNAL_ERROR, 50 ) 90 | 91 | ERROR_CODE( IERR_NEW_LINE_IN_STRING, 51 ) 92 | ERROR_CODE( IERR_INVALID_LEADING_ZEROS, 52 ) 93 | ERROR_CODE( IERR_INVALID_LOB_TERMINATOR, 53 ) 94 | 95 | 96 | // if it was defined we undefine it now 97 | #undef ERROR_CODE 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /ionc/include/ionc/ion_errors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | /**@file */ 16 | 17 | #ifndef ION_ERRORS_ 18 | #define ION_ERRORS_ 19 | 20 | #include "ion_platform_config.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /** define the Ion error code enumeration. 27 | * 28 | */ 29 | enum ion_error_code { 30 | IERR_NOT_IMPL = -1, 31 | 32 | #define ERROR_CODE(name, val) name = val, 33 | #include "ion_error_codes.h" 34 | 35 | IERR_MAX_ERROR_CODE 36 | }; 37 | // included in ion_error.h: #undef ERROR_CODE 38 | 39 | typedef enum ion_error_code iERR; 40 | 41 | /** 42 | * Gets a static string representation of an error code. 43 | */ 44 | ION_API_EXPORT const char *ion_error_to_str(iERR err); 45 | 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif // ION_ERRORS_INCLUDED 52 | -------------------------------------------------------------------------------- /ionc/include/ionc/ion_float.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | /**@file */ 16 | 17 | #ifndef IONC_ION_FLOAT_H 18 | #define IONC_ION_FLOAT_H 19 | 20 | #include "ion_types.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | ION_API_EXPORT BOOL ion_float_is_negative_zero(double value); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | #endif //IONC_ION_FLOAT_H 33 | -------------------------------------------------------------------------------- /ionc/include/ionc/ion_platform_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | /**@file */ 16 | 17 | // 18 | // Ion internal header for platform configurations 19 | // 20 | 21 | #ifndef ION_PLATFORM_CONFIG_H_ 22 | #define ION_PLATFORM_CONFIG_H_ 23 | 24 | // OS Macros 25 | 26 | #ifdef _WIN32 27 | #define ION_PLATFORM_WINDOWS 28 | #endif 29 | 30 | #ifdef __CYGWIN__ 31 | #define ION_PLATFORM_CYGWIN 32 | #endif 33 | 34 | #ifdef __ANDROID__ 35 | #define ION_PLATFORM_ANDROID 36 | #endif 37 | 38 | // Ion Public API Export 39 | // NB - for gcc/clang -fvisibility=hidden should be used, otherwise, all symbols are exported 40 | #if (defined(ION_PLATFORM_WINDOWS) || defined(ION_PLATFORM_CYGWIN)) && defined(_WINDLL) 41 | #define ION_API_EXPORT __declspec(dllexport) 42 | #elif __GNUC__ >= 4 43 | #define ION_API_EXPORT __attribute__ ((visibility("default"))) 44 | #else 45 | #define ION_API_EXPORT 46 | #endif 47 | 48 | // Support for thread local storage across compilers 49 | #if __STDC_VERSION__ >= 201112L 50 | #define THREAD_LOCAL_STORAGE _Thread_local 51 | #elif __GNUC__ 52 | #define THREAD_LOCAL_STORAGE __thread 53 | #elif defined(_MSC_VER) 54 | #define THREAD_LOCAL_STORAGE __declspec(thread) 55 | #else 56 | #error "Compiler does not support thread local storage" 57 | #endif 58 | 59 | // Support for type alignment specification (`alignas`) across compilers 60 | #if __STDC_VERSION__ >= 201112L 61 | #define ALIGN_AS(size) _Alignas(size) 62 | #elif __GNUC__ 63 | #define ALIGN_AS(size) __attribute__((__aligned__(size))) 64 | #elif defined(_MSC_VER) 65 | #define ALIGN_AS(size) __declspec(align(size)) 66 | #else 67 | #error "Compiler does not support type alignment specification" 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /ionc/include/ionc/ion_string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | /**@file */ 16 | 17 | /** 18 | * Ion strings are length prefixed value encoded using UTF8 19 | * this struct provides an independent lifetime for these 20 | * where references into the current buffer or references to 21 | * external strings are unified as a single representation 22 | * 23 | * a length == 0 and value == NULL is a null string 24 | */ 25 | 26 | 27 | 28 | #ifndef ION_STRING_H_ 29 | #define ION_STRING_H_ 30 | 31 | #include 32 | #include "ion_platform_config.h" 33 | #include "ion_types.h" 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | struct _ion_string 40 | { 41 | 42 | int32_t length; /**< The number of bytes in the value array. */ 43 | 44 | 45 | BYTE *value; /**< UTF-8 encoded text, not null-terminated. */ 46 | }; 47 | 48 | #define DEFAULT_STRING_LENGTH 8 /**< default for minimum alloc, 8 is average from IBM study */ 49 | // WAS: #define INIT_ION_STRING(x) memset((x), 0, sizeof(*(x))) 50 | // WAS: #define ION_STRING_INIT(x) memset((x), 0, sizeof(*(x))) 51 | #define ION_STRING_INIT(x) (x)->length = 0; (x)->value = NULL 52 | #define ION_STRING_ASSIGN(dst, src) (dst)->length = (src)->length; (dst)->value = (src)->value 53 | #define ION_STRING_IS_NULL(x) ((x) == NULL || ((x)->value == NULL)) 54 | #define ION_STRING_EQUALS(x, y) (((x) == (y)) || (((x)->length == (y)->length) && (memcmp((x)->value, (y)->value, (x)->length) == 0))) 55 | #define ION_STRING_CHAR_AT(str, ii) ((ii) < (str)->length ? (str)->value[ii] : -1) 56 | 57 | ION_API_EXPORT void ion_string_init (ION_STRING *str); 58 | ION_API_EXPORT void ion_string_assign (ION_STRING *dst, ION_STRING *src); // assigns contents but doesn't move bytes 59 | ION_API_EXPORT ION_STRING *ion_string_assign_cstr (ION_STRING *str, char *val, SIZE len); 60 | ION_API_EXPORT char *ion_string_strdup (ION_STRING *p_ionstring); 61 | ION_API_EXPORT iERR ion_string_copy_to_owner(hOWNER owner, ION_STRING *dst, ION_STRING *src); 62 | 63 | /** 64 | * Gets the number of UTF-8 bytes held by the string. 65 | * 66 | * @param str must not be null. 67 | * 68 | * @return may be zero. 69 | */ 70 | ION_API_EXPORT int ion_string_get_length(ION_STRING *str); 71 | 72 | /** 73 | * Returns -1 is idx is out of range or str is null 74 | */ 75 | ION_API_EXPORT BYTE ion_string_get_byte(ION_STRING *str, int idx); 76 | 77 | /** 78 | * Gets a pointer to the UTF-8 bytes held by the string. 79 | * The number of bytes in the string is determined via ion_string_get_length(). 80 | * 81 | * @param str must not be null. 82 | * 83 | * @return a pointer to the first UTF-8 byte in the string; may be null. 84 | * The byte sequence is not null-terminated. 85 | */ 86 | ION_API_EXPORT BYTE *ion_string_get_bytes(ION_STRING *str); 87 | 88 | ION_API_EXPORT BOOL ion_string_is_null (ION_STRING *str); 89 | ION_API_EXPORT BOOL ion_string_is_equal (ION_STRING *str1, ION_STRING *str2); 90 | 91 | #ifdef __cplusplus 92 | } 93 | #endif 94 | #endif /* ION_STRING_H_ */ 95 | -------------------------------------------------------------------------------- /ionc/include/ionc/ion_version.h: -------------------------------------------------------------------------------- 1 | #ifndef __IONC_VERSION_H__ 2 | #define __IONC_VERSION_H__ 3 | 4 | #include "ion_errors.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /** 11 | * Returns a version string containing the major, minor, and patch level in dotted decimal form. 12 | * The string does not need to be free'd by the caller. 13 | * 14 | * Example: "v1.0.0" 15 | * 16 | * @return Pointer to version string. 17 | */ 18 | ION_API_EXPORT char const *ion_version(void); 19 | 20 | /** 21 | * Returns a version string containing the major, minor, patch, and revision in a format matching 22 | * the output from git's describe: vM.m.p-d-gR[-dirty], where M = Major, m = minor, p = Patch, 23 | * d = commits since tag, R = revision, and -dirty is appended if the repository had been modified 24 | * at the time of build. 25 | * 26 | * This is mostly used for ion-c development and testing. 27 | */ 28 | ION_API_EXPORT char const *ion_version_full(void); 29 | 30 | /** 31 | * Provides ion-c's version information in numeric format by storing the major, minor, and patch level 32 | * into the locations provided by the caller. 33 | * 34 | * @param major A pointer to where to store the major version. 35 | * @param minor A pointer to where to store the minor version. 36 | * @param patch A pointer to where to store the patch level. 37 | * @return IERR_OK if successful. 38 | */ 39 | ION_API_EXPORT iERR ion_version_components(unsigned int *major, unsigned int *minor, unsigned int *patch); 40 | 41 | /** 42 | * Returns a string containing the revision. Currently, the git commit hash. 43 | * 44 | * @return A string containing ion-c's revision. 45 | */ 46 | char const *ion_version_revision(void); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif /* __IONC_VERSION_H__ */ 53 | -------------------------------------------------------------------------------- /ionc/ion_alloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef ION_ALLOC_H_ 16 | #define ION_ALLOC_H_ 17 | 18 | #include 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | // 26 | // ion managed resources are broken into two general classes, primary 27 | // and secondary (ignoring the third case of "user"). 28 | // 29 | // primary resource include readers, writers, catalogs and sometimes 30 | // symbol tables (symtabs). 31 | // 32 | // primary resources are separately allocated and are freed when they 33 | // are closed. 34 | // 35 | // secondary resources are allocated in the scope of a primary resource. 36 | // secondary resources are, for example, ion_strings, decimal and timestamp 37 | // values. and often symbol tables. 38 | // secodary resources are automattically freed when their associated 39 | // primary resource is freed. 40 | // 41 | // this is handled by making allocating memory in pages, where the 42 | // primary resource is the first page of such a chain. Then freeing 43 | // the entire chain as a single operation. 44 | // 45 | 46 | // 47 | // support routines for memory managment 48 | // 49 | ION_API_EXPORT char *ion_alloc_name (hOWNER owner, SIZE length); 50 | ION_API_EXPORT iIMPORT *ion_alloc_import (hSYMTAB hsymtab); 51 | ION_API_EXPORT iSYMBOL *ion_alloc_symbol (hSYMTAB hsymtab); 52 | ION_API_EXPORT decQuad *ion_alloc_decimal (hOWNER owner); 53 | ION_API_EXPORT iTIMESTAMP ion_alloc_timestamp (hOWNER owner); 54 | ION_API_EXPORT void ion_alloc_free (void *ptr); 55 | 56 | // define MEM_DEBUG with compiler flag to turn on memory debugging 57 | 58 | #if defined(MEM_DEBUG) 59 | 60 | #include 61 | 62 | void *debug_malloc(size_t size, const char *file, int line); 63 | void debug_free(const void *ptr, const char *file, int line); 64 | 65 | #define ion_xalloc(x) debug_malloc((x), __FILE__, __LINE__) 66 | #define ion_xfree(x) debug_free((x), __FILE__, __LINE__) 67 | 68 | #else 69 | 70 | #include 71 | 72 | #define ion_xalloc(sz) malloc(sz) 73 | #define ion_xfree(ptr) free(ptr) 74 | 75 | #endif 76 | 77 | //#ifndef ION_ALLOCATION_BLOCK_SIZE 78 | //#define ION_ALLOCATION_BLOCK_SIZE DEFAULT_BLOCK_SIZE 79 | //#endif 80 | 81 | // DEFAULT_BLOCK_SIZE was defined in ion_internal.h, but needed for initializing g_ion_alloc_page_list. 82 | #define DEFAULT_BLOCK_SIZE (1024*64) 83 | 84 | // force aligned allocations 85 | #ifndef ALLOC_ALIGNMENT 86 | #if __STDC_VERSION__ >= 201112L 87 | #include 88 | #include 89 | #define ALLOC_ALIGNMENT (alignof(max_align_t)) 90 | #else 91 | #define ALLOC_ALIGNMENT 16 92 | #endif 93 | #elif ((ALLOC_ALIGNMENT) & ((ALLOC_ALIGNMENT)-1)) != 0 94 | #error Invalid ALLOC_ALIGNMENT. Must be a power of 2. 95 | #endif 96 | 97 | #define ALIGN_MASK ((ALLOC_ALIGNMENT)-1) 98 | 99 | #define ALIGN_SIZE(size) ((((size_t)(size)) + ALIGN_MASK) & ~ALIGN_MASK) 100 | #define ALIGN_PTR(ptr) ALIGN_SIZE(ptr) 101 | 102 | typedef struct _ion_allocation_chain ION_ALLOCATION_CHAIN; 103 | 104 | struct _ion_allocation_chain 105 | { 106 | SIZE size; 107 | ION_ALLOCATION_CHAIN *next; 108 | ION_ALLOCATION_CHAIN *head; 109 | 110 | BYTE *position; 111 | BYTE *limit; 112 | // user bytes follow this header, though there may be some unused bytes here for alignment purposes 113 | }; 114 | 115 | #define ION_ALLOC_BLOCK_TO_USER_PTR(block) ((BYTE*)(((BYTE*)(block)) + ALIGN_SIZE(sizeof(ION_ALLOCATION_CHAIN)))) 116 | #define ION_ALLOC_USER_PTR_TO_BLOCK(ptr) ((ION_ALLOCATION_CHAIN *)(((BYTE*)(ptr)) - ALIGN_SIZE(sizeof(ION_ALLOCATION_CHAIN)))) 117 | 118 | 119 | #ifdef MEM_DEBUG 120 | typedef struct _ion_allocation_chain DBG_ION_ALLOCATION_CHAIN; 121 | 122 | #define ion_alloc_owner(len) _dbg_ion_alloc_owner(len, __FILE__, __LINE__) 123 | #define ion_alloc_with_owner(owner, length) _dbg_ion_alloc_with_owner(owner, length, __FILE__, __LINE__) 124 | #define ion_free_owner(owner) _dbg_ion_free_owner(owner, __FILE__, __LINE__) 125 | #define ion_strdup(owner, dst, src) _dbg_ion_strdup(owner, dst, src, __FILE__, __LINE__) 126 | #else 127 | #define ion_alloc_owner(len) _ion_alloc_owner(len) 128 | #define ion_alloc_with_owner(owner, length) _ion_alloc_with_owner(owner, length) 129 | #define ion_free_owner(owner) _ion_free_owner(owner) 130 | #define ion_strdup(owner, dst, src) _ion_strdup(owner, dst, src) 131 | #endif 132 | 133 | 134 | 135 | void *_ion_alloc_owner (SIZE len); 136 | void *_ion_alloc_with_owner(hOWNER owner, SIZE length); 137 | void _ion_free_owner (hOWNER owner); 138 | iERR _ion_strdup (hOWNER owner, iSTRING dst, iSTRING src); 139 | 140 | 141 | 142 | #ifdef MEM_DEBUG 143 | void *_dbg_ion_alloc_owner (SIZE len, const char *file, int line); 144 | void *_dbg_ion_alloc_with_owner(hOWNER owner, SIZE length, const char *file, int line); 145 | void _dbg_ion_free_owner (hOWNER owner, const char *file, int line); 146 | iERR _dbg_ion_strdup (hOWNER owner, iSTRING dst, iSTRING src, const char *file, int line); 147 | #endif 148 | 149 | 150 | #ifdef __cplusplus 151 | } 152 | #endif 153 | 154 | #endif 155 | 156 | -------------------------------------------------------------------------------- /ionc/ion_catalog_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef ION_CATALOG_IMPL_H_ 16 | #define ION_CATALOG_IMPL_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | struct _ion_catalog 23 | { 24 | void *owner; 25 | ION_SYMBOL_TABLE *system_symbol_table; 26 | ION_COLLECTION table_list; // collection of ION_SYMBOL_TABLE * 27 | 28 | }; 29 | 30 | // internal (pointer based helpers) functions for catalog (in ion_catalog.c) 31 | iERR _ion_catalog_open_with_owner_helper(ION_CATALOG **p_pcatalog, hOWNER owner); 32 | iERR _ion_catalog_get_symbol_table_count_helper(ION_CATALOG *pcatalog, int32_t *p_count); 33 | iERR _ion_catalog_add_symbol_table_helper(ION_CATALOG *pcatalog, ION_SYMBOL_TABLE *psymtab); 34 | iERR _ion_catalog_find_symbol_table_helper(ION_CATALOG *pcatalog, ION_STRING *name, int32_t version, ION_SYMBOL_TABLE **p_psymtab); 35 | iERR _ion_catalog_find_best_match_helper(ION_CATALOG *pcatalog, ION_STRING *name, int32_t version, int32_t max_id, ION_SYMBOL_TABLE **p_psymtab); 36 | iERR _ion_catalog_release_symbol_table_helper(ION_CATALOG *pcatalog, ION_SYMBOL_TABLE *psymtab); 37 | iERR _ion_catalog_close_helper(ION_CATALOG *pcatalog); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif /* ION_CATALOG_IMPL_H_ */ 44 | -------------------------------------------------------------------------------- /ionc/ion_collection_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef ION_COLLECTION_IMPL_H_ 16 | #define ION_COLLECTION_IMPL_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | typedef iERR (*ION_COPY_FN)(void *context, void *dst, void *src, int32_t data_size); 23 | typedef iERR (*ION_COMPARE_FN)(void *lhs, void *rhs, BOOL *is_equal); 24 | 25 | void _ion_collection_initialize(void *allocation_parent, ION_COLLECTION *collection, int32_t data_length); 26 | void *_ion_collection_push (ION_COLLECTION *collection); 27 | void *_ion_collection_append (ION_COLLECTION *collection); 28 | void _ion_collection_pop_head (ION_COLLECTION *collection); 29 | void _ion_collection_pop_tail (ION_COLLECTION *collection); 30 | void _ion_collection_remove (ION_COLLECTION *collection, void *p_entry); 31 | void *_ion_collection_head (ION_COLLECTION *collection); 32 | void *_ion_collection_tail (ION_COLLECTION *collection); 33 | void _ion_collection_reset (ION_COLLECTION *collection); // resets the collection contents, preserves the freelist 34 | void _ion_collection_release (ION_COLLECTION *collection); // frees the pages back to the owner, back to new state - valid only on empty collections 35 | iERR _ion_collection_copy (ION_COLLECTION *dst, ION_COLLECTION *src, ION_COPY_FN copy_contents_fn, void *copy_fn_context); 36 | iERR _ion_collection_compare (ION_COLLECTION *lhs, ION_COLLECTION *rhs, ION_COMPARE_FN compare_contents_fn, BOOL *is_equal); 37 | iERR _ion_collection_contains (ION_COLLECTION *collection, void *element, ION_COMPARE_FN compare_contents_fn, BOOL *contains); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #ifdef HANDY_CODE_TO_COPY 44 | ION_COLLECTION_CURSOR symbol_cursor; 45 | if (!ION_COLLECTION_IS_EMPTY(&symtab->symbols)) { 46 | ION_COLLECTION_OPEN(&symtab->symbols, symbol_cursor); 47 | for (;;) { 48 | ION_COLLECTION_NEXT(symbol_cursor, sym); 49 | if (!sym) break; 50 | 51 | } 52 | ION_COLLECTION_CLOSE(symbol_cursor); 53 | } 54 | 55 | ION_COLLECTION_CURSOR import_cursor; 56 | if (!ION_COLLECTION_IS_EMPTY(&symtab->import_list)) { 57 | ION_COLLECTION_OPEN(&symtab->import_list, import_cursor); 58 | for (;;) { 59 | ION_COLLECTION_NEXT(import_cursor, import); 60 | if (!import) break; 61 | 62 | } 63 | ION_COLLECTION_CLOSE(import_cursor); 64 | } 65 | 66 | ION_COLLECTION_CURSOR symtab_cursor; 67 | if (!ION_COLLECTION_IS_EMPTY(&pcatalog->table_list)) { 68 | ION_COLLECTION_OPEN(&pcatalog->table_list, symtab_cursor); 69 | for (;;) { 70 | ION_COLLECTION_NEXT(symtab_cursor, symtab); 71 | if (!symtab) break; 72 | 73 | } 74 | ION_COLLECTION_CLOSE(symtab_cursor); 75 | } 76 | 77 | #endif 78 | #endif /* ION_COLLECTION_IMPL_H_ */ 79 | -------------------------------------------------------------------------------- /ionc/ion_debug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | // 16 | // ion library debug facilities 17 | // 18 | 19 | #include 20 | 21 | BOOL ion_debug_has_tracing(void) 22 | { 23 | return g_ion_debug_tracing; 24 | } 25 | 26 | void ion_debug_set_tracing(BOOL state) 27 | { 28 | g_ion_debug_tracing = state; 29 | } 30 | -------------------------------------------------------------------------------- /ionc/ion_decimal_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef IONC_ION_DECIMAL_IMPL_H 16 | #define IONC_ION_DECIMAL_IMPL_H 17 | 18 | #include 19 | 20 | #define ION_DECNUMBER_UNITS_SIZE(decimal_digits) \ 21 | (sizeof(decNumberUnit) * ((((decimal_digits) / DECDPUN) + (((decimal_digits) % DECDPUN) ? 1 : 0)))) 22 | 23 | // NOTE: each decNumber has DECNUMUNITS preallocated units in its lsu array. These provide space for (DECNUMUNITS * DECDPUN) 24 | // decimal digits. Therefore, space for an additional (decimal_digits - (DECNUMUNITS * DECDPUN)) digits is needed. 25 | #define ION_DECNUMBER_SIZE(decimal_digits) \ 26 | (sizeof(decNumber) + ((decimal_digits > (DECNUMUNITS * DECDPUN)) ? ION_DECNUMBER_UNITS_SIZE(decimal_digits - (DECNUMUNITS * DECDPUN)) : 0)) 27 | 28 | #define ION_DECIMAL_IS_NUMBER(dec) (dec->type == ION_DECIMAL_TYPE_NUMBER || dec->type == ION_DECIMAL_TYPE_NUMBER_OWNED) 29 | 30 | #define ION_DECIMAL_SAVE_STATUS(decimal_status, decimal_context, status_flags) \ 31 | decimal_status = decContextSaveStatus(decimal_context, status_flags); \ 32 | decContextClearStatus(decimal_context, status_flags); 33 | 34 | #define ION_DECIMAL_TEST_AND_RESTORE_STATUS(decimal_status, decimal_context, status_flags) \ 35 | if (decContextTestStatus(decimal_context, status_flags)) { \ 36 | /* Status failure occurred; fail loudly. */ \ 37 | FAILWITH(IERR_NUMERIC_OVERFLOW); \ 38 | } \ 39 | decContextRestoreStatus(decimal_context, decimal_status, status_flags); 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | iERR _ion_decimal_number_alloc(void *owner, SIZE decimal_digits, decNumber **p_number); 46 | iERR _ion_decimal_from_string_helper(const char *str, decContext *context, hOWNER owner, decQuad *p_quad, decNumber **p_num); 47 | iERR _ion_decimal_to_string_quad_helper(const decQuad *value, char *p_string, BOOL as_float); 48 | iERR _ion_decimal_to_string_number_helper(const decNumber *value, char *p_string); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif //IONC_ION_DECIMAL_IMPL_H 55 | -------------------------------------------------------------------------------- /ionc/ion_errors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include 16 | #include "ion_helpers.h" 17 | 18 | const char *ion_error_to_str(iERR err) 19 | { 20 | char *s; 21 | 22 | switch (err) { 23 | case IERR_NOT_IMPL: 24 | s = "IERR_NOT_IMPL"; 25 | break; 26 | 27 | #define ERROR_CODE( name, val ) case name: s = #name; break; 28 | #include "ionc/ion_error_codes.h" 29 | 30 | default: 31 | return _ion_hack_bad_value_to_str((intptr_t)err, "Unknown error code"); 32 | } 33 | return s; 34 | } 35 | -------------------------------------------------------------------------------- /ionc/ion_float.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | BOOL ion_float_is_negative_zero(double value) { 19 | return value == 0.0 && signbit(value); 20 | } 21 | -------------------------------------------------------------------------------- /ionc/ion_helpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef ION_HELPERS_H_ 16 | #define ION_HELPERS_H_ 17 | 18 | #include 19 | #include 20 | #include "ion_writer_impl.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | // helper functions in IonHelper.c 27 | ION_API_EXPORT BOOL ion_helper_is_ion_version_marker(BYTE *buffer, SIZE len); 28 | ION_API_EXPORT int ion_helper_get_tid_from_ion_type(ION_TYPE t); 29 | ION_API_EXPORT ION_TYPE ion_helper_get_iontype_from_tid(int tid); 30 | 31 | ION_API_EXPORT void ion_helper_breakpoint(void); 32 | ION_API_EXPORT long ion_helper_enter(const char *filename, int line_number, long count); 33 | ION_API_EXPORT iERR ion_helper_return(const char *filename, int line_number, long count, iERR err); 34 | 35 | ION_API_EXPORT const char *ion_helper_short_filename(const char *filename); 36 | ION_API_EXPORT const char *_ion_hack_bad_value_to_str(intptr_t val, char *msg); 37 | 38 | // utf8 helpers 39 | ION_API_EXPORT int32_t ion_makeUnicodeScalar(int32_t high_surrogate, int32_t low_surrogate); 40 | ION_API_EXPORT int32_t ion_makeHighSurrogate(int32_t unicodeScalar); 41 | ION_API_EXPORT int32_t ion_makeLowSurrogate(int32_t unicodeScalar); 42 | ION_API_EXPORT BOOL ion_isHighSurrogate(int32_t c); 43 | ION_API_EXPORT BOOL ion_isLowSurrogate(int32_t c); 44 | ION_API_EXPORT BOOL ion_isSurrogate(int32_t c); 45 | 46 | // base64 encoding helpers 47 | void _ion_writer_text_write_blob_make_base64_image(int triple, char *output); 48 | 49 | // escape sequence helpers 50 | char *_ion_writer_get_control_escape_string(int c); 51 | char *_ion_writer_get_control_escape_string_json(int c); 52 | 53 | // 54 | // helpers to convert some of the public types to char *'s 55 | // these return constants or a pointer to a singleton internal 56 | // buffer - which is volitile and should be copied to local 57 | // space if you want more than one of these - and are not 58 | // thread safe. 59 | ION_API_EXPORT const char *ion_type_to_str(ION_TYPE t); 60 | ION_API_EXPORT const char *ion_error_to_str(iERR err); 61 | 62 | // utility for portable integer to string, constrained to base-10 63 | // NB dest must be large enough (MAX_INT32_LENGTH) 64 | char *_ion_itoa_10(int32_t val, char *dst, SIZE len); 65 | char *_ion_i64toa_10(int64_t val, char *dst, SIZE len); 66 | 67 | // utility for portable strnlen 68 | ION_API_EXPORT SIZE _ion_strnlen(const char *str, const SIZE maxlen); 69 | 70 | /** Get the absolute value of the given integer. 71 | * 72 | */ 73 | uint32_t abs_int32(int32_t value); 74 | 75 | /** Get the absolute value of the given integer. 76 | * 77 | */ 78 | uint64_t abs_int64(int64_t value); 79 | 80 | /** Cast unsigned value with sign to signed value. 81 | * NUMERIC_OVERFLOW if the uint value does not fit into a int 82 | */ 83 | iERR cast_to_int64(uint64_t unsignedInt64Value, BOOL is_negative, int64_t* int64Ptr); 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /* ION_HELPERS_H_ */ 90 | -------------------------------------------------------------------------------- /ionc/ion_index.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | /* 16 | * this helps define indexed collections used for symbol support 17 | * in Ion.c. These follow the collection pattern and use the base 18 | * collection heavily. And, like ion_index, the memory used 19 | * for the nodes is allocated on the parent, which is passed in when 20 | * the user initializes an index. 21 | * 22 | * each collections holds a high water mark free list of nodes that 23 | * were previously used but aren't currently being used 24 | * 25 | * index supports: 26 | * iERR initialize(ION_INDEX *idx, CMP_FN cmp, HASH_FN hash) 27 | * BOOL exists (void *key) 28 | * void *find (void *key) 29 | * BOOL insert (void *key, void *data) 30 | * BOOL upsert (void *key, void *data) 31 | * void delete (void *key) 32 | * void reset () 33 | * void release () 34 | * 35 | * unlike collection index expects the caller to own the key and 36 | * the data objects and index itself only maintains the additional 37 | * data to manage these functions. 38 | * 39 | * there are also cursor macros that mirror the collection cursors 40 | * 41 | * to define the index comparison behavior the user supplies a 42 | * compare function and a hash function 43 | */ 44 | 45 | #ifndef ION_INDEX_H_ 46 | #define ION_INDEX_H_ 47 | 48 | #ifdef __cplusplus 49 | extern "C" { 50 | #endif 51 | 52 | typedef int_fast8_t (*II_COMPARE_FN)(void *key1, void *key2, void *context); 53 | typedef int_fast32_t (*II_HASH_FN) (void *key, void *context); 54 | 55 | #define II_DEFAULT_128X_PERCENT 104 /* 80% pre-converted to "base 128 percent" */ 56 | #define II_DEFAULT_MINIMUM 16 /* net desired buckets */ 57 | 58 | typedef struct _ion_index_options ION_INDEX_OPTIONS; 59 | struct _ion_index_options 60 | { 61 | void *_memory_owner; 62 | II_COMPARE_FN _compare_fn; 63 | II_HASH_FN _hash_fn; 64 | void *_fn_context; 65 | int32_t _initial_size; /* number of actual keys */ 66 | uint8_t _density_target_percent; /* whole percent for table size increases 200% is usual (and default) */ 67 | 68 | }; 69 | 70 | // the node allocation scheme depends on this 71 | // layout - currently that there are only 2 members 72 | // so it uses the size of the ptr as the base to 73 | // allocate 74 | typedef struct _ion_index_node ION_INDEX_NODE; 75 | struct _ion_index_node 76 | { 77 | int_fast32_t _hash; 78 | void *_key; 79 | void *_data; 80 | ION_INDEX_NODE *_next; 81 | }; 82 | 83 | typedef struct _ion_index ION_INDEX; 84 | struct _ion_index 85 | { 86 | void *_memory_owner; 87 | II_COMPARE_FN _compare_fn; 88 | II_HASH_FN _hash_fn; 89 | void *_fn_context; 90 | uint8_t _density_target_percent_128x; 91 | 92 | int32_t _key_count; 93 | int32_t _bucket_count; 94 | int32_t _bucket_in_use_count; // watch for bad distribution 95 | int32_t _grow_at; 96 | ION_INDEX_NODE**_bucket_table; 97 | ION_COLLECTION _nodes; 98 | 99 | }; 100 | 101 | GLOBAL int32_t g_ion_index_multiplier_x128 INITTO(2*128); 102 | 103 | #define II_GROW(x) \ 104 | do { \ 105 | (x) *= g_ion_index_multiplier_x128; \ 106 | (x) /= 128; \ 107 | } while (0) 108 | 109 | // BOOL ion_index_is_empty(ION_INDEX *index) 110 | #define ION_INDEX_IS_EMPTY(index) (ION_INDEX_SIZE(index) == 0) 111 | 112 | // SIZE count = ion_index_size(ION_INDEX *index) 113 | #define ION_INDEX_SIZE(index) ((index)->_count) 114 | 115 | typedef struct _ion_index_node *ION_INDEX_CURSOR; 116 | 117 | // ION_INDEX_CURSOR pcursor = ion_index_open(ION_INDEX *collection) 118 | #define ION_INDEX_OPEN(index, pcursor) ION_COLLECTION_OPEN(&(index)->_nodes, pcursor) 119 | 120 | // void *pbuf = ion_index_next(ION_INDEX_CURSOR *pcursor) 121 | #define ION_INDEX_NEXT(index, pbuf) ION_COLECTION_NEXT( &(index)->_nodes, pbuf ) 122 | 123 | // ION_INDEX_CURSOR *pcursor = ion_index_close(); 124 | #define ION_INDEX_CLOSE(pcursor) ION_COLLECTION_CLOSE( pcursor ) 125 | 126 | iERR _ion_index_initialize(ION_INDEX *index, ION_INDEX_OPTIONS *p_options); 127 | iERR _ion_index_make_room(ION_INDEX *index, int32_t expected_new); 128 | 129 | BOOL _ion_index_exists (ION_INDEX *index, void *key); 130 | void *_ion_index_find (ION_INDEX *index, void *key); 131 | iERR _ion_index_insert (ION_INDEX *index, void *key, void *data); 132 | iERR _ion_index_upsert (ION_INDEX *index, void *key, void *data); 133 | void _ion_index_delete (ION_INDEX *index, void *key, void **p_data); 134 | void _ion_index_reset (ION_INDEX *index); 135 | void _ion_index_release (ION_INDEX *index); 136 | 137 | iERR _ion_index_grow_array(void **p_array, int32_t old_count, int32_t new_count, int32_t entry_size, BOOL with_copy, void *owner); 138 | 139 | #ifdef __cplusplus 140 | } 141 | #endif 142 | 143 | #endif 144 | 145 | -------------------------------------------------------------------------------- /ionc/ion_initialize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | // 16 | // this holds the initializers and forces 17 | // the constants to be defined, not just 18 | // declared. 19 | // 20 | 21 | #define ION_INIT 22 | #include "ion_internal.h" 23 | 24 | void ion_init(void) 25 | { 26 | /* do nothing */ 27 | return; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /ionc/ion_string.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | // 16 | // public functions to manipulate strings 17 | // 18 | // generally the macro version are recommended for 19 | // internal use, which are defined in ion_internal.h 20 | // 21 | 22 | #include "ion_internal.h" 23 | 24 | // 25 | // ion strings are length prefixed value encoded using UTF8 26 | // this struct provides an independant lifetime for these 27 | // where references into the current buffer or references to 28 | // external strings are unified as a single representation 29 | // 30 | // a length == 0 and value == NULL is a null string 31 | // 32 | 33 | void ion_string_init(ION_STRING *str) 34 | { 35 | ION_STRING_INIT(str); 36 | } 37 | 38 | // assigns contents but doesn't move bytes 39 | void ion_string_assign(ION_STRING *dst, ION_STRING *src) 40 | { 41 | ION_STRING_ASSIGN(dst, src); 42 | } 43 | 44 | // assigns the contest of a c string to the ion_string 45 | ION_STRING *ion_string_assign_cstr(ION_STRING *str, char *val, SIZE len) 46 | { 47 | ASSERT(str); 48 | if (len > MAX_INT32) return NULL; 49 | 50 | if (len > 0) { 51 | if (!val) return NULL; 52 | str->length = (int32_t)len; 53 | str->value = (BYTE*)val; 54 | } 55 | else { 56 | str->length = 0; 57 | str->value = (BYTE*)val; 58 | } 59 | 60 | return str; 61 | } 62 | 63 | // assignment with ownership move 64 | iERR ion_string_copy_to_owner(hOWNER owner, ION_STRING *dst, ION_STRING *src) 65 | { 66 | iENTER; 67 | 68 | ASSERT(dst != NULL); 69 | 70 | ION_STRING_INIT(dst); 71 | if (ION_STRING_IS_NULL(src)) SUCCEED(); 72 | dst->value = ion_alloc_with_owner(owner, src->length); 73 | if (dst->value == NULL) FAILWITH(IERR_NO_MEMORY); 74 | memcpy(dst->value, src->value, src->length); 75 | dst->length = src->length; 76 | 77 | iRETURN; 78 | } 79 | 80 | // length in utf-8 bytes 81 | int ion_string_get_length(ION_STRING *str) 82 | { 83 | return str->length; 84 | } 85 | 86 | // was: char *ion_str_dup_chars(ION_STRING *pionstring) 87 | char *ion_string_strdup(ION_STRING *pionstring) 88 | { 89 | char *str = ion_xalloc(pionstring->length + 1); 90 | if (!str) return NULL; 91 | 92 | memcpy(str, pionstring->value, pionstring->length); 93 | str[pionstring->length] = 0; 94 | 95 | return str; 96 | } 97 | 98 | // returns -1 is idx is out of range or str is null 99 | BYTE ion_string_get_byte(ION_STRING *str, int idx) 100 | { 101 | if (idx < 0) return -1; 102 | if (ION_STRING_IS_NULL(str)) return -1; 103 | if (idx >= str->length) return -1; 104 | return *(str->value + idx); 105 | } 106 | 107 | BYTE *ion_string_get_bytes(ION_STRING *str) 108 | { 109 | return str->value; 110 | } 111 | 112 | BOOL ion_string_is_null(ION_STRING *str) 113 | { 114 | return ION_STRING_IS_NULL(str); 115 | } 116 | 117 | BOOL ion_string_is_equal(ION_STRING *str1, ION_STRING *str2) 118 | { 119 | return ION_STRING_EQUALS(str1, str2); 120 | } 121 | -------------------------------------------------------------------------------- /ionc/ion_timestamp_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef ION_TIMESTAMP_IMPL_H_ 16 | #define ION_TIMESTAMP_IMPL_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | // 9999-99-99T23:59:59.9999...999999+12:15\0 23 | // the precision of the quad decimal allows 43 decimal digits 24 | // with 31622400 minutes in a year that's 316,192,377,600 in minutes 25 | // or about 12 digits of precision - that leave 31 digits for seconds 26 | // so: 16 (through minutes) + 2 + 31 + 6 + 1 = 55 characters 27 | 28 | #define ION_TIMESTAMP_NULL_IMAGE "null.timestamp" 29 | #define ION_TIMESTAMP_NULL_IMAGE_LEN 14 30 | #define ION_TIMESTAMP_NULL_OFFSET_IMAGE "-00:00" 31 | #define ION_TIMESTAMP_NULL_OFFSET_IMAGE_LEN 6 32 | 33 | #define ION_TS_NULL 0x00 34 | #define ION_TT_BIT_TZ 0x80 35 | #define ION_TS_SUB_DATE (ION_TT_BIT_MIN | ION_TT_BIT_SEC | ION_TT_BIT_FRAC) 36 | 37 | // If, somehow, the timestamp has coarser than minute precision AND it has a known offset, ignore the offset. 38 | #define HAS_TZ_OFFSET(pt) (IS_FLAG_ON((pt)->precision, ION_TT_BIT_TZ) && IS_FLAG_ON((pt)->precision, ION_TT_BIT_MIN)) 39 | 40 | GLOBAL int JULIAN_DAY_PER_MONTH[2][12] 41 | #ifdef INIT_STATICS 42 | = { 43 | // jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec 44 | { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 45 | { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 46 | } 47 | #endif 48 | ; 49 | 50 | BOOL _ion_timestamp_is_leap_year(int y); 51 | int _ion_timestamp_julian_day (int month, int day, BOOL is_leapyear); 52 | int _ion_timestamp_month (int julianday, BOOL is_leapyear); 53 | int _ion_timestamp_day (int julianday, BOOL is_leapyear); 54 | 55 | int32_t _ion_timestamp_julian_day_1_from_year(int32_t year); 56 | void _ion_timestamp_get_year_and_jan1_from_julian_day(int32_t day, int32_t *p_year, int32_t *p_jan_1_julian); 57 | 58 | int _ion_timestamp_julian_day0_from_year_using_list(int32_t julian_day, int low, int high); 59 | 60 | iERR _ion_timestamp_append_time_to_date(iTIMESTAMP ptime, int hours, int minutes, decQuad *p_seconds, decContext *pcontext); 61 | 62 | iERR _ion_timestamp_to_string_int (int value, int32_t width, char *start, char *end_of_buffer); 63 | iERR _ion_timestamp_copy_to_buf (char *dst, char *src, char *end_of_buffer, int*p_copied); 64 | 65 | iERR _ion_timestamp_parse_int (int *p_value, int32_t width, int terminator, char *cp, char *end_of_buffer); 66 | 67 | iERR ion_timestamp_binary_read( ION_STREAM *pstream, int32_t len, decContext *context, ION_TIMESTAMP *p_value ); 68 | 69 | /** Initialize to null value. 70 | * 71 | */ 72 | iERR _ion_timestamp_initialize(iTIMESTAMP ptime); 73 | 74 | /** fraction = value / scale. 75 | * 76 | */ 77 | iERR _ion_timestamp_get_dec_fraction_with_scale(iTIMESTAMP ptime, int32_t scale, 78 | int32_t value, decQuad *decRetValue, decContext *pcontext); 79 | 80 | /** value = fraction * scale. 81 | * 82 | */ 83 | iERR _ion_timestamp_get_fraction_with_scale(iTIMESTAMP ptime, int32_t scale, 84 | int32_t *value, decContext *pcontext); 85 | 86 | iERR _ion_timestamp_equals_helper(const ION_TIMESTAMP *ptime1, const ION_TIMESTAMP *ptime2, 87 | BOOL *is_equal, decContext *pcontext, BOOL instant_only); 88 | 89 | /** Compare timestamps for instant equality only (i.e. precision and local offsets need not be equivalent). 90 | * NOTE: if this has any use externally, it could be exposed. If not, it should be removed. 91 | */ 92 | iERR ion_timestamp_instant_equals(const ION_TIMESTAMP *ptime1, const ION_TIMESTAMP *ptime2, 93 | BOOL *is_equal, decContext *pcontext); 94 | 95 | /** 96 | * Convert ptime to UTC (i.e. the pout's local offset will be +00:00 unless ptime's local offset is unknown, 97 | * in which case pout's local offset will be -00:00). 98 | * @param ptime - The timestamp to convert to UTC. 99 | * @param pout - The resulting UTC timestamp (may be the same reference as ptime). 100 | * @return IERR_OK, unless ptime is an invalid timestamp. 101 | */ 102 | iERR _ion_timestamp_to_utc(const ION_TIMESTAMP *ptime, ION_TIMESTAMP *pout); 103 | 104 | /** 105 | * Validates that the given fraction is at least zero is less than one. 106 | * @param p_fraction the fraction to validate. 107 | * @param pcontext the decContext to use for the comparison. 108 | * @param error_code the error code to return if validation fails. 109 | * @return IERR_OK, unless p_fraction is out of range. 110 | */ 111 | iERR _ion_timestamp_validate_fraction(decQuad *p_fraction, decContext *pcontext, iERR error_code); 112 | 113 | #ifdef __cplusplus 114 | } 115 | #endif 116 | 117 | #endif /* ION_TIMESTAMP_IMPL_H_ */ 118 | -------------------------------------------------------------------------------- /ionc/ion_version.c: -------------------------------------------------------------------------------- 1 | #include "ion_internal.h" 2 | 3 | // This is generated by cmake using git and available tags. 4 | #include "build_version.h" 5 | 6 | char const *ion_version(void) { 7 | return IONC_VERSION; 8 | } 9 | 10 | char const *ion_version_full(void) { 11 | return IONC_BUILD_VERSION; 12 | } 13 | 14 | iERR ion_version_components(unsigned int *major, unsigned int *minor, unsigned int *patch) { 15 | if (major != NULL) { 16 | *major = IONC_VERSION_MAJOR; 17 | } 18 | if (major != NULL) { 19 | *minor = IONC_VERSION_MINOR; 20 | } 21 | if (patch != NULL) { 22 | *patch = IONC_VERSION_PATCH; 23 | } 24 | return IERR_OK; 25 | } 26 | 27 | char const *ion_version_revision(void) { 28 | return IONC_VERSION_HASH; 29 | } 30 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 2 | set(CMAKE_CXX_EXTENSIONS OFF) 3 | if (NOT CMAKE_CXX_FLAGS OR CMAKE_CXX_STANDARD LESS 14) 4 | set(CMAKE_CXX_STANDARD 14) 5 | endif() 6 | 7 | # Avoid macro definition collisions between ionc and googletest. 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_DONT_DEFINE_SUCCEED=1 -DGTEST_DONT_DEFINE_FAIL=1") 9 | # Verbose parameterized names are disabled in debug configuration and on Windows. These don't 10 | # always integrate well with IDEs (e.g. CLion), but are nice to have from the command line. 11 | 12 | add_executable(all_tests 13 | gather_vectors.cpp 14 | ion_assert.cpp 15 | ion_test_util.cpp 16 | test_vectors.cpp 17 | test_ion_binary.cpp 18 | test_ion_writer.cpp 19 | test_ion_decimal.cpp 20 | test_ion_symbol.cpp 21 | test_ion_text.cpp 22 | test_ion_timestamp.cpp 23 | test_ion_values.cpp 24 | test_ion_extractor.cpp 25 | test_ion_integer.cpp 26 | test_ion_cli.cpp 27 | test_ion_stream.cpp 28 | test_ion_reader_seek.cpp 29 | ) 30 | 31 | target_include_directories(all_tests 32 | PRIVATE 33 | . 34 | ../tools/cli 35 | ../tools/events 36 | ../tools/events/inc 37 | ../ionc/ 38 | ../ionc/include 39 | ) 40 | 41 | # Linking against gtest_main provides a basic main() method, which detects all tests, for free. 42 | target_link_libraries(all_tests ionc ion_events ion_cli gtest_main) 43 | -------------------------------------------------------------------------------- /test/gather_vectors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef IONC_GATHER_VECTORS_H 16 | #define IONC_GATHER_VECTORS_H 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #ifdef ION_PLATFORM_WINDOWS 27 | #define ION_TEST_PATH_SEPARATOR_CHAR '\\' 28 | #else 29 | #define ION_TEST_PATH_SEPARATOR_CHAR '/' 30 | #endif 31 | 32 | /** Returns true if file should be included. */ 33 | typedef BOOL (*FILE_PREDICATE_FN)(std::string filename); 34 | 35 | typedef enum _test_file_type 36 | { 37 | FILETYPE_BINARY = 1, 38 | FILETYPE_TEXT, 39 | FILETYPE_ALL 40 | 41 | } TEST_FILE_TYPE; 42 | 43 | typedef enum _test_file_classification 44 | { 45 | CLASSIFICATION_GOOD_BASIC = 1, 46 | CLASSIFICATION_GOOD_EQUIVS, 47 | CLASSIFICATION_GOOD_NONEQUIVS, 48 | CLASSIFICATION_GOOD_TIMESTAMP_EQUIVTIMELINE, 49 | CLASSIFICATION_BAD 50 | 51 | } TEST_FILE_CLASSIFICATION; 52 | 53 | std::string find_ion_tests_path(); 54 | std::string join_path(std::string prefix, std::string suffix); 55 | 56 | static const std::string iontests_path = find_ion_tests_path(); 57 | static const std::string good_path = join_path("iontestdata", "good"); 58 | static const std::string bad_path = join_path("iontestdata", "bad"); 59 | static const std::string bad_timestamp_path = join_path(bad_path, "timestamp"); 60 | static const std::string good_equivs_path = join_path(good_path, "equivs"); 61 | static const std::string good_nonequivs_path = join_path(good_path, "non-equivs"); 62 | static const std::string good_timestamp_path = join_path(good_path, "timestamp"); 63 | static const std::string good_timestamp_equivtimeline_path = join_path(good_timestamp_path, "equivTimeline"); 64 | 65 | static const std::string full_good_path = join_path(iontests_path, good_path); 66 | static const std::string full_good_equivs_path = join_path(full_good_path, "equivs"); 67 | static const std::string full_good_nonequivs_path = join_path(full_good_path, "non-equivs"); 68 | static const std::string full_good_timestamp_equivtimeline_path = join_path(iontests_path, good_timestamp_equivtimeline_path); 69 | static const std::string full_bad_path = join_path(iontests_path, bad_path); 70 | 71 | /** 72 | * Gather all files of the given type and classification under the ion-tests directory. 73 | * @param filetype - specifies binary, text, or all files. 74 | * @param classification - specifies good basic, good equivs, good nonequivs, good timestamp equivtimeline, or bad files. 75 | * @param files_out - sink for the matching files. 76 | * @return IERR_OK on success. 77 | */ 78 | iERR gather_files( 79 | TEST_FILE_TYPE filetype 80 | , TEST_FILE_CLASSIFICATION classification 81 | , std::vector *files_out 82 | ); 83 | 84 | #endif //IONC_GATHER_VECTORS_H 85 | -------------------------------------------------------------------------------- /test/ion_assert.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include "ion_assert.h" 16 | 17 | std::string _bytesToHexString(const BYTE *bytes, SIZE len) { 18 | std::stringstream ss; 19 | ss << std::hex; 20 | for (int i = 0; i < len; ++i) { 21 | ss << std::setfill('0') << std::setw(2) << (int)bytes[i] << " "; 22 | } 23 | return ss.str(); 24 | } 25 | 26 | void assertBytesEqual(const char *expected, SIZE expected_len, const BYTE *actual, SIZE actual_len) { 27 | EXPECT_EQ(expected_len, actual_len); 28 | BOOL bytes_not_equal = memcmp((BYTE *)expected, actual, (size_t)actual_len); 29 | if (bytes_not_equal) { 30 | ASSERT_FALSE(bytes_not_equal) << "Expected: " << _bytesToHexString((BYTE *)expected, expected_len) << " vs. " << std::endl 31 | << " Actual: "<< _bytesToHexString(actual, actual_len); 32 | } 33 | } 34 | 35 | void assertStringsEqual(const char *expected, const char *actual, SIZE actual_len) { 36 | BOOL strings_not_equal = strlen(expected) != actual_len || strncmp(expected, actual, (size_t)actual_len); 37 | if (strings_not_equal) { 38 | ASSERT_FALSE(strings_not_equal) << std::string(expected) << " vs. " << std::endl 39 | << std::string(actual, (unsigned long)actual_len); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/ion_assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef IONC_ION_ASSERT_H 16 | #define IONC_ION_ASSERT_H 17 | 18 | #include 19 | #include 20 | 21 | /** 22 | * Tests that the given bytes are equal. 23 | */ 24 | void assertBytesEqual(const char *expected, SIZE expected_len, const BYTE *actual, SIZE actual_len); 25 | 26 | /** 27 | * Tests that the given strings are equal. 28 | */ 29 | void assertStringsEqual(const char *expected, const char *actual, SIZE actual_len); 30 | 31 | #endif -------------------------------------------------------------------------------- /test/ion_test_util.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include 16 | #include "ion_helpers.h" 17 | #include "ion_test_util.h" 18 | #include "ion_event_util.h" 19 | 20 | void BinaryAndTextTest::SetUp() { 21 | is_binary = GetParam(); 22 | } 23 | 24 | iERR ion_test_new_writer(hWRITER *writer, ION_STREAM **ion_stream, BOOL is_binary) { 25 | iENTER; 26 | IONCHECK(ion_stream_open_memory_only(ion_stream)); 27 | ION_WRITER_OPTIONS options; 28 | ion_event_initialize_writer_options(&options); 29 | options.output_as_binary = is_binary; 30 | IONCHECK(ion_writer_open(writer, *ion_stream, &options)); 31 | iRETURN; 32 | } 33 | 34 | iERR ion_test_writer_get_bytes(hWRITER writer, ION_STREAM *ion_stream, BYTE **out, SIZE *len) { 35 | iENTER; 36 | POSITION pos; 37 | UPDATEERROR(ion_writer_close(writer)); 38 | pos = ion_stream_get_position(ion_stream); 39 | UPDATEERROR(ion_stream_seek(ion_stream, 0)); 40 | *out = (BYTE *)(malloc((size_t)pos)); 41 | UPDATEERROR(ion_stream_read(ion_stream, *out, (SIZE)pos, len)); 42 | UPDATEERROR(ion_stream_close(ion_stream)); 43 | if (*len != (SIZE)pos) { 44 | UPDATEERROR(IERR_EOF); 45 | } 46 | RETURN(__location_name__, __line__, __count__++, err); 47 | } 48 | 49 | iERR ion_test_writer_write_symbol_sid(ION_WRITER *writer, SID sid) { 50 | iENTER; 51 | ION_SYMBOL symbol; 52 | memset(&symbol, 0, sizeof(ION_SYMBOL)); 53 | symbol.sid = sid; 54 | IONCHECK(ion_writer_write_ion_symbol(writer, &symbol)); 55 | iRETURN; 56 | } 57 | 58 | iERR ion_test_writer_add_annotation_sid(ION_WRITER *writer, SID sid) { 59 | iENTER; 60 | ION_SYMBOL symbol; 61 | memset(&symbol, 0, sizeof(ION_SYMBOL)); 62 | symbol.sid = sid; 63 | IONCHECK(ion_writer_add_annotation_symbol(writer, &symbol)); 64 | iRETURN; 65 | } 66 | 67 | iERR ion_test_writer_write_field_name_sid(ION_WRITER *writer, SID sid) { 68 | iENTER; 69 | ION_SYMBOL symbol; 70 | memset(&symbol, 0, sizeof(ION_SYMBOL)); 71 | symbol.sid = sid; 72 | IONCHECK(ion_writer_write_field_name_symbol(writer, &symbol)); 73 | iRETURN; 74 | } 75 | 76 | iERR ion_string_from_cstr(const char *cstr, ION_STRING *out) { 77 | iENTER; 78 | if (!out) FAILWITH(IERR_INVALID_ARG); 79 | out->value = (BYTE *)cstr; 80 | out->length = (SIZE)strlen(cstr); 81 | iRETURN; 82 | } 83 | 84 | iERR ion_test_new_reader(BYTE *ion_data, SIZE buffer_length, hREADER *reader) { 85 | iENTER; 86 | ION_READER_OPTIONS options; 87 | ion_event_initialize_reader_options(&options); 88 | IONCHECK(ion_reader_open_buffer(reader, ion_data, buffer_length, &options)); 89 | iRETURN; 90 | } 91 | 92 | iERR ion_test_new_text_reader(const char *ion_text, hREADER *reader) { 93 | iENTER; 94 | IONCHECK(ion_test_new_reader((BYTE *)ion_text, (SIZE)strlen(ion_text), reader)); 95 | iRETURN; 96 | } 97 | 98 | iERR ion_test_reader_read_symbol_sid(ION_READER *reader, SID *sid) { 99 | iENTER; 100 | ASSERT(sid); 101 | ION_SYMBOL symbol; 102 | IONCHECK(ion_reader_read_ion_symbol(reader, &symbol)); 103 | *sid = symbol.sid; 104 | iRETURN; 105 | } 106 | 107 | iERR ion_read_string_as_chars(hREADER reader, char **out) { 108 | iENTER; 109 | ION_STRING ion_string; 110 | IONCHECK(ion_reader_read_string(reader, &ion_string)); 111 | *out = ion_string_strdup(&ion_string); 112 | iRETURN; 113 | } 114 | 115 | void ion_test_print_bytes(BYTE *bytes, SIZE length) { 116 | for(int i = 0; i < length; i++) { 117 | printf("\\x%02X", bytes[i]); 118 | } 119 | printf("\n"); 120 | } 121 | -------------------------------------------------------------------------------- /test/ion_test_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef IONC_ION_TEST_UTIL_H 16 | #define IONC_ION_TEST_UTIL_H 17 | 18 | #include 19 | #include 20 | 21 | #define ION_ASSERT_OK(x) ASSERT_EQ(IERR_OK, x) 22 | #define ION_ASSERT_FAIL(x) ASSERT_FALSE(IERR_OK == (x)) 23 | 24 | #define INSTANTIATE_TEST_CASE_BOOLEAN_PARAM(instantiation_name) \ 25 | INSTANTIATE_TEST_SUITE_P(instantiation_name, BinaryAndTextTest, ::testing::Bool()) 26 | 27 | /** 28 | * Parameterized test fixture for tests that should be run for both text and binary. 29 | * Use by declaring a test with TEST_P(BinaryAndTextTest, TestName) {...}. 30 | */ 31 | class BinaryAndTextTest : public ::testing::TestWithParam { 32 | virtual void SetUp(); 33 | public: 34 | BOOL is_binary; 35 | }; 36 | 37 | /** 38 | * Initializes and opens a new in-memory writer. 39 | * @param writer - the writer to initialize and open. 40 | * @param ion_stream - output parameter for the underlying in-memory stream. 41 | * @param is_binary - TRUE if the writer should be a binary writer; else FALSE. 42 | * @return IERR_OK, unless the writer or stream fails to open. 43 | */ 44 | iERR ion_test_new_writer(hWRITER *writer, ION_STREAM **ion_stream, BOOL is_binary); 45 | 46 | /** 47 | * Closes a writer and its in-memory stream and copies the written bytes. 48 | * @param writer - the writer to finish. 49 | * @param ion_stream - the stream to close. 50 | * @param out - output parameter for the copied written bytes. 51 | * @param len - the length of the written bytes. 52 | * @return IERR_OK, unless the writer or stream fails to close. 53 | */ 54 | iERR ion_test_writer_get_bytes(hWRITER writer, ION_STREAM *ion_stream, BYTE **out, SIZE *len); 55 | 56 | /** 57 | * Creates an ION_SYMBOL with the given SID and calls `ion_writer_write_ion_symbol`. 58 | * @param writer - the writer to write to. 59 | * @param sid - the local SID of the symbol to be written. 60 | * @return the result of `ion_writer_write_ion_symbol`. 61 | */ 62 | iERR ion_test_writer_write_symbol_sid(ION_WRITER *writer, SID sid); 63 | 64 | /** 65 | * Creates an ION_SYMBOL with the given SID and calls `ion_writer_add_annotation_symbol`. 66 | * @param writer - the writer to write to. 67 | * @param sid - the local SID of the symbol to be written. 68 | * @return the result of `ion_writer_add_annotation_symbol`. 69 | */ 70 | iERR ion_test_writer_add_annotation_sid(ION_WRITER *writer, SID sid); 71 | 72 | /** 73 | * Creates an ION_SYMBOL with the given SID and calls `ion_writer_write_field_name_symbol`. 74 | * @param writer - the writer to write to. 75 | * @param sid - the local SID of the symbol to be written. 76 | * @return the result of `ion_writer_write_field_name_symbol`. 77 | */ 78 | iERR ion_test_writer_write_field_name_sid(ION_WRITER *writer, SID sid); 79 | 80 | /** 81 | * Assigns the given char * to an ION_STRING, without copying. 82 | * @param cstr - the char * to assign. 83 | * @param out - the ION_STRING to assign to. 84 | * @return IERR_OK, unless out is NULL. 85 | */ 86 | iERR ion_string_from_cstr(const char *cstr, ION_STRING *out); 87 | 88 | /** 89 | * Initializes and opens a new in-memory reader over the given buffer of Ion data. 90 | * @param ion_data - the Ion data to read. 91 | * @param buffer_length - the length of the buffer of Ion data. 92 | * @param reader - the reader to initialize and open. 93 | * @return IERR_OK, unless the reader fails to open. 94 | */ 95 | iERR ion_test_new_reader(BYTE *ion_data, SIZE buffer_length, hREADER *reader); 96 | 97 | /** 98 | * Initializes and opens a new in-memory reader over the given string of Ion text. 99 | * @param ion_text - the Ion text to read. 100 | * @param reader - the reader to initialize and open. 101 | * @return IERR_OK, unless the reader fails to open. 102 | */ 103 | iERR ion_test_new_text_reader(const char *ion_text, hREADER *reader); 104 | 105 | /** 106 | * Reads an ION_SYMBOL and provides its local SID. 107 | * @param reader - the reader from which to read. 108 | * @param sid - Output parameter for the local SID of the symbol 109 | * @return the result of `ion_reader_read_symbol.` 110 | */ 111 | iERR ion_test_reader_read_symbol_sid(ION_READER *reader, SID *sid); 112 | 113 | /** 114 | * Reads the Ion string at the given reader's current position and assigns its contents 115 | * to a char *. 116 | * @param reader - the reader from which to read the string. 117 | * @param out - output parameter for the copied string. 118 | * @return IERR_OK, unless the read or the copy fails. 119 | */ 120 | iERR ion_read_string_as_chars(hREADER reader, char **out); 121 | 122 | /** 123 | * Prints the given bytes in two-digit hexadecimal format, delimited by "\x" 124 | * @param bytes - the bytes to print. 125 | * @param length - the number of bytes to print. 126 | */ 127 | void ion_test_print_bytes(BYTE *bytes, SIZE length); 128 | 129 | #endif //IONC_ION_TEST_UTIL_H 130 | -------------------------------------------------------------------------------- /test/test_ion_integer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include "ion_assert.h" 16 | #include "ion_helpers.h" 17 | #include "ion_test_util.h" 18 | 19 | iERR test_ion_int_roundtrip_int64_t(int64_t value_in, int64_t * value_out) { 20 | iENTER; 21 | // Create an uninitialized Ion integer. 22 | ION_INT * iint; 23 | // Initialize the Ion integer, setting its owner to NULL. 24 | IONCHECK(ion_int_alloc(NULL, &iint)); 25 | // Populate the Ion integer with the provided int64_t value. 26 | IONCHECK(ion_int_from_long(iint, value_in)); 27 | // Read the Ion integer's value back out into the output int64_t. 28 | IONCHECK(ion_int_to_int64(iint, value_out)); 29 | // Free the memory used to store the Ion integer's digits. 30 | ion_int_free(iint); 31 | iRETURN; 32 | } 33 | 34 | TEST(IonInteger, IIntToInt64RoundTrip) { 35 | // This test verifies that the `ion_int_from_long` and `ion_int_to_int64` functions work as 36 | // intended. For each of the following values in the range from MIN_INT64 to MAX_INT64 inclusive, 37 | // the test will convert the int64_t to an IINT and then back again, confirming that the output 38 | // int64_t is equal to the input int64_t. 39 | const uint32_t number_of_values = 19; 40 | int64_t values[number_of_values] = { 41 | MIN_INT64, MAX_INT64, 42 | MIN_INT64 + 16, MAX_INT64 - 16, 43 | -9670031482938124, 9670031482938124, 44 | -10031482954246, 10031482954246, 45 | -58116329947, 58116329947, 46 | -66182226, 66182226, 47 | -75221, 75221, 48 | -825, 825 49 | -1, 1, 50 | 0 51 | }; 52 | 53 | int64_t value_in; 54 | int64_t value_out; 55 | for(int m = 0; m < number_of_values; m++) { 56 | value_in = values[m]; 57 | ION_ASSERT_OK(test_ion_int_roundtrip_int64_t(value_in, &value_out)); 58 | ASSERT_EQ(value_in, value_out); 59 | } 60 | } 61 | 62 | iERR test_ion_int_to_int64_t_overflow_detection(const char * p_chars) { 63 | iENTER; 64 | const uint32_t max_string_length = 32; 65 | uint32_t string_length = strnlen(p_chars, max_string_length); 66 | // Create an uninitialized Ion integer. 67 | ION_INT *iint = NULL; 68 | // Create an int64_t that we will later populate with the value of iint. 69 | int64_t value_out; 70 | 71 | // Allocate ION_INT on the heap so we don't have to free the inner data manually. 72 | ion_int_alloc(NULL, &iint); 73 | // Initialize the Ion integer, setting its owner to NULL. 74 | IONCHECK(ion_int_init(iint, NULL)); 75 | // Populate the Ion integer with the value of the provided base-10 string 76 | IONCHECK(ion_int_from_chars(iint, p_chars, string_length)); 77 | // Attempt to read the Ion integer's value back out into the int64_t. 78 | // If the number is outside the range of values that can be represented by 79 | // an int64_t, this should return IERR_NUMERIC_OVERFLOW. 80 | IONCHECK(ion_int_to_int64(iint, &value_out)); 81 | 82 | fail: 83 | ion_int_free(iint); 84 | 85 | RETURN(__location_name__, __line__, __count__++, err); 86 | } 87 | 88 | TEST(IonInteger, IIntToInt64Overflow) { 89 | // This test verifies that the `ion_int_to_int64` method will return IERR_NUMERIC_OVERFLOW 90 | // if the provided Ion integer's value will not fit in an int64_t. Because any Ion integer 91 | // constructed using `ion_int_from_long` will inherently fit in an int64_t, we instead 92 | // construct each Ion integer with `ion_int_from_chars`, passing in Ion text encodings 93 | // of the integers to create. 94 | const uint32_t number_of_ok_values = 9; 95 | const char *small_integers[number_of_ok_values] = { 96 | "-10004991088", 97 | "-9862", 98 | "-138", 99 | "-1", 100 | "0", 101 | "1", 102 | "138", 103 | "9862", 104 | "10004991088" 105 | }; 106 | 107 | // Each of the above values will fit in an int64_t, so the test function should succeed. 108 | for (int m = 0; m < number_of_ok_values; m++) { 109 | const char *small_integer = small_integers[m]; 110 | ION_ASSERT_OK(test_ion_int_to_int64_t_overflow_detection(small_integer)); 111 | } 112 | 113 | const uint32_t number_of_oversized_values = 4; 114 | const char *oversized_integers[number_of_oversized_values] = { 115 | "9223372036854775808", // MAX_INT64 + 1 116 | "-9223372036854775809", // MIN_INT64 - 1 117 | "10004991088252643637337337422", 118 | "-10004991088252643637337337422", 119 | }; 120 | 121 | // Each of the above values has a magnitude that is too large to fit in an int64_t, 122 | // so the test function should fail, returning IERR_NUMERIC_OVERFLOW. 123 | for (int m = 0; m < number_of_oversized_values; m++) { 124 | const char *oversized_integer = oversized_integers[m]; 125 | iERR error_value = test_ion_int_to_int64_t_overflow_detection(oversized_integer); 126 | ASSERT_EQ(error_value, IERR_NUMERIC_OVERFLOW); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /test/test_ion_values.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include "ion_assert.h" 16 | #include "ion_helpers.h" 17 | #include "ion_test_util.h" 18 | #include "ion_event_equivalence.h" 19 | 20 | iERR test_stream_handler(struct _ion_user_stream *pstream) { 21 | iENTER; 22 | _ion_user_stream *next_stream = (_ion_user_stream *)pstream->handler_state; 23 | if (next_stream) { 24 | memcpy(pstream, next_stream, sizeof(_ion_user_stream)); 25 | } 26 | else { 27 | FAILWITH(IERR_UNEXPECTED_EOF); 28 | } 29 | iRETURN; 30 | } 31 | 32 | TEST(IonUserStream, SucceedsInTheMiddleOfAValue) { 33 | const char *chunk1 = "{\"foo\": \"ba"; 34 | const char *chunk2 = "r\"}"; 35 | _ion_user_stream chunk1_stream, chunk2_stream; 36 | chunk1_stream.curr = (BYTE *)chunk1; 37 | chunk1_stream.limit = (BYTE *)(chunk1 + strlen(chunk1)); 38 | chunk1_stream.handler_state = &chunk2_stream; 39 | chunk1_stream.handler = &test_stream_handler; 40 | chunk2_stream.curr = (BYTE *)chunk2; 41 | chunk2_stream.limit = (BYTE *)(chunk2 + strlen(chunk2)); 42 | chunk2_stream.handler_state = NULL; 43 | chunk2_stream.handler = &test_stream_handler; 44 | 45 | ION_STREAM *ion_stream = NULL; 46 | hREADER reader; 47 | ION_TYPE type; 48 | ION_STRING value; 49 | ION_ASSERT_OK(ion_stream_open_handler_in(test_stream_handler, &chunk1_stream, &ion_stream)); 50 | ION_ASSERT_OK(ion_reader_open(&reader, ion_stream, NULL)); 51 | ION_ASSERT_OK(ion_reader_next(reader, &type)); 52 | ASSERT_EQ(tid_STRUCT, type); 53 | ION_ASSERT_OK(ion_reader_step_in(reader)); 54 | ION_ASSERT_OK(ion_reader_next(reader, &type)); 55 | ASSERT_EQ(tid_STRING, type); 56 | ION_ASSERT_OK(ion_reader_get_field_name(reader, &value)); 57 | ASSERT_EQ(0, strncmp("foo", (char *)value.value, value.length)); 58 | ION_ASSERT_OK(ion_reader_read_string(reader, &value)); 59 | ASSERT_EQ(0, strncmp("bar", (char *)value.value, value.length)); 60 | ION_ASSERT_OK(ion_reader_step_out(reader)); 61 | 62 | ION_ASSERT_OK(ion_reader_close(reader)); 63 | ION_ASSERT_OK(ion_stream_close(ion_stream)); 64 | } 65 | -------------------------------------------------------------------------------- /test/test_ion_writer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | #include "ion_assert.h" 18 | #include "ion_event_stream.h" 19 | #include "ion_helpers.h" 20 | #include "ion_test_util.h" 21 | 22 | class WriterTest : public ::testing::Test { 23 | protected: 24 | void SetUp() { 25 | out = tmpfile(); 26 | } 27 | 28 | void TearDown() { 29 | fclose(out); 30 | } 31 | 32 | FILE *out; 33 | }; 34 | 35 | iERR ion_test_open_file_writer(hWRITER *writer, FILE *out, BOOL is_binary, ION_STREAM **stream) { 36 | iENTER; 37 | ION_WRITER_OPTIONS options; 38 | ION_STREAM *ion_stream = NULL; 39 | 40 | ion_event_initialize_writer_options(&options); 41 | options.output_as_binary = is_binary; 42 | 43 | IONCHECK(ion_stream_open_file_out(out, &ion_stream)); 44 | IONCHECK(ion_writer_open(writer, ion_stream, &options)); 45 | 46 | *stream = ion_stream; 47 | 48 | iRETURN; 49 | } 50 | 51 | TEST_F(WriterTest, ResourcesNotLeakedOnWriteToTooSmallBuffer) 52 | { 53 | hWRITER writer = NULL; 54 | ION_WRITER_OPTIONS options; 55 | ion_event_initialize_writer_options(&options); 56 | options.output_as_binary = true; 57 | 58 | uint8_t buf[1]; 59 | SIZE len; 60 | 61 | ion_writer_open_buffer(&writer, buf, sizeof(buf), &options); 62 | ion_writer_write_int32(writer, 1); 63 | ion_writer_finish(writer, &len); 64 | 65 | ASSERT_EQ(IERR_BUFFER_TOO_SMALL, ion_writer_close(writer)); 66 | } 67 | 68 | TEST_F(WriterTest, BinaryWriterCloseMustFlushStream) { 69 | hWRITER writer = NULL; 70 | ION_STREAM *stream = NULL; 71 | 72 | long file_size; 73 | 74 | ion_test_open_file_writer(&writer, out, TRUE, &stream); 75 | 76 | ION_ASSERT_OK(ion_writer_write_bool(writer, TRUE)); 77 | 78 | ION_ASSERT_OK(ion_writer_close(writer)); 79 | 80 | ION_ASSERT_OK(ion_stream_close(stream)); 81 | 82 | // get the size of the file after closing the writer 83 | fseek(out, 0L, SEEK_END); 84 | file_size = ftell(out); 85 | 86 | // 4 bytes for the IVM 1 byte for Ion bool 87 | ASSERT_EQ(file_size, 4 + 1); 88 | } 89 | 90 | TEST_F(WriterTest, TextWriterCloseMustFlushStream) { 91 | hWRITER writer = NULL; 92 | ION_STREAM *stream = NULL; 93 | 94 | long file_size; 95 | 96 | ion_test_open_file_writer(&writer, out, FALSE, &stream); 97 | 98 | ION_ASSERT_OK(ion_writer_write_bool(writer, TRUE)); 99 | 100 | ION_ASSERT_OK(ion_writer_close(writer)); 101 | ION_ASSERT_OK(ion_stream_close(stream)); 102 | 103 | // get the size of the file after closing the writer 104 | fseek(out, 0L, SEEK_END); 105 | file_size = ftell(out); 106 | 107 | ASSERT_EQ(file_size, 4); 108 | } 109 | -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | option(IONC_BENCHMARKING_ENABLED "Enable ion-bench build" OFF) 2 | 3 | add_subdirectory(ionizer) 4 | add_subdirectory(ionsymbols) 5 | add_subdirectory(events) 6 | add_subdirectory(cli) 7 | if (IONC_BENCHMARKING_ENABLED) 8 | add_subdirectory(ion-bench) 9 | endif() 10 | -------------------------------------------------------------------------------- /tools/cli/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # C++ standard 3 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 4 | set(CMAKE_CXX_EXTENSIONS OFF) 5 | if(NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 11) 6 | set(CMAKE_CXX_STANDARD 11) 7 | endif() 8 | 9 | 10 | # The public executable. 11 | add_executable(ion main.cpp argtable/argtable3.c cli.cpp) 12 | 13 | target_include_directories(ion 14 | PRIVATE 15 | ./ 16 | ../events 17 | ../events/inc 18 | ../../ionc 19 | ../../ionc/include 20 | argtable) 21 | 22 | target_link_libraries(ion ionc ion_events) 23 | 24 | # A static library version of `ion` that does not include a main() 25 | # function, allowing other programs to wrap it. 26 | add_library(ion_cli_main STATIC main.cpp argtable/argtable3.c cli.cpp) 27 | target_compile_definitions(ion_cli_main PUBLIC EXTERNAL_DRIVER) 28 | target_include_directories(ion_cli_main 29 | PRIVATE 30 | ./ 31 | ../events 32 | ../events/inc 33 | ../../ionc 34 | ../../ionc/include 35 | argtable) 36 | target_link_libraries(ion_cli_main ionc ion_events) 37 | 38 | 39 | # A library for testing. 40 | add_library(ion_cli cli.cpp) 41 | target_include_directories(ion_cli 42 | PRIVATE 43 | ./ 44 | ../events 45 | ../../ionc 46 | ../../ionc/include 47 | ../events/inc) 48 | target_link_libraries(ion_cli ionc ion_events) 49 | -------------------------------------------------------------------------------- /tools/cli/cli.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef IONC_CLI_H 16 | #define IONC_CLI_H 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "ion_event_equivalence.h" 24 | #include "ion_event_util.h" 25 | #include "ion_event_stream_impl.h" 26 | #include "ion_catalog_impl.h" 27 | #include "ion_helpers.h" 28 | 29 | #define ION_CLI_VERSION "1.0" 30 | #define ION_CLI_PNAME "ion" 31 | 32 | typedef enum _ion_cli_input_format { 33 | IO_TYPE_FILE = 0, 34 | IO_TYPE_CONSOLE, 35 | IO_TYPE_MEMORY 36 | } ION_CLI_IO_TYPE; 37 | 38 | /** 39 | * Describes an input to or output from a CLI command. 40 | */ 41 | class IonCliIO { 42 | public: 43 | ION_CLI_IO_TYPE type; 44 | std::string contents; 45 | 46 | IonCliIO(){ 47 | this->type = IO_TYPE_FILE; 48 | } 49 | 50 | IonCliIO(std::string contents, ION_CLI_IO_TYPE type=IO_TYPE_FILE) { 51 | this->contents = contents; 52 | this->type = type; 53 | } 54 | }; 55 | 56 | /** 57 | * Arguments shared by the process, compare, and extract commands. 58 | */ 59 | class IonCliCommonArgs { 60 | public: 61 | IonCliIO output; 62 | IonCliIO error_report; 63 | ION_EVENT_OUTPUT_TYPE output_format; 64 | std::vector catalogs; 65 | std::vector input_files; 66 | 67 | IonCliCommonArgs() { 68 | output_format = OUTPUT_TYPE_TEXT_PRETTY; 69 | } 70 | }; 71 | 72 | /** 73 | * Arguments specific to the process command. 74 | */ 75 | class IonCliProcessArgs { 76 | public: 77 | IonCliIO perf_report; 78 | std::string filter; 79 | IonCliIO traverse; 80 | std::vector imports; 81 | 82 | IonCliProcessArgs() {} 83 | }; 84 | 85 | iERR ion_cli_command_compare(IonCliCommonArgs *common_args, ION_EVENT_COMPARISON_TYPE comparison_type, 86 | ION_STRING *output, IonEventReport *report); 87 | 88 | iERR ion_cli_command_process(IonCliCommonArgs *common_args, IonCliProcessArgs *process_args, ION_STRING *output, 89 | IonEventReport *report); 90 | 91 | iERR ion_cli_write_error_report(IonEventReport *report, IonCliCommonArgs *common_args); 92 | 93 | /** 94 | * Accepts the `output` parameter to an `ion_cli_command_*` function 95 | * and frees any memory allocated during that function. NOTE: if 96 | * `output` itself was dynamically allocated, it remains the caller's 97 | * responsibility to free it. 98 | */ 99 | void ion_cli_free_command_output(ION_STRING *output); 100 | 101 | #endif //IONC_CLI_H 102 | -------------------------------------------------------------------------------- /tools/events/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(ion_events 2 | ion_event_util.cpp 3 | ion_event_stream.cpp 4 | ion_event_equivalence.cpp) 5 | 6 | target_include_directories(ion_events 7 | PUBLIC 8 | ${CMAKE_CURRENT_SOURCE_DIR}/inc 9 | PRIVATE 10 | ${CMAKE_CURRENT_SOURCE_DIR} 11 | ${CMAKE_CURRENT_SOURCE_DIR}/../../ionc 12 | ${CMAKE_CURRENT_SOURCE_DIR}/../../ionc/include 13 | ) 14 | 15 | target_link_libraries(ion_events ionc) 16 | 17 | add_library(ion_events_static STATIC 18 | ion_event_util.cpp 19 | ion_event_stream.cpp 20 | ion_event_equivalence.cpp) 21 | 22 | target_include_directories(ion_events_static 23 | PUBLIC 24 | ${CMAKE_CURRENT_SOURCE_DIR}/inc 25 | PRIVATE 26 | ${CMAKE_CURRENT_SOURCE_DIR} 27 | ${CMAKE_CURRENT_SOURCE_DIR}/../../ionc 28 | ${CMAKE_CURRENT_SOURCE_DIR}/../../ionc/include 29 | ) 30 | 31 | target_link_libraries(ion_events_static ionc) 32 | -------------------------------------------------------------------------------- /tools/events/inc/ion_event_equivalence.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef IONC_ION_EVENT_EQUIVALENCE_H 16 | #define IONC_ION_EVENT_EQUIVALENCE_H 17 | 18 | #include 19 | #include 20 | #include "ion_event_stream.h" 21 | 22 | typedef enum _ion_event_comparison_type { 23 | COMPARISON_TYPE_EQUIVS = 0, 24 | COMPARISON_TYPE_NONEQUIVS, 25 | COMPARISON_TYPE_BASIC, 26 | COMPARISON_TYPE_EQUIVTIMELINE, 27 | COMPARISON_TYPE_UNKNOWN 28 | } ION_EVENT_COMPARISON_TYPE; 29 | 30 | /** 31 | * Tests the given IonEventStreams for equivalence, meaning that the corresponding values in each stream 32 | * must all be equivalent. 33 | */ 34 | BOOL ion_compare_streams(IonEventStream *stream_expected, IonEventStream *stream_actual, IonEventResult *result = NULL); 35 | 36 | /** 37 | * Compares the comparison sets contained in the given stream based on the given comparison type. A comparison set 38 | * is a top-level sequence type (list or s-expression) that contains values or embedded streams that will be compared 39 | * for equivalence or non-equivalence against all other values or embedded streams in that sequence. 40 | */ 41 | BOOL ion_compare_sets(IonEventStream *stream_expected, IonEventStream *stream_actual, 42 | ION_EVENT_COMPARISON_TYPE comparison_type, IonEventResult *result = NULL); 43 | 44 | // Equivalence checks. If the optional failure_message output parameter is supplied and the given values are not 45 | // equivalent, failure_message will be populated with a message explaining why. If the optional result output parameter 46 | // is supplied, it will be populated with an IonEventErrorDescription if an error occurs during the comparison. If an 47 | // error occurs, the function will always return FALSE. 48 | 49 | BOOL ion_equals_bool(BOOL *expected, BOOL *actual, std::string *failure_message = NULL, IonEventResult *result = NULL); 50 | 51 | 52 | BOOL ion_equals_string(ION_STRING *expected, ION_STRING *actual, std::string *failure_message = NULL, 53 | IonEventResult *result = NULL); 54 | 55 | 56 | BOOL ion_equals_symbol(ION_SYMBOL *expected, ION_SYMBOL *actual, std::string *failure_message = NULL, 57 | IonEventResult *result = NULL); 58 | 59 | 60 | BOOL ion_equals_int(ION_INT *expected, ION_INT *actual, std::string *failure_message = NULL, 61 | IonEventResult *result = NULL); 62 | 63 | 64 | BOOL ion_equals_decimal(ION_DECIMAL *expected, ION_DECIMAL *actual, std::string *failure_message = NULL, 65 | IonEventResult *result = NULL); 66 | 67 | 68 | BOOL ion_equals_float(double *expected, double *actual, std::string *failure_message = NULL, 69 | IonEventResult *result = NULL); 70 | 71 | /** 72 | * Uses ion_timestamp_equals as the comparison method. 73 | */ 74 | BOOL ion_equals_timestamp(ION_TIMESTAMP *expected, ION_TIMESTAMP *actual, std::string *failure_message = NULL, 75 | IonEventResult *result = NULL); 76 | 77 | /** 78 | * Uses ion_timestamp_instant_equals as the comparison method. 79 | */ 80 | BOOL ion_equals_timestamp_instant(ION_TIMESTAMP *expected, ION_TIMESTAMP *actual, std::string *failure_message, 81 | IonEventResult *ION_RESULT_ARG); 82 | 83 | #endif //IONC_ION_EVENT_EQUIVALENCE_H 84 | -------------------------------------------------------------------------------- /tools/ion-bench/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | option(BUILD_TESTING "" OFF) 4 | set(BUILD_SHARED_LIBS OFF) 5 | option(MSGPACK_BUILD_TESTS "" OFF) 6 | 7 | set(CMAKE_CXX_EXTENSIONS OFF) 8 | set(CMAKE_CXX_STANDARD 17) 9 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 10 | set(BENCHMARK_ENABLE_GTEST_TESTS OFF) 11 | 12 | # We currently need std::filesystem to build IonCBench. 13 | Include(CheckCXXSourceCompiles) 14 | check_cxx_source_compiles( 15 | "#include \nint main(int argc, char **argv) { return 0; }" 16 | CXX_FILESYSTEM_SUPPORTED 17 | ) 18 | 19 | if (CXX_FILESYSTEM_SUPPORTED) 20 | add_subdirectory(deps/google-benchmark EXCLUDE_FROM_ALL) 21 | add_subdirectory(deps/json-c EXCLUDE_FROM_ALL) 22 | add_subdirectory(deps/libcbor EXCLUDE_FROM_ALL) 23 | add_subdirectory(deps/msgpack-c EXCLUDE_FROM_ALL) 24 | add_subdirectory(deps/yyjson EXCLUDE_FROM_ALL) 25 | add_subdirectory(src) 26 | else() 27 | message("NOTE: C++17, or at least std::filesystem not supported, cannot build IonCBench") 28 | endif() 29 | -------------------------------------------------------------------------------- /tools/ion-bench/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | set(CMAKE_CXX_VISIBILITY_PRESET hidden) 4 | set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) 5 | 6 | set(SOURCES main.cpp common.cc ../../cli/argtable/argtable3.c) 7 | if (TRACK_MEMORY) 8 | list(APPEND SOURCES memory.c) 9 | endif() 10 | 11 | add_executable(IonCBench ${SOURCES}) 12 | set_property(TARGET IonCBench 13 | PROPERTY CXX_STANDARD 17 14 | ) 15 | set_property(TARGET IonCBench 16 | PROPERTY CXX_STANDARD_REQUIRED ON 17 | ) 18 | target_compile_features(IonCBench PRIVATE cxx_std_17) 19 | target_include_directories(IonCBench PRIVATE ${libcbor_BINARY_DIR} ../../cli/argtable/) 20 | target_link_libraries(IonCBench 21 | benchmark::benchmark 22 | objlib 23 | m 24 | decNumber_static 25 | yyjson 26 | msgpack-c 27 | json-c 28 | cbor 29 | ) 30 | -------------------------------------------------------------------------------- /tools/ion-bench/src/benchmarks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "benchmark/benchmark.h" 4 | 5 | // A deserialization benchmark that materializes every item in the dataset. 6 | struct deserialize_all { 7 | int operator()(benchmark::State &st, Library *l, const char *dataset, bool pretty) { 8 | size_t total_bytes = 0; 9 | ValueStats stats = {0}; 10 | DataLoader data(dataset); 11 | 12 | for (auto _ : st) { 13 | auto vals = l->deserialize(data.buffer(), data.length()); 14 | total_bytes += data.length(); 15 | stats += vals; 16 | } 17 | st.counters["Bps"] = benchmark::Counter(total_bytes, benchmark::Counter::kIsRate); 18 | st.counters["objs"] = benchmark::Counter(stats.num_objs); 19 | st.counters["bools"] = benchmark::Counter(stats.num_bools); 20 | st.counters["strs"] = benchmark::Counter(stats.num_strs); 21 | st.counters["nulls"] = benchmark::Counter(stats.num_nulls); 22 | st.counters["nums"] = benchmark::Counter(stats.num_nums); 23 | return 0; 24 | } 25 | }; 26 | 27 | // A serialization benchmark that first reads the dataset into an in-memory format, and then 28 | // serializes everything into a new representation. 29 | struct serialize_all { 30 | int operator()(benchmark::State &st, Library *l, const char *dataset, bool pretty) { 31 | ValueStats stats = {0}; 32 | DataLoader data(dataset); 33 | 34 | st.SetLabel(l->name()); 35 | 36 | l->load_data(data.buffer(), data.length()); 37 | size_t buffer_size = l->data_size() * 2; 38 | 39 | // TODO: Let the implementation determine this. 40 | uint8_t *buffer = new uint8_t[buffer_size]; 41 | size_t output_size = 0; 42 | 43 | for (auto _ : st) { 44 | output_size = buffer_size; 45 | auto iter_stats = l->serialize_loaded_data(buffer, output_size, pretty); 46 | stats += iter_stats; 47 | } 48 | 49 | delete[] buffer; 50 | 51 | st.counters["Bps"] = benchmark::Counter(stats.serde_bytes, benchmark::Counter::kIsRate, benchmark::Counter::OneK::kIs1024); 52 | st.counters["objs"] = benchmark::Counter(stats.num_objs); 53 | st.counters["bools"] = benchmark::Counter(stats.num_bools); 54 | st.counters["strs"] = benchmark::Counter(stats.num_strs); 55 | st.counters["nulls"] = benchmark::Counter(stats.num_nulls); 56 | st.counters["nums"] = benchmark::Counter(stats.num_nums); 57 | return 0; 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /tools/ion-bench/src/common.cc: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace fs = std::filesystem; 9 | 10 | size_t file_size(const char *path) { 11 | struct stat filestat; 12 | 13 | if (0 == stat(path, &filestat)) { 14 | return filestat.st_size; 15 | } 16 | 17 | return 0; 18 | } 19 | 20 | void read_file(FILE *file, uint8_t *buffer, size_t size) { 21 | size_t offset = 0; 22 | size_t read = 0; 23 | do { 24 | read = fread(buffer+offset, 1, size - offset, file); 25 | offset += read; 26 | } while (read != 0); 27 | } 28 | 29 | void DataLoader::load_data(char const *full_path) { 30 | FILE *f = nullptr; 31 | if (NULL != (f = fopen(full_path, "r"))) { 32 | int fd = fileno(f); 33 | struct stat filestat; 34 | 35 | if (0 == fstat(fd, &filestat)) { 36 | _buffer = new uint8_t[filestat.st_size]; 37 | _length = filestat.st_size; 38 | read_file(f, _buffer, _length); 39 | } else { 40 | printf("ERROR: Unable to get file size.\n"); 41 | exit(1); 42 | } 43 | 44 | fclose(f); 45 | } else { 46 | printf("ERROR: Unable to open %s\n", full_path); 47 | exit(1); 48 | } 49 | } 50 | 51 | DataLoader::DataLoader(char const *full_path) : _buffer(nullptr) { 52 | load_data(full_path); 53 | } 54 | 55 | DataLoader::DataLoader(char const *dataset, char const *suffix, Format format) : _buffer(nullptr) { 56 | // Path should be: ./data//.[min.] 57 | fs::path datapath = fs::path("data") / fs::path(dataset) / fs::path(dataset); 58 | switch (format) { 59 | case Format::Pretty: 60 | datapath += std::string(".pretty"); 61 | break; 62 | case Format::Compact: 63 | datapath += std::string(".min"); 64 | break; 65 | case Format::Binary: 66 | break; 67 | } 68 | datapath += std::string(".") + suffix; 69 | load_data(datapath.c_str()); 70 | } 71 | 72 | DataLoader::~DataLoader() { 73 | delete[] _buffer; 74 | } 75 | -------------------------------------------------------------------------------- /tools/ion-bench/src/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | enum Format { 13 | Pretty, 14 | Compact, 15 | Binary 16 | }; 17 | 18 | class DataLoader { 19 | private: 20 | uint8_t *_buffer; 21 | size_t _length; 22 | public: 23 | DataLoader(char const *full_path); 24 | DataLoader(char const *path, char const *suffix, Format format); 25 | ~DataLoader(); 26 | void load_data(char const *full_path); 27 | uint8_t *buffer() const { return _buffer; } 28 | size_t length() const { return _length; } 29 | }; 30 | 31 | struct ValueStats { 32 | uint64_t num_objs; 33 | uint64_t num_bools; 34 | uint64_t num_strs; 35 | uint64_t num_nulls; 36 | uint64_t num_nums; 37 | uint64_t num_lists; 38 | uint64_t str_size; 39 | uint64_t serde_bytes; 40 | 41 | void operator+=(ValueStats &other) { 42 | num_objs += other.num_objs; 43 | num_bools += other.num_bools; 44 | num_strs += other.num_strs; 45 | num_nulls += other.num_nulls; 46 | num_nums += other.num_nums; 47 | num_lists += other.num_lists; 48 | str_size += other.str_size; 49 | serde_bytes += other.serde_bytes; 50 | } 51 | }; 52 | 53 | 54 | template 55 | struct TapeData { 56 | T tpe; 57 | bool end_of_container; 58 | size_t container_size; // Used only for msgpack currently. 59 | std::optional value; 60 | std::optional field_name; 61 | 62 | TapeData(T tpe) : tpe(tpe), end_of_container(false), value(std::nullopt), field_name(std::nullopt) {} 63 | TapeData &with_field_name(const std::optional &name) { field_name = name; return *this; } 64 | TapeData &with_value(const std::optional &val) { value = val; return *this; } 65 | TapeData &with_container_size(size_t s) { container_size = s; return *this; } 66 | TapeData that_closes() { end_of_container = true; return *this; } 67 | }; 68 | 69 | template 70 | using Tape = std::vector>; 71 | 72 | template 73 | using TapeItr = typename Tape::iterator; 74 | 75 | class Library { 76 | public: 77 | virtual const char *name() const = 0; 78 | virtual ValueStats deserialize(uint8_t *input, size_t in_size) = 0; 79 | virtual void load_data(uint8_t *input, size_t in_size) = 0; 80 | virtual size_t data_size() const = 0; 81 | virtual ValueStats serialize_loaded_data(uint8_t *output, size_t &len, bool pretty) = 0; 82 | }; 83 | 84 | // Very basic typelist for holding our registered library implementations. 85 | template 86 | struct typelist {}; 87 | 88 | template typename func, typename head> 89 | void for_list(typelist &list) { 90 | func f; 91 | f(); 92 | } 93 | 94 | template class func, typename first, typename second, typename... rest> 95 | void for_list(typelist &list) { 96 | func f; 97 | f(); 98 | typelist remaining; 99 | for_list(remaining); 100 | } 101 | 102 | template class func, typename first, typename second, typename... rest> 103 | void list_until(typelist &list) { 104 | } 105 | -------------------------------------------------------------------------------- /tools/ion-bench/src/ion/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(IonCBench PRIVATE 2 | writing.cc 3 | ) 4 | -------------------------------------------------------------------------------- /tools/ion-bench/src/ion/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "ionc/ion.h" 8 | 9 | #include "../common.h" 10 | 11 | namespace ion { 12 | 13 | enum class Format { 14 | Text, 15 | Binary, 16 | JSON, 17 | }; 18 | 19 | constexpr bool is_text(Format f) { 20 | return f != Format::Binary; 21 | } 22 | 23 | struct IonData { 24 | int64_t tpe; 25 | bool null_container; 26 | std::optional field_name; 27 | std::optional value; 28 | std::vector annotations; 29 | }; 30 | 31 | inline void print_iondata(const IonData &data) { 32 | printf("[IONDATA] tpe:0x%.4lX field_name:%s", 33 | data.tpe, 34 | data.field_name.value_or("none").c_str() 35 | ); 36 | auto annots = std::accumulate(data.annotations.begin(), data.annotations.end(), std::string(), 37 | [](const std::string &a, const std::string &b) -> std::string { 38 | return a + (a.length() > 0 ? "," : "") + b; 39 | } 40 | ); 41 | printf(" value:"); 42 | if (!data.value.has_value()) printf("none"); 43 | else { 44 | if (data.value->type() == typeid(std::string)) 45 | printf("\"%s\"", std::any_cast(data.value.value()).c_str()); 46 | } 47 | printf(" annotations:[%s]\n", annots.c_str()); 48 | } 49 | 50 | struct IonDecimalDeleter { 51 | void operator()(ION_DECIMAL *d) { 52 | ion_decimal_free(d); 53 | free(d); 54 | } 55 | }; 56 | 57 | typedef std::shared_ptr IonDecimalPtr; 58 | typedef struct { std::string value; } Symbol; 59 | } 60 | -------------------------------------------------------------------------------- /tools/ion-bench/src/ion/writing.cc: -------------------------------------------------------------------------------- 1 | #include "writing.h" 2 | 3 | namespace ion { 4 | 5 | 6 | } 7 | -------------------------------------------------------------------------------- /tools/ion-bench/src/json/common.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __JSON_COMMON_H__ 3 | #define __JSON_COMMON_H__ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace json { 10 | 11 | template 12 | struct JsonData { 13 | T tpe; 14 | bool end_of_container; 15 | std::optional value; 16 | std::optional field_name; 17 | 18 | JsonData(T tpe) : tpe(tpe), end_of_container(false), value(std::nullopt), field_name(std::nullopt) {} 19 | JsonData &with_field_name(const std::optional &name) { field_name = name; return *this; } 20 | JsonData &with_value(const std::optional &val) { value = val; return *this; } 21 | JsonData that_closes() { end_of_container = true; return *this; } 22 | }; 23 | 24 | } 25 | 26 | #endif /* __JSON_COMMON_H__ */ 27 | -------------------------------------------------------------------------------- /tools/ion-bench/src/memory.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #if defined(__MACH__) 7 | # include 8 | #elif defined(__linux__) 9 | # include 10 | # define malloc_size(x) malloc_usable_size(x) 11 | #endif 12 | 13 | #include "memory.h" 14 | 15 | // This is not threadsafe. We should not be executing benchmarks using 16 | // multiple threads. This should only be included in a build where we 17 | // want to track memory usage. Which should be handled by our CMake 18 | // config. 19 | 20 | 21 | struct memory_usage MEMUSAGE = { 22 | .alloc = 0, 23 | .current= 0, 24 | .freed = 0, 25 | .high = 0, 26 | .low = 0, 27 | }; 28 | 29 | extern void *__libc_malloc(size_t size); 30 | extern void *__libc_calloc(size_t n, size_t size); 31 | extern void *__libc_realloc(void *oldmem, size_t bytes); 32 | extern void __libc_free(void *ptr); 33 | 34 | void *malloc_hook(size_t size); 35 | void free_hook(void *ptr); 36 | 37 | int hook_active = 0; 38 | 39 | void start_memusage() { 40 | hook_active = 1; 41 | } 42 | 43 | void stop_memusage() { 44 | hook_active = 0; 45 | } 46 | 47 | extern void *malloc(size_t size) { 48 | if (hook_active == 1) { 49 | return malloc_hook(size); 50 | } else { 51 | return __libc_malloc(size); 52 | } 53 | } 54 | 55 | void *malloc_hook(size_t size) { 56 | hook_active = 0; 57 | 58 | void *ptr = __libc_malloc(size); 59 | size_t alloc_size = malloc_size(ptr); 60 | 61 | MEMUSAGE.alloc += alloc_size; 62 | MEMUSAGE.current += alloc_size; 63 | 64 | if (MEMUSAGE.current > MEMUSAGE.high) { 65 | MEMUSAGE.high = MEMUSAGE.current; 66 | } 67 | 68 | if (MEMUSAGE.low == 0) 69 | MEMUSAGE.low = MEMUSAGE.current; 70 | // printf("[MEM] malloc(%lu) alloc:%lu hi:%lu lo:%lu current:%lu\n", size, alloc_size, MEMUSAGE.high, MEMUSAGE.low, MEMUSAGE.current); 71 | hook_active = 1; 72 | return ptr; 73 | } 74 | 75 | void *calloc_hook(size_t n, size_t size) { 76 | hook_active = 0; 77 | 78 | void *ptr = __libc_calloc(n, size); 79 | size_t alloc_size = malloc_size(ptr); 80 | 81 | MEMUSAGE.alloc += alloc_size; 82 | MEMUSAGE.current += alloc_size; 83 | 84 | if (MEMUSAGE.current > MEMUSAGE.high) { 85 | MEMUSAGE.high = MEMUSAGE.current; 86 | } 87 | 88 | if (MEMUSAGE.low == 0) 89 | MEMUSAGE.low = MEMUSAGE.current; 90 | 91 | hook_active = 1; 92 | return ptr; 93 | } 94 | 95 | extern void *calloc(size_t n, size_t size) { 96 | if (hook_active == 1) { 97 | return calloc_hook(n, size); 98 | } else { 99 | return __libc_calloc(n, size); 100 | } 101 | } 102 | 103 | extern void free(void *ptr) { 104 | if (hook_active == 1) { 105 | free_hook(ptr); 106 | } else { 107 | __libc_free(ptr); 108 | } 109 | } 110 | 111 | void free_hook(void *ptr) { 112 | hook_active = 0; 113 | if (ptr != NULL) { 114 | size_t size = malloc_size(ptr); 115 | 116 | size_t old_current = MEMUSAGE.current; 117 | 118 | MEMUSAGE.freed += size; 119 | MEMUSAGE.current -= size; 120 | 121 | // Detecting underflow, JIC we missed something.. like an allocation, or re-allocation. 122 | if (MEMUSAGE.current > old_current) { 123 | printf("[FREE] UNDERFLOW old: %lu free'd: %lu\n", old_current, size); 124 | } 125 | 126 | if (MEMUSAGE.current < MEMUSAGE.low || MEMUSAGE.low == 0) { 127 | MEMUSAGE.low = MEMUSAGE.current; 128 | } 129 | 130 | __libc_free(ptr); 131 | // printf("[MEM] free(%lu) hi:%lu lo:%lu current:%lu\n", size, MEMUSAGE.high, MEMUSAGE.low, MEMUSAGE.current); 132 | } 133 | hook_active = 1; 134 | } 135 | 136 | void *realloc_hook(void *oldmem, size_t bytes) { 137 | hook_active = 0; 138 | 139 | size_t presize = malloc_size(oldmem); 140 | void *ptr = __libc_realloc(oldmem, bytes); 141 | size_t postsize = malloc_size(ptr); 142 | 143 | // Given our new size, we need to adjust.. 144 | long diff = (postsize - presize); 145 | MEMUSAGE.alloc += diff; 146 | MEMUSAGE.current += diff; 147 | if (MEMUSAGE.current > MEMUSAGE.high) 148 | MEMUSAGE.high = MEMUSAGE.current; 149 | if (MEMUSAGE.current < MEMUSAGE.low) 150 | MEMUSAGE.low = MEMUSAGE.current; 151 | 152 | // printf("[REALLOC] %p old: %lu new: %lu\n", oldmem, presize, postsize); 153 | 154 | hook_active = 1; 155 | return ptr; 156 | } 157 | 158 | extern void *realloc(void *oldmem, size_t bytes) { 159 | if (hook_active == 1 ) { 160 | return realloc_hook(oldmem, bytes); 161 | } else { 162 | return __libc_realloc(oldmem, bytes); 163 | } 164 | } 165 | 166 | 167 | void load_memusage(struct memory_usage *usage) { 168 | memcpy(usage, &MEMUSAGE, sizeof(struct memory_usage)); 169 | } 170 | 171 | void clear_memusage() { 172 | memset(&MEMUSAGE, 0, sizeof(struct memory_usage)); 173 | } 174 | -------------------------------------------------------------------------------- /tools/ion-bench/src/memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | struct memory_usage { 11 | size_t alloc; 12 | size_t current; 13 | size_t freed; 14 | size_t high; 15 | size_t low; 16 | }; 17 | 18 | void start_memusage(); 19 | void stop_memusage(); 20 | void load_memusage(struct memory_usage *usage); 21 | void clear_memusage(); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /tools/ionizer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_executable(ionizer 3 | ionizer_args.c 4 | ionizer.c 5 | ionizer_stream.c 6 | options.c 7 | ) 8 | set_property(TARGET ionizer PROPERTY C_STANDARD 99) 9 | target_include_directories(ionizer 10 | PRIVATE 11 | . 12 | ../../ionc 13 | ../../ionc/include 14 | ) 15 | 16 | if (MSVC) 17 | target_link_libraries(ionizer ionc) 18 | else() 19 | # Unix requires linking against lib m explicitly. 20 | target_link_libraries(ionizer ionc m) 21 | endif() 22 | 23 | -------------------------------------------------------------------------------- /tools/ionizer/ionizer_stream.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | // 16 | // helper routines for opening a stream and an ion reader or writer 17 | // 18 | 19 | #include "ionizer.h" 20 | #include "options.h" 21 | #include "memory.h" 22 | 23 | iERR ionizer_reader_open_fstream( 24 | FSTREAM_READER_STATE **p_read_helper, 25 | FILE *fp_in, 26 | ION_READER_OPTIONS *options 27 | ) { 28 | iENTER; 29 | FSTREAM_READER_STATE *read_helper = NULL; 30 | ION_STREAM *stream = NULL; 31 | hREADER hreader = 0; 32 | 33 | if (!fp_in || !p_read_helper) FAILWITH(IERR_INVALID_ARG); 34 | if (fp_in == stdout) { 35 | FAILWITH(IERR_INVALID_ARG); 36 | } 37 | 38 | read_helper = (FSTREAM_READER_STATE *)malloc(sizeof(FSTREAM_READER_STATE)); 39 | if (!read_helper) FAILWITH(IERR_NO_MEMORY); 40 | 41 | if (fp_in == stdin) { 42 | CHECK(ion_stream_open_stdin( &stream ), "opening a stream over stdin"); 43 | } 44 | else { 45 | CHECK(ion_stream_open_file_in( fp_in, &stream ), "opening an input stream"); 46 | } 47 | 48 | CHECK(ion_reader_open( &hreader, stream, options), "opening the ion reader"); 49 | 50 | read_helper->hreader = hreader; 51 | read_helper->in = stream; 52 | *p_read_helper = read_helper; 53 | SUCCEED(); 54 | 55 | fail: 56 | if (err != IERR_OK) { 57 | if (hreader) ion_reader_close(hreader); 58 | if (stream) ion_stream_close(stream); 59 | if (read_helper) free(read_helper); 60 | } 61 | return err; 62 | } 63 | 64 | iERR ionizer_reader_close_fstream( FSTREAM_READER_STATE *read_helper ) 65 | { 66 | iENTER; 67 | hREADER h = 0; 68 | ION_STREAM *s = NULL; 69 | FILE *f = NULL; 70 | 71 | if (!read_helper) FAILWITH(IERR_INVALID_ARG); 72 | 73 | if (read_helper->hreader) { 74 | h = read_helper->hreader; 75 | read_helper->hreader= 0; 76 | CHECK(ion_reader_close(h), "closing an ion writer"); 77 | } 78 | if (read_helper->in) { 79 | s = read_helper->in; 80 | read_helper->in = NULL; 81 | f = ion_stream_get_file_stream(s); 82 | CHECK(ion_stream_close(s), "closing an input stream"); 83 | if (f == stdin) { 84 | // DO NOTHING 85 | } 86 | else if (f == stdout) { 87 | // do nothing, but we shouldn't be here anyway 88 | } 89 | else { 90 | fclose(f); 91 | } 92 | } 93 | free(read_helper); 94 | SUCCEED(); 95 | 96 | 97 | iRETURN; 98 | } 99 | 100 | iERR ionizer_writer_open_fstream( 101 | FSTREAM_WRITER_STATE **p_write_helper, 102 | FILE *fp_out, 103 | ION_WRITER_OPTIONS *options) 104 | { 105 | iENTER; 106 | FSTREAM_WRITER_STATE *write_helper = NULL; 107 | ION_STREAM *stream = NULL; 108 | hWRITER hwriter = 0; 109 | 110 | if (!fp_out || !p_write_helper) FAILWITH(IERR_INVALID_ARG); 111 | if (fp_out == stdin) { 112 | FAILWITH(IERR_INVALID_ARG); 113 | } 114 | 115 | write_helper = (FSTREAM_WRITER_STATE *)malloc(sizeof(FSTREAM_WRITER_STATE)); 116 | if (!write_helper) FAILWITH(IERR_NO_MEMORY); 117 | 118 | if (fp_out == stdout) { 119 | CHECK(ion_stream_open_stdout( &stream ), "opening a stdout as stream"); 120 | } 121 | else { 122 | CHECK(ion_stream_open_file_out( fp_out, &stream ), "opening an output stream"); 123 | } 124 | 125 | CHECK(ion_writer_open( &hwriter, stream, options), "opening the ion writer"); 126 | 127 | write_helper->hwriter = hwriter; 128 | write_helper->out = stream; 129 | *p_write_helper = write_helper; 130 | SUCCEED(); 131 | 132 | fail: 133 | if (err != IERR_OK) { 134 | if (hwriter) ion_writer_close(hwriter); 135 | if (stream) ion_stream_close(stream); 136 | if (write_helper) free(write_helper); 137 | } 138 | return err; 139 | 140 | } 141 | 142 | iERR ionizer_writer_close_fstream( FSTREAM_WRITER_STATE *write_helper ) 143 | { 144 | iENTER; 145 | hWRITER h; 146 | ION_STREAM *s; 147 | FILE *f; 148 | 149 | if (!write_helper) FAILWITH(IERR_INVALID_ARG); 150 | if (write_helper->hwriter) { 151 | h = write_helper->hwriter; 152 | write_helper->hwriter = 0; 153 | CHECK(ion_writer_close(h), "closing an ion writer"); 154 | } 155 | if (write_helper->out) { 156 | s = write_helper->out; 157 | write_helper->out = 0; 158 | f = ion_stream_get_file_stream(s); 159 | if (f == stdin) { 160 | // DO NOTHING 161 | } 162 | else if (f == stdout) { 163 | fflush(stdout); 164 | } 165 | else { 166 | fclose(f); 167 | } 168 | } 169 | free(write_helper); 170 | SUCCEED(); 171 | 172 | iRETURN; 173 | } 174 | 175 | -------------------------------------------------------------------------------- /tools/ionizer/options.h: -------------------------------------------------------------------------------- 1 | // 2 | // command line argument option processing routines 3 | // 4 | // Copyright (c) 2009 - Microquill Inc. - All rights reserved 5 | // Chris Suver 6 | // 7 | 8 | #ifndef OPTION_H_INCLUDED 9 | #define OPTION_H_INCLUDED 10 | 11 | #define OPT_MAX_INT_ARG_LEN 30 12 | 13 | #ifndef BOOL 14 | #define BOOL int 15 | #endif 16 | 17 | #ifndef GLOBAL 18 | #define GLOBAL extern 19 | #define OPT_INITTO(x) 20 | #endif 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef enum _opt_type { 27 | ot_none, 28 | ot_int, 29 | ot_string, 30 | ot_non_arg 31 | } OT; 32 | 33 | typedef struct _opt_cursor OC; 34 | typedef BOOL (*OPT_ARG_FN)(OC *pcur); 35 | 36 | typedef struct _opt_def { 37 | OT type; 38 | char short_name; 39 | char *long_name; 40 | BOOL hidden; 41 | BOOL required; 42 | OPT_ARG_FN fn; 43 | char *help; 44 | } OPT_DEF; 45 | 46 | typedef struct _opt_msg OPT_MSG; 47 | struct _opt_msg { 48 | char *msg; 49 | OPT_MSG *next; 50 | }; 51 | 52 | BOOL opt_process(OPT_DEF *opts, int opt_count, int argc, char **argv); // returns TRUE if ok, FALSE if there's a bad arg 53 | BOOL opt_process_return_non_args(OPT_DEF *opts, int opt_count, int argc, char **argv, char **p_non_argv, int *p_non_argc); // returns TRUE if ok, FALSE if there's a bad arg 54 | void opt_log_error_line(OC *cur, const char *msg); // sets options as in error and appends this string to the error message list for help (if the user calls help) 55 | void opt_help (OPT_DEF *opts, int opt_count, char *name, int version, char *title, char *copyright); 56 | char *opt_get_arg(OC *cur); 57 | #ifdef WIN 58 | OPT_MSG *opt_decode_wildcards(OPT_MSG *prev_head, char *name_with_wildcards); 59 | #endif 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /tools/ionsymbols/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_executable(ionsymbols 3 | ionsymbols_args.c 4 | ionsymbols.c 5 | options.c 6 | ) 7 | set_property(TARGET ionsymbols PROPERTY C_STANDARD 99) 8 | target_include_directories(ionsymbols 9 | PRIVATE 10 | . 11 | ../../ionc 12 | ../../ionc/include 13 | ) 14 | target_link_libraries(ionsymbols ionc) 15 | 16 | -------------------------------------------------------------------------------- /tools/ionsymbols/ionsymbols.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at: 7 | * 8 | * http://aws.amazon.com/apache2.0/ 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 12 | * language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | #ifdef IZ_INITIALIZE 22 | #define IZ_GLOBAL 23 | #define IZ_INITTO(x) = x 24 | #endif 25 | 26 | #ifndef IZ_GLOBAL 27 | #define IZ_GLOBAL extern 28 | #define IZ_INITTO(x) 29 | #endif 30 | 31 | #define APP_NAME "ionsymbols" 32 | 33 | #define MAX_FILE_NAME_LEN 1024 34 | 35 | typedef struct _str_node STR_NODE; 36 | struct _str_node { 37 | char *str; 38 | STR_NODE *next; 39 | }; 40 | 41 | IZ_GLOBAL BOOL g_include_counts IZ_INITTO(FALSE); 42 | 43 | IZ_GLOBAL BOOL g_verbose IZ_INITTO(FALSE); 44 | IZ_GLOBAL BOOL g_print_help IZ_INITTO(FALSE); 45 | IZ_GLOBAL BOOL g_debug IZ_INITTO(FALSE); 46 | IZ_GLOBAL BOOL g_dump_args IZ_INITTO(FALSE); 47 | IZ_GLOBAL BOOL g_timer IZ_INITTO(FALSE); 48 | 49 | IZ_GLOBAL char *g_update_symtab IZ_INITTO(NULL); 50 | 51 | #define UNDEFINED_SYMTAB_NAME ("unnamed_symbol_table") 52 | IZ_GLOBAL char *g_symtab_name IZ_INITTO(UNDEFINED_SYMTAB_NAME); 53 | 54 | #define UNDEFINED_VERSION_NUMBER (-1) 55 | IZ_GLOBAL int g_symtab_version IZ_INITTO(UNDEFINED_VERSION_NUMBER); 56 | 57 | IZ_GLOBAL STR_NODE *g_catalogs IZ_INITTO(NULL); 58 | 59 | 60 | #define CHECKREADER(fn, msg, reader) \ 61 | if ((err = (fn)) != IERR_OK ) { \ 62 | err = report_error(err, msg, reader, __FILE__, __LINE__); \ 63 | if (err) goto fail; \ 64 | } 65 | 66 | #define CHECK(fn, msg) \ 67 | if ((err = (fn)) != IERR_OK ) { \ 68 | err = report_error(err, msg, NULL, __FILE__, __LINE__); \ 69 | if (err) goto fail; \ 70 | } 71 | 72 | 73 | // globals for "real" state we'll be reusing here and there 74 | IZ_GLOBAL ION_STRING g_symbol_counts_str; 75 | IZ_GLOBAL hSYMTAB g_hsymtab IZ_INITTO(NULL); 76 | IZ_GLOBAL hCATALOG g_hcatalog IZ_INITTO(NULL); 77 | IZ_GLOBAL BOOL g_ion_debug_timer IZ_INITTO(FALSE); 78 | 79 | IZ_GLOBAL ION_READER_OPTIONS g_reader_options; 80 | IZ_GLOBAL ION_WRITER_OPTIONS g_writer_options; 81 | 82 | 83 | // 84 | // in ionsymbols.c 85 | // 86 | iERR process_filename(char *pathname, ION_READER_OPTIONS *options); 87 | iERR process_one_file(char *filename, ION_READER_OPTIONS *options); 88 | iERR process_input_reader(hREADER hreader); 89 | 90 | iERR load_symbol_table(hSYMTAB *p_hsymtab, char *symtab_file_name); 91 | iERR initialize_new_symbol_table(hSYMTAB *p_hsymtab); 92 | iERR load_catalog_list(hCATALOG *p_catalog); 93 | iERR symbol_table_fill( hREADER hreader ); 94 | 95 | iERR symbol_table_write( hWRITER hwriter ); 96 | int compare_sids_by_count(const void *psid1, const void *psid2) ; 97 | 98 | iERR report_error(iERR err, const char *msg, hREADER reader, const char *file, int line); 99 | 100 | void start_timing(void); 101 | void stop_timing(void); 102 | 103 | 104 | // 105 | // in ionsymbols_args.c 106 | // 107 | void process_args(int argc, char **argv, char **p_non_argv, int *p_non_argc); 108 | void print_help(void); 109 | void dump_arg_globals(void); 110 | 111 | -------------------------------------------------------------------------------- /tools/ionsymbols/options.h: -------------------------------------------------------------------------------- 1 | // 2 | // command line argument option processing routines 3 | // 4 | // Copyright (c) 2009 - Microquill Inc. - All rights reserved 5 | // Chris Suver 6 | // 7 | 8 | #ifndef OPTION_H_INCLUDED 9 | #define OPTION_H_INCLUDED 10 | 11 | #define OPT_MAX_INT_ARG_LEN 30 12 | 13 | #ifndef BOOL 14 | #define BOOL int 15 | #endif 16 | 17 | #ifndef GLOBAL 18 | #define GLOBAL extern 19 | #define OPT_INITTO(x) 20 | #endif 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef enum _opt_type { 27 | ot_none, 28 | ot_int, 29 | ot_string, 30 | ot_non_arg 31 | } OT; 32 | 33 | typedef struct _opt_cursor OC; 34 | typedef BOOL (*OPT_ARG_FN)(OC *pcur); 35 | 36 | typedef struct _opt_def { 37 | OT type; 38 | char short_name; 39 | char *long_name; 40 | BOOL hidden; 41 | BOOL required; 42 | OPT_ARG_FN fn; 43 | char *help; 44 | } OPT_DEF; 45 | 46 | typedef struct _opt_msg OPT_MSG; 47 | struct _opt_msg { 48 | char *msg; 49 | OPT_MSG *next; 50 | }; 51 | 52 | BOOL opt_process(OPT_DEF *opts, int opt_count, int argc, char **argv); // returns TRUE if ok, FALSE if there's a bad arg 53 | BOOL opt_process_return_non_args(OPT_DEF *opts, int opt_count, int argc, char **argv, char **p_non_argv, int *p_non_argc); // returns TRUE if ok, FALSE if there's a bad arg 54 | void opt_log_error_line(OC *cur, const char *msg); // sets options as in error and appends this string to the error message list for help (if the user calls help) 55 | void opt_help (OPT_DEF *opts, int opt_count, char *name, int version, char *title, char *copyright); 56 | char *opt_get_arg(OC *cur); 57 | #ifdef WIN 58 | OPT_MSG *opt_decode_wildcards(OPT_MSG *prev_head, char *name_with_wildcards); 59 | #endif 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | 67 | --------------------------------------------------------------------------------